Skip to content

Commit 256c87c

Browse files
pjvuurendavem330
authored andcommitted
net: check tunnel option type in tunnel flags
Check the tunnel option type stored in tunnel flags when creating options for tunnels. Thereby ensuring we do not set geneve, vxlan or erspan tunnel options on interfaces that are not associated with them. Make sure all users of the infrastructure set correct flags, for the BPF helper we have to set all bits to keep backward compatibility. Signed-off-by: Pieter Jansen van Vuuren <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9d7298c commit 256c87c

File tree

7 files changed

+23
-7
lines changed

7 files changed

+23
-7
lines changed

drivers/net/geneve.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
236236
}
237237
/* Update tunnel dst according to Geneve options. */
238238
ip_tunnel_info_opts_set(&tun_dst->u.tun_info,
239-
gnvh->options, gnvh->opt_len * 4);
239+
gnvh->options, gnvh->opt_len * 4,
240+
TUNNEL_GENEVE_OPT);
240241
} else {
241242
/* Drop packets w/ critical options,
242243
* since we don't support any...
@@ -675,7 +676,8 @@ static void geneve_build_header(struct genevehdr *geneveh,
675676
geneveh->proto_type = htons(ETH_P_TEB);
676677
geneveh->rsvd2 = 0;
677678

678-
ip_tunnel_info_opts_get(geneveh->options, info);
679+
if (info->key.tun_flags & TUNNEL_GENEVE_OPT)
680+
ip_tunnel_info_opts_get(geneveh->options, info);
679681
}
680682

681683
static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,

drivers/net/vxlan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2122,7 +2122,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
21222122
vni = tunnel_id_to_key32(info->key.tun_id);
21232123
ifindex = 0;
21242124
dst_cache = &info->dst_cache;
2125-
if (info->options_len)
2125+
if (info->options_len &&
2126+
info->key.tun_flags & TUNNEL_VXLAN_OPT)
21262127
md = ip_tunnel_info_opts(info);
21272128
ttl = info->key.ttl;
21282129
tos = info->key.tos;

include/net/ip_tunnels.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,12 @@ static inline void ip_tunnel_info_opts_get(void *to,
466466
}
467467

468468
static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
469-
const void *from, int len)
469+
const void *from, int len,
470+
__be16 flags)
470471
{
471472
memcpy(ip_tunnel_info_opts(info), from, len);
472473
info->options_len = len;
474+
info->key.tun_flags |= flags;
473475
}
474476

475477
static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstate)
@@ -511,9 +513,11 @@ static inline void ip_tunnel_info_opts_get(void *to,
511513
}
512514

513515
static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
514-
const void *from, int len)
516+
const void *from, int len,
517+
__be16 flags)
515518
{
516519
info->options_len = 0;
520+
info->key.tun_flags |= flags;
517521
}
518522

519523
#endif /* CONFIG_INET */

net/core/filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3582,7 +3582,7 @@ BPF_CALL_3(bpf_skb_set_tunnel_opt, struct sk_buff *, skb,
35823582
if (unlikely(size > IP_TUNNEL_OPTS_MAX))
35833583
return -ENOMEM;
35843584

3585-
ip_tunnel_info_opts_set(info, from, size);
3585+
ip_tunnel_info_opts_set(info, from, size, TUNNEL_OPTIONS_PRESENT);
35863586

35873587
return 0;
35883588
}

net/ipv4/ip_gre.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,8 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
587587
goto err_free_skb;
588588

589589
key = &tun_info->key;
590+
if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
591+
goto err_free_rt;
590592
md = ip_tunnel_info_opts(tun_info);
591593
if (!md)
592594
goto err_free_rt;

net/ipv6/ip6_gre.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
990990
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
991991

992992
dsfield = key->tos;
993+
if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
994+
goto tx_err;
993995
md = ip_tunnel_info_opts(tun_info);
994996
if (!md)
995997
goto tx_err;

net/openvswitch/flow_netlink.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2516,7 +2516,9 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
25162516
struct ovs_tunnel_info *ovs_tun;
25172517
struct nlattr *a;
25182518
int err = 0, start, opts_type;
2519+
__be16 dst_opt_type;
25192520

2521+
dst_opt_type = 0;
25202522
ovs_match_init(&match, &key, true, NULL);
25212523
opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log);
25222524
if (opts_type < 0)
@@ -2528,10 +2530,13 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
25282530
err = validate_geneve_opts(&key);
25292531
if (err < 0)
25302532
return err;
2533+
dst_opt_type = TUNNEL_GENEVE_OPT;
25312534
break;
25322535
case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
2536+
dst_opt_type = TUNNEL_VXLAN_OPT;
25332537
break;
25342538
case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
2539+
dst_opt_type = TUNNEL_ERSPAN_OPT;
25352540
break;
25362541
}
25372542
}
@@ -2574,7 +2579,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
25742579
*/
25752580
ip_tunnel_info_opts_set(tun_info,
25762581
TUN_METADATA_OPTS(&key, key.tun_opts_len),
2577-
key.tun_opts_len);
2582+
key.tun_opts_len, dst_opt_type);
25782583
add_nested_action_end(*sfa, start);
25792584

25802585
return err;

0 commit comments

Comments
 (0)