Skip to content

Commit f8337ef

Browse files
pmachatakuba-moo
authored andcommitted
vxlan: Support MC routing in the underlay
Locally-generated MC packets have so far not been subject to MC routing. Instead an MC-enabled installation would maintain the MC routing tables, and separately from that the list of interfaces to send packets to as part of the VXLAN FDB and MDB. In a previous patch, a ip_mr_output() and ip6_mr_output() routines were added for IPv4 and IPv6. All locally generated MC traffic is now passed through these functions. For reasons of backward compatibility, an SKB (IPCB / IP6CB) flag guards the actual MC routing. This patch adds logic to set the flag, and the UAPI to enable the behavior. Signed-off-by: Petr Machata <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Reviewed-by: Nikolay Aleksandrov <[email protected]> Link: https://patch.msgid.link/d899655bb7e9b2521ee8c793e67056b9fd02ba12.1750113335.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 96e8f5a commit f8337ef

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,6 +2451,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
24512451
rcu_read_lock();
24522452
if (addr_family == AF_INET) {
24532453
struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock);
2454+
u16 ipcb_flags = 0;
24542455
struct rtable *rt;
24552456
__be16 df = 0;
24562457
__be32 saddr;
@@ -2467,6 +2468,9 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
24672468
goto tx_error;
24682469
}
24692470

2471+
if (flags & VXLAN_F_MC_ROUTE)
2472+
ipcb_flags |= IPSKB_MCROUTE;
2473+
24702474
if (!info) {
24712475
/* Bypass encapsulation if the destination is local */
24722476
err = encap_bypass_if_local(skb, dev, vxlan, AF_INET,
@@ -2522,11 +2526,13 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
25222526

25232527
udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, saddr,
25242528
pkey->u.ipv4.dst, tos, ttl, df,
2525-
src_port, dst_port, xnet, !udp_sum, 0);
2529+
src_port, dst_port, xnet, !udp_sum,
2530+
ipcb_flags);
25262531
#if IS_ENABLED(CONFIG_IPV6)
25272532
} else {
25282533
struct vxlan_sock *sock6 = rcu_dereference(vxlan->vn6_sock);
25292534
struct in6_addr saddr;
2535+
u16 ip6cb_flags = 0;
25302536

25312537
if (!ifindex)
25322538
ifindex = sock6->sock->sk->sk_bound_dev_if;
@@ -2542,6 +2548,9 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
25422548
goto tx_error;
25432549
}
25442550

2551+
if (flags & VXLAN_F_MC_ROUTE)
2552+
ip6cb_flags |= IP6SKB_MCROUTE;
2553+
25452554
if (!info) {
25462555
u32 rt6i_flags = dst_rt6_info(ndst)->rt6i_flags;
25472556

@@ -2587,7 +2596,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
25872596
udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev,
25882597
&saddr, &pkey->u.ipv6.dst, tos, ttl,
25892598
pkey->label, src_port, dst_port, !udp_sum,
2590-
0);
2599+
ip6cb_flags);
25912600
#endif
25922601
}
25932602
vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX, pkt_len);
@@ -3402,6 +3411,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
34023411
[IFLA_VXLAN_LOCALBYPASS] = NLA_POLICY_MAX(NLA_U8, 1),
34033412
[IFLA_VXLAN_LABEL_POLICY] = NLA_POLICY_MAX(NLA_U32, VXLAN_LABEL_MAX),
34043413
[IFLA_VXLAN_RESERVED_BITS] = NLA_POLICY_EXACT_LEN(sizeof(struct vxlanhdr)),
3414+
[IFLA_VXLAN_MC_ROUTE] = NLA_POLICY_MAX(NLA_U8, 1),
34053415
};
34063416

34073417
static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -4315,6 +4325,14 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
43154325
return err;
43164326
}
43174327

4328+
if (data[IFLA_VXLAN_MC_ROUTE]) {
4329+
err = vxlan_nl2flag(conf, data, IFLA_VXLAN_MC_ROUTE,
4330+
VXLAN_F_MC_ROUTE, changelink,
4331+
true, extack);
4332+
if (err)
4333+
return err;
4334+
}
4335+
43184336
if (tb[IFLA_MTU]) {
43194337
if (changelink) {
43204338
NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_MTU],

include/net/vxlan.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ struct vxlan_dev {
332332
#define VXLAN_F_VNIFILTER 0x20000
333333
#define VXLAN_F_MDB 0x40000
334334
#define VXLAN_F_LOCALBYPASS 0x80000
335+
#define VXLAN_F_MC_ROUTE 0x100000
335336

336337
/* Flags that are used in the receive path. These flags must match in
337338
* order for a socket to be shareable
@@ -353,7 +354,9 @@ struct vxlan_dev {
353354
VXLAN_F_UDP_ZERO_CSUM6_RX | \
354355
VXLAN_F_COLLECT_METADATA | \
355356
VXLAN_F_VNIFILTER | \
356-
VXLAN_F_LOCALBYPASS)
357+
VXLAN_F_LOCALBYPASS | \
358+
VXLAN_F_MC_ROUTE | \
359+
0)
357360

358361
struct net_device *vxlan_dev_create(struct net *net, const char *name,
359362
u8 name_assign_type, struct vxlan_config *conf);

include/uapi/linux/if_link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,7 @@ enum {
13981398
IFLA_VXLAN_LOCALBYPASS,
13991399
IFLA_VXLAN_LABEL_POLICY, /* IPv6 flow label policy; ifla_vxlan_label_policy */
14001400
IFLA_VXLAN_RESERVED_BITS,
1401+
IFLA_VXLAN_MC_ROUTE,
14011402
__IFLA_VXLAN_MAX
14021403
};
14031404
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)

0 commit comments

Comments
 (0)