ipmr, ip6mr: Allow MC-routing locally-generated MC packets
Subsystems (10)
cover ipmr, ip6mr: Allow MC-routing locally-generated MC packets
Multicast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. In practice that means that MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
To that end, this patchset adds support to route locally generated multicast packets.
However, an installation that uses a VXLAN underlay netdevice for which it also has matching MC routes, would get a different routing with this patch. Previously, the MC packets would be delivered directly to the underlay port, whereas now they would be MC-routed. In order to avoid this change in behavior, introduce an IPCB/IP6CB flag. Unless the flag is set, the new MC-routing code is skipped.
All this is keyed to a new VXLAN attribute, IFLA_VXLAN_MC_ROUTE. Only when it is set does any of the above engage.
In addition to that, and as is the case today with MC forwarding, IPV4_DEVCONF_MC_FORWARDING must be enabled for the netdevice that acts as a source of MC traffic (i.e. the VXLAN PHYS_DEV), so an MC daemon must be attached to the netdevice.
When a VXLAN netdevice with a MC remote is brought up, the physical netdevice joins the indicated MC group. This is important for local delivery of MC packets, so it is still necessary to configure a physical netdevice -- the parameter cannot go away. The netdevice would however typically not be a front panel port, but a dummy. An MC daemon would then sit on top of that netdevice as well as any front panel ports that it needs to service, and have routes set up between the two.
A way to configure the VXLAN netdevice to take advantage of the new MC routing would be:
# ip link add name d up type dummy # ip link add name vx10 up type vxlan id 1000 dstport 4789 \ local 192.0.2.1 group 225.0.0.1 ttl 16 dev d mrcoute # ip link set dev vx10 master br # plus vlans etc.
With the following MC routes:
(192.0.2.1, 225.0.0.1) iif=d oil=swp1,swp2 # TX route
(*, 225.0.0.1) iif=swp1 oil=d,swp2 # RX route
(*, 225.0.0.1) iif=swp2 oil=d,swp1 # RX route
The RX path has not changed, with the exception of an extra MC hop. Packets are delivered to the front panel port and MC-forwarded to the VXLAN physical port, here "d". Since the port has joined the multicast group, the packets are locally delivered, and end up being processed by the VXLAN netdevice.
This patchset is based on earlier patches from Nikolay Aleksandrov and Roopa Prabhu, though it underwent significant changes. Roopa broadly presented the topic on LPC 2019 [0].
Patchset progression:
- Patches #1 to #4 add ip_mr_output()
- Patches #5 to #9 add ip6_mr_output()
- Patch #10 adds the VXLAN bits to enable MR engagement
- Patches #11 to #13 prepare selftest libraries
- Patch #14 includes a new test suite
[0] https://www.youtube.com/watch?v=xlReECfi-uo
Petr Machata (14):
net: ipv4: Add a flags argument to iptunnel_xmit(),
udp_tunnel_xmit_skb()
net: ipv4: ipmr: ipmr_queue_xmit(): Drop local variable `dev'
net: ipv4: ipmr: Split ipmr_queue_xmit() in two
net: ipv4: Add ip_mr_output()
net: ipv6: Make udp_tunnel6_xmit_skb() void
net: ipv6: Add a flags argument to ip6tunnel_xmit(),
udp_tunnel6_xmit_skb()
net: ipv6: ip6mr: Fix in/out netdev to pass to the FORWARD chain
net: ipv6: ip6mr: Extract a helper out of ip6mr_forward2()
net: ipv6: Add ip6_mr_output()
vxlan: Support MC routing in the underlay
selftests: forwarding: lib: Move smcrouted helpers here
selftests: net: lib: Add ip_link_has_flag()
selftests: forwarding: adf_mcd_start(): Allow configuring custom
interfaces
selftests: forwarding: Add a test for verifying VXLAN MC underlay
drivers/net/amt.c | 9 +- drivers/net/bareudp.c | 7 +- drivers/net/geneve.c | 7 +- drivers/net/gtp.c | 12 +- drivers/net/ovpn/udp.c | 4 +- drivers/net/vxlan/vxlan_core.c | 23 +- drivers/net/wireguard/socket.c | 4 +- include/linux/ipv6.h | 1 + include/linux/mroute6.h | 7 + include/net/ip.h | 2 + include/net/ip6_tunnel.h | 3 +- include/net/ip_tunnels.h | 2 +- include/net/udp_tunnel.h | 17 +- include/net/vxlan.h | 5 +- include/uapi/linux/if_link.h | 1 + net/ipv4/ip_tunnel.c | 4 +- net/ipv4/ip_tunnel_core.c | 4 +- net/ipv4/ipmr.c | 169 +++- net/ipv4/route.c | 2 +- net/ipv4/udp_tunnel_core.c | 5 +- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/ip6_udp_tunnel.c | 18 +- net/ipv6/ip6mr.c | 137 +++- net/ipv6/route.c | 1 + net/ipv6/sit.c | 2 +- net/sctp/ipv6.c | 7 +- net/sctp/protocol.c | 3 +- net/tipc/udp_media.c | 12 +- .../testing/selftests/net/forwarding/Makefile | 1 + tools/testing/selftests/net/forwarding/lib.sh | 43 + .../net/forwarding/router_multicast.sh | 31 +- .../net/forwarding/vxlan_bridge_1q_mc_ul.sh | 757 ++++++++++++++++++ tools/testing/selftests/net/lib.sh | 12 +- 33 files changed, 1199 insertions(+), 115 deletions(-) create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1q_mc_ul.sh
Signature · 1 line
2.49.0
PATCH 1/14 net: ipv4: Add a flags argument to iptunnel_xmit(), udp_tunnel_xmit_skb()
iptunnel_xmit() erases the contents of the SKB control block. In order to be able to set particular IPCB flags on the SKB, add a corresponding parameter, and propagate it to udp_tunnel_xmit_skb() as well.
In one of the following patches, VXLAN driver will use this facility to mark packets as subject to IP multicast routing.
---
Notes:
CC: Pablo Neira Ayuso <[email protected]>
CC: [email protected]
CC: Andrew Lunn <[email protected]>
CC: Taehee Yoo <[email protected]>
CC: Antonio Quartulli <[email protected]>
CC: "Jason A. Donenfeld" <[email protected]>
CC: [email protected]
CC: Marcelo Ricardo Leitner <[email protected]>
CC: [email protected]
CC: Jon Maloy <[email protected]>
CC: [email protected]
drivers/net/amt.c | 9 ++++++--- drivers/net/bareudp.c | 4 ++-- drivers/net/geneve.c | 4 ++-- drivers/net/gtp.c | 10 ++++++---- drivers/net/ovpn/udp.c | 2 +- drivers/net/vxlan/vxlan_core.c | 2 +- drivers/net/wireguard/socket.c | 2 +- include/net/ip_tunnels.h | 2 +- include/net/udp_tunnel.h | 2 +- net/ipv4/ip_tunnel.c | 4 ++-- net/ipv4/ip_tunnel_core.c | 4 +++- net/ipv4/udp_tunnel_core.c | 5 +++-- net/ipv6/sit.c | 2 +- net/sctp/protocol.c | 3 ++- net/tipc/udp_media.c | 2 +- 15 files changed, 33 insertions(+), 24 deletions(-)
drivers/net/amt.c +6 -3
@@ -1046,7 +1046,8 @@ static bool amt_send_membership_update(struct amt_dev *amt, amt->gw_port, amt->relay_port, false, - false); + false, + 0);amt_update_gw_status (amt,AMT_STATUS_SENT_UPDATE , true);return false; }
@@ -1103,7 +1104,8 @@ static void amt_send_multicast_data(struct amt_dev *amt, amt->relay_port, tunnel->source_port, false, - false); + false, + 0); } static bool amt_send_membership_query(struct amt_dev *amt,
@@ -1161,7 +1163,8 @@ static bool amt_send_membership_query(struct amt_dev *amt, amt->relay_port, tunnel->source_port, false, - false); + false, + 0);amt_update_relay_status (tunnel,AMT_STATUS_SENT_QUERY , true);return false; }
drivers/net/bareudp.c +2 -2
@@ -362,8 +362,8 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,udp_tunnel_xmit_skb (rt, sock->sk, skb, saddr, info->key.u.ipv4.dst, tos, ttl, df, sport, bareudp->port, !net_eq (bareudp->net,dev_net (bareudp->dev)), - !test_bit (IP_TUNNEL_CSUM_BIT , - info->key.tun_flags)); + !test_bit (IP_TUNNEL_CSUM_BIT , info->key.tun_flags), +0 );return 0 ; free_dst:
drivers/net/geneve.c +2 -2
@@ -921,8 +921,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,udp_tunnel_xmit_skb (rt, gs4->sock->sk, skb, saddr, info->key.u.ipv4.dst, tos, ttl, df, sport, geneve->cfg.info.key.tp_dst, !net_eq (geneve->net,dev_net (geneve->dev)), - !test_bit (IP_TUNNEL_CSUM_BIT , - info->key.tun_flags)); + !test_bit (IP_TUNNEL_CSUM_BIT , info->key.tun_flags), +0 );return 0 ; }
drivers/net/gtp.c +6 -4
@@ -446,7 +446,8 @@ static int gtp0_send_echo_resp_ip(struct gtp_dev *gtp, struct sk_buff *skb)htons (GTP0_PORT ),htons (GTP0_PORT ), !net_eq (sock_net (gtp->sk1u),dev_net (gtp->dev)), - false); + false, + 0);return 0 ; }
@@ -704,7 +705,8 @@ static int gtp1u_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb)htons (GTP1U_PORT ),htons (GTP1U_PORT ), !net_eq (sock_net (gtp->sk1u),dev_net (gtp->dev)), - false); + false, + 0);return 0 ; }
@@ -1304,7 +1306,7 @@ static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev) pktinfo.gtph_port, pktinfo.gtph_port, !net_eq (sock_net (pktinfo.pctx->sk),dev_net (dev)), - false); + false, 0);break ;case AF_INET6 :#if IS_ENABLED (CONFIG_IPV6 )
@@ -2405,7 +2407,7 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) port, port, !net_eq (sock_net (sk),dev_net (gtp->dev)), - false); + false, 0);return 0 ; }
drivers/net/ovpn/udp.c +1 -1
@@ -199,7 +199,7 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, transmit:udp_tunnel_xmit_skb (rt, sk, skb, fl.saddr, fl.daddr,0 ,ip4_dst_hoplimit (&rt->dst),0 , fl.fl4_sport, - fl.fl4_dport, false, sk->sk_no_check_tx); + fl.fl4_dport, false, sk->sk_no_check_tx,0 ); ret =0 ; err:local_bh_enable ();
drivers/net/vxlan/vxlan_core.c +1 -1
@@ -2522,7 +2522,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,udp_tunnel_xmit_skb (rt, sock4->sock->sk, skb, saddr, pkey->u.ipv4.dst, tos, ttl, df, - src_port, dst_port, xnet, !udp_sum); + src_port, dst_port, xnet, !udp_sum,0 );#if IS_ENABLED (CONFIG_IPV6 ) } else {struct vxlan_sock *sock6 =rcu_dereference (vxlan->vn6_sock);
drivers/net/wireguard/socket.c +1 -1
@@ -84,7 +84,7 @@ static int send4(struct wg_device *wg, struct sk_buff *skb, skb->ignore_df =1 ;udp_tunnel_xmit_skb (rt, sock, skb, fl.saddr, fl.daddr, ds,ip4_dst_hoplimit (&rt->dst),0 , fl.fl4_sport, - fl.fl4_dport, false, false); + fl.fl4_dport, false, false,0 ); goto out; err:
include/net/ip_tunnels.h +1 -1
@@ -603,7 +603,7 @@ static inline int iptunnel_pull_header(struct sk_buff *skb, int hdr_len,void iptunnel_xmit (struct sock *sk,struct rtable *rt,struct sk_buff *skb,__be32 src,__be32 dst,u8 proto, -u8 tos,u8 ttl,__be16 df,bool xnet); +u8 tos,u8 ttl,__be16 df,bool xnet,u16 ipcb_flags);struct metadata_dst *iptunnel_metadata_reply (struct metadata_dst *md,gfp_t flags); int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst,
include/net/udp_tunnel.h +1 -1
@@ -150,7 +150,7 @@ static inline void udp_tunnel_drop_rx_info(struct net_device *dev)void udp_tunnel_xmit_skb (struct rtable *rt,struct sock *sk,struct sk_buff *skb,__be32 src,__be32 dst,__u8 tos,__u8 ttl,__be16 df,__be16 src_port,__be16 dst_port, -bool xnet,bool nocheck); +bool xnet,bool nocheck,u16 ipcb_flags); int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb,
net/ipv4/ip_tunnel.c +2 -2
@@ -668,7 +668,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,ip_tunnel_adj_headroom (dev, headroom);iptunnel_xmit (NULL , rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl, - df, !net_eq (tunnel->net,dev_net (dev))); + df, !net_eq (tunnel->net,dev_net (dev)),0 );return ; tx_error:DEV_STATS_INC (dev, tx_errors);
@@ -857,7 +857,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,ip_tunnel_adj_headroom (dev, max_headroom);iptunnel_xmit (NULL , rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, - df, !net_eq (tunnel->net,dev_net (dev))); + df, !net_eq (tunnel->net,dev_net (dev)),0 );return ;#if IS_ENABLED (CONFIG_IPV6 )
net/ipv4/ip_tunnel_core.c +3 -1
@@ -49,7 +49,8 @@ EXPORT_SYMBOL(ip6tun_encaps);void iptunnel_xmit (struct sock *sk,struct rtable *rt,struct sk_buff *skb,__be32 src,__be32 dst,__u8 proto, -__u8 tos,__u8 ttl,__be16 df,bool xnet) +__u8 tos,__u8 ttl,__be16 df,bool xnet, +u16 ipcb_flags) {int pkt_len = skb->len -skb_inner_network_offset (skb);struct net *net =dev_net (rt->dst.dev);
@@ -62,6 +63,7 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,skb_clear_hash_if_not_l4 (skb);skb_dst_set (skb, &rt->dst);memset (IPCB (skb),0 ,sizeof (*IPCB (skb))); +IPCB (skb)->flags = ipcb_flags;/* Push down and install the IP header. */ skb_push (skb,sizeof (struct iphdr ));
net/ipv4/udp_tunnel_core.c +3 -2
@@ -169,7 +169,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel_notify_del_rx_port);void udp_tunnel_xmit_skb (struct rtable *rt,struct sock *sk,struct sk_buff *skb,__be32 src,__be32 dst,__u8 tos,__u8 ttl,__be16 df,__be16 src_port,__be16 dst_port, -bool xnet,bool nocheck) +bool xnet,bool nocheck,u16 ipcb_flags) {struct udphdr *uh;
@@ -185,7 +185,8 @@ void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skbudp_set_csum (nocheck, skb, src, dst, skb->len); -iptunnel_xmit (sk, rt, skb, src, dst,IPPROTO_UDP , tos, ttl, df, xnet); +iptunnel_xmit (sk, rt, skb, src, dst,IPPROTO_UDP , tos, ttl, df, xnet, + ipcb_flags); }EXPORT_SYMBOL_GPL (udp_tunnel_xmit_skb);
net/ipv6/sit.c +1 -1
@@ -1035,7 +1035,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,skb_set_inner_ipproto (skb,IPPROTO_IPV6 );iptunnel_xmit (NULL , rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, - df, !net_eq (tunnel->net,dev_net (dev))); + df, !net_eq (tunnel->net,dev_net (dev)),0 );return NETDEV_TX_OK ; tx_error_icmp:
net/sctp/protocol.c +2 -1
@@ -1103,7 +1103,8 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, struct sctp_transport *t)skb_set_inner_ipproto (skb,IPPROTO_SCTP );udp_tunnel_xmit_skb (dst_rtable (dst), sk, skb, fl4->saddr, fl4->daddr, dscp,ip4_dst_hoplimit (dst), df, -sctp_sk (sk)->udp_port, t->encap_port, false, false); +sctp_sk (sk)->udp_port, t->encap_port, false, false, +0 );return 0 ; }
net/tipc/udp_media.c +1 -1
@@ -197,7 +197,7 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, ttl =ip4_dst_hoplimit (&rt->dst);udp_tunnel_xmit_skb (rt, ub->ubsock->sk, skb, src->ipv4.s_addr, dst->ipv4.s_addr,0 , ttl,0 , src->port, - dst->port, false, true); + dst->port, false, true,0 );#if IS_ENABLED (CONFIG_IPV6 ) } else {if (!ndst) {
Signature · 1 line
2.49.0
Re: [PATCH net-next 01/14] net: ipv4: Add a flags argument to iptunnel_xmit(), udp_tunnel_xmit_skb()
Quoted 24 lines · Petr Machata
iptunnel_xmit()erases the contents of the SKB control block. In order to be able to set particular IPCB flags on the SKB, add a corresponding parameter, and propagate it toudp_tunnel_xmit_skb()as well.In one of the following patches, VXLAN driver will use this facility to mark packets as subject to IP multicast routing.
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>---
Notes:
CC: Pablo Neira Ayuso <[email protected]>
CC: [email protected]
CC: Andrew Lunn <[email protected]>
CC: Taehee Yoo <[email protected]>
CC: Antonio Quartulli <[email protected]>
CC: "Jason A. Donenfeld" <[email protected]>
CC: [email protected]
CC: Marcelo Ricardo Leitner <[email protected]>
CC: [email protected]
CC: Jon Maloy <[email protected]>
CC: [email protected]
Quoted 17 lines
drivers/net/amt.c | 9 ++++++--- drivers/net/bareudp.c | 4 ++-- drivers/net/geneve.c | 4 ++-- drivers/net/gtp.c | 10 ++++++---- drivers/net/ovpn/udp.c | 2 +- drivers/net/vxlan/vxlan_core.c | 2 +- drivers/net/wireguard/socket.c | 2 +- include/net/ip_tunnels.h | 2 +- include/net/udp_tunnel.h | 2 +- net/ipv4/ip_tunnel.c | 4 ++-- net/ipv4/ip_tunnel_core.c | 4 +++- net/ipv4/udp_tunnel_core.c | 5 +++-- net/ipv6/sit.c | 2 +- net/sctp/protocol.c | 3 ++- net/tipc/udp_media.c | 2 +- 15 files changed, 33 insertions(+), 24 deletions(-)
Re: [PATCH net-next 01/14] net: ipv4: Add a flags argument to iptunnel_xmit(), udp_tunnel_xmit_skb()
In reply to Petr MachataQuoted 11 lines · Petr Machata
iptunnel_xmit()erases the contents of the SKB control block. In order to be able to set particular IPCB flags on the SKB, add a corresponding parameter, and propagate it toudp_tunnel_xmit_skb()as well.In one of the following patches, VXLAN driver will use this facility to mark packets as subject to IP multicast routing.
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>---
Quoted 12 lines
Notes:
CC: Pablo Neira Ayuso <[email protected]>
CC: [email protected]
CC: Andrew Lunn <[email protected]>
CC: Taehee Yoo <[email protected]>
CC: Antonio Quartulli <[email protected]>
CC: "Jason A. Donenfeld" <[email protected]>
CC: [email protected]
CC: Marcelo Ricardo Leitner <[email protected]>
CC: [email protected]
CC: Jon Maloy <[email protected]>
CC: [email protected]
Signature · 2 lines
Antonio Quartulli OpenVPN Inc.
PATCH 2/14 net: ipv4: ipmr: ipmr_queue_xmit(): Drop local variable `dev'
In reply to Petr MachataThe variable is used for caching of rt->dst.dev. The netdevice referenced therein does not change during the scope of validity of that local. At the same time, the local is only used twice, and each of these uses will end up in a different function in the following patches, further eliminating any use the local could have had.
Drop the local altogether and inline the uses.
--- net/ipv4/ipmr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
net/ipv4/ipmr.c +2 -5
@@ -1859,7 +1859,6 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,const struct iphdr *iph =ip_hdr (skb);struct vif_device *vif = &mrt->vif_table[vifi];struct net_device *vif_dev; -struct net_device *dev;struct rtable *rt;struct flowi4 fl4;int encap =0 ;
@@ -1898,8 +1897,6 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, goto out_free; } - dev = rt->dst.dev; -if (skb->len+encap >dst_mtu (&rt->dst) && (ntohs (iph->frag_off) &IP_DF )) {/* Do not fragment multicasts. Alas, IPv4 does not * allow to send ICMP, so that packets will disappear
@@ -1910,7 +1907,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, goto out_free; } - encap +=LL_RESERVED_SPACE (dev) + rt->dst.header_len; + encap +=LL_RESERVED_SPACE (rt->dst.dev) + rt->dst.header_len;if (skb_cow (skb, encap)) {ip_rt_put (rt);
@@ -1947,7 +1944,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,* result in receiving multiple packets. */ NF_HOOK (NFPROTO_IPV4 ,NF_INET_FORWARD , - net,NULL , skb, skb->dev, dev, + net,NULL , skb, skb->dev, rt->dst.dev, ipmr_forward_finish);return ;
Signature · 1 line
2.49.0
Re: [PATCH net-next 02/14] net: ipv4: ipmr: ipmr_queue_xmit(): Drop local variable `dev'
Quoted 6 lines · Petr Machata
The variable is used for caching of
rt->dst.dev. The netdevice referenced therein does not change during the scope of validity of that local. At the same time, the local is only used twice, and each of these uses will end up in a different function in the following patches, further eliminating any use the local could have had.
Quoted 8 lines
Drop the local altogether and inline the uses.
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>--- net/ipv4/ipmr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
PATCH 3/14 net: ipv4: ipmr: Split ipmr_queue_xmit() in two
In reply to Petr MachataSome of the work of ipmr_queue_xmit() is specific to IPMR forwarding, and should not take place on the output path. In order to allow reuse of the common parts, split the function into two: the ipmr_prepare_xmit() helper that takes care of the common bits, and the ipmr_queue_fwd_xmit(), which invokes the former and encapsulates the whole forwarding algorithm.
--- net/ipv4/ipmr.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-)
net/ipv4/ipmr.c +29 -16
@@ -1853,8 +1853,8 @@ static bool ipmr_forward_offloaded(struct sk_buff *skb, struct mr_table *mrt,/* Processing handlers for ipmr_forward, under rcu_read_lock() */ -static void ipmr_queue_xmit (struct net *net,struct mr_table *mrt, -int in_vifi,struct sk_buff *skb,int vifi) +static int ipmr_prepare_xmit (struct net *net,struct mr_table *mrt, +struct sk_buff *skb,int vifi) {const struct iphdr *iph =ip_hdr (skb);struct vif_device *vif = &mrt->vif_table[vifi];
@@ -1865,7 +1865,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, vif_dev =vif_dev_read (vif);if (!vif_dev) - goto out_free; +return -1 ;if (vif->flags &VIFF_REGISTER ) {WRITE_ONCE (vif->pkt_out, vif->pkt_out +1 );
@@ -1873,12 +1873,9 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,DEV_STATS_ADD (vif_dev, tx_bytes, skb->len);DEV_STATS_INC (vif_dev, tx_packets);ipmr_cache_report (mrt, skb, vifi,IGMPMSG_WHOLEPKT ); - goto out_free; +return -1 ; } -if (ipmr_forward_offloaded (skb, mrt, in_vifi, vifi)) - goto out_free; -if (vif->flags &VIFF_TUNNEL ) { rt = ip_route_output_ports(net, &fl4, NULL, vif->remote, vif->local,
@@ -1886,7 +1883,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,IPPROTO_IPIP , iph->tos & INET_DSCP_MASK, vif->link);if (IS_ERR (rt)) - goto out_free; +return -1 ; encap =sizeof (struct iphdr ); }else { rt = ip_route_output_ports(net, &fl4, NULL, iph->daddr, 0,
@@ -1894,7 +1891,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,IPPROTO_IPIP , iph->tos & INET_DSCP_MASK, vif->link);if (IS_ERR (rt)) - goto out_free; +return -1 ; }if (skb->len+encap >dst_mtu (&rt->dst) && (ntohs (iph->frag_off) &IP_DF )) {
@@ -1904,14 +1901,14 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,*/ IP_INC_STATS (net,IPSTATS_MIB_FRAGFAILS );ip_rt_put (rt); - goto out_free; +return -1 ; } encap +=LL_RESERVED_SPACE (rt->dst.dev) + rt->dst.header_len;if (skb_cow (skb, encap)) {ip_rt_put (rt); - goto out_free; +return -1 ; }WRITE_ONCE (vif->pkt_out, vif->pkt_out +1 );
@@ -1931,6 +1928,22 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,DEV_STATS_ADD (vif_dev, tx_bytes, skb->len); } +return 0 ; +} + +static void ipmr_queue_fwd_xmit (struct net *net,struct mr_table *mrt, +int in_vifi,struct sk_buff *skb,int vifi) +{ +struct rtable *rt; + +if (ipmr_forward_offloaded (skb, mrt, in_vifi, vifi)) + goto out_free; + +if (ipmr_prepare_xmit (net, mrt, skb, vifi)) + goto out_free; + + rt =skb_rtable (skb); +IPCB (skb)->flags |=IPSKB_FORWARDED ;/* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
@@ -2062,8 +2075,8 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,struct sk_buff *skb2 =skb_clone (skb,GFP_ATOMIC );if (skb2) -ipmr_queue_xmit (net, mrt, true_vifi, - skb2, psend); +ipmr_queue_fwd_xmit (net, mrt, true_vifi, + skb2, psend); } psend = ct; }
@@ -2074,10 +2087,10 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,struct sk_buff *skb2 =skb_clone (skb,GFP_ATOMIC );if (skb2) -ipmr_queue_xmit (net, mrt, true_vifi, skb2, - psend); +ipmr_queue_fwd_xmit (net, mrt, true_vifi, skb2, + psend); }else { -ipmr_queue_xmit (net, mrt, true_vifi, skb, psend); +ipmr_queue_fwd_xmit (net, mrt, true_vifi, skb, psend);return ; } }
Signature · 1 line
2.49.0
Re: [PATCH net-next 03/14] net: ipv4: ipmr: Split ipmr_queue_xmit() in two
Quoted 6 lines · Petr Machata
Some of the work of
ipmr_queue_xmit()is specific to IPMR forwarding, and should not take place on the output path. In order to allow reuse of the common parts, split the function into two: theipmr_prepare_xmit()helper that takes care of the common bits, and theipmr_queue_fwd_xmit(), which invokes the former and encapsulates the whole forwarding algorithm.
Quoted 6 lines
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>--- net/ipv4/ipmr.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-)
PATCH 4/14 net: ipv4: Add ip_mr_output()
In reply to Petr MachataMulticast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code today. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. Thus MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
To that end, this patch adds support to route locally generated multicast packets. The newly-added routines do largely what ip_mr_input() and ip_mr_forward() do: make an MR cache lookup to find where to send the packets, and use ip_mc_output() to send each of them. When no cache entry is found, the packet is punted to the daemon for resolution.
However, an installation that uses a VXLAN underlay netdevice for which it also has matching MC routes, would get a different routing with this patch. Previously, the MC packets would be delivered directly to the underlay port, whereas now they would be MC-routed. In order to avoid this change in behavior, introduce an IPCB flag. Only if the flag is set will ip_mr_output() actually engage, otherwise it reverts to ip_mc_output().
This code is based on work by Roopa Prabhu and Nikolay Aleksandrov.
--- include/net/ip.h | 2 + net/ipv4/ipmr.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ net/ipv4/route.c | 2 +- 3 files changed, 120 insertions(+), 1 deletion(-)
include/net/ip.h +2 -0
@@ -59,6 +59,7 @@ struct inet_skb_parm {#define IPSKB_L3SLAVE BIT(7)#define IPSKB_NOPOLICY BIT(8)#define IPSKB_MULTIPATH BIT(9) +#define IPSKB_MCROUTE BIT(10)u16 frag_max_size; };
@@ -167,6 +168,7 @@ void ip_list_rcv(struct list_head *head, struct packet_type *pt,int ip_local_deliver (struct sk_buff *skb);void ip_protocol_deliver_rcu (struct net *net,struct sk_buff *skb,int proto);int ip_mr_input (struct sk_buff *skb); +int ip_mr_output (struct net *net,struct sock *sk,struct sk_buff *skb);int ip_output (struct net *net,struct sock *sk,struct sk_buff *skb);int ip_mc_output (struct net *net,struct sock *sk,struct sk_buff *skb); int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
net/ipv4/ipmr.c +117 -0
129 lines not on this page · raw message
net/ipv4/route.c +1 -1
@@ -2660,7 +2660,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,if (IN_DEV_MFORWARD (in_dev) && !ipv4_is_local_multicast (fl4->daddr)) { rth->dst.input = ip_mr_input; - rth->dst.output = ip_mc_output; + rth->dst.output = ip_mr_output; } }#endif
Signature · 1 line
2.49.0
PATCH 5/14 net: ipv6: Make udp_tunnel6_xmit_skb() void
In reply to Petr MachataThe function always returns zero, thus the return value does not carry any signal. Just make it void.
Most callers already ignore the return value. However:
- Refold arguments of the call from sctp_v6_xmit() so that they fit into the 80-column limit.
- tipc_udp_xmit() initializes err from the return value, but that should already be always zero at that point. So there's no practical change, but elision of the assignment prompts a couple more tweaks to clean up the function.
---
Notes:
CC:Marcelo Ricardo Leitner <[email protected]> CC:[email protected]
CC:Jon Maloy <[email protected]> CC:[email protected]
include/net/udp_tunnel.h | 14 +++++++------- net/ipv6/ip6_udp_tunnel.c | 15 +++++++-------- net/sctp/ipv6.c | 7 ++++--- net/tipc/udp_media.c | 10 +++++----- 4 files changed, 23 insertions(+), 23 deletions(-)
include/net/udp_tunnel.h +7 -7
@@ -152,13 +152,13 @@ void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb __be16 df, __be16 src_port, __be16 dst_port, bool xnet, bool nocheck, u16 ipcb_flags); -int udp_tunnel6_xmit_skb (struct dst_entry *dst,struct sock *sk, -struct sk_buff *skb, -struct net_device *dev, -const struct in6_addr *saddr, -const struct in6_addr *daddr, -__u8 prio,__u8 ttl,__be32 label, -__be16 src_port,__be16 dst_port,bool nocheck); +void udp_tunnel6_xmit_skb (struct dst_entry *dst,struct sock *sk, +struct sk_buff *skb, +struct net_device *dev, +const struct in6_addr *saddr, +const struct in6_addr *daddr, +__u8 prio,__u8 ttl,__be32 label, +__be16 src_port,__be16 dst_port,bool nocheck);void udp_tunnel_sock_release (struct socket *sock);
net/ipv6/ip6_udp_tunnel.c +7 -8
@@ -74,13 +74,13 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, }EXPORT_SYMBOL_GPL (udp_sock_create6); -int udp_tunnel6_xmit_skb (struct dst_entry *dst,struct sock *sk, -struct sk_buff *skb, -struct net_device *dev, -const struct in6_addr *saddr, -const struct in6_addr *daddr, -__u8 prio,__u8 ttl,__be32 label, -__be16 src_port,__be16 dst_port,bool nocheck) +void udp_tunnel6_xmit_skb (struct dst_entry *dst,struct sock *sk, +struct sk_buff *skb, +struct net_device *dev, +const struct in6_addr *saddr, +const struct in6_addr *daddr, +__u8 prio,__u8 ttl,__be32 label, +__be16 src_port,__be16 dst_port,bool nocheck) {struct udphdr *uh;struct ipv6hdr *ip6h;
@@ -109,7 +109,6 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, ip6h->saddr = *saddr;ip6tunnel_xmit (sk, skb, dev); -return 0 ; }EXPORT_SYMBOL_GPL (udp_tunnel6_xmit_skb);
net/sctp/ipv6.c +4 -3
@@ -261,9 +261,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)skb_set_inner_ipproto (skb,IPPROTO_SCTP ); label =ip6_make_flowlabel (sock_net (sk), skb, fl6->flowlabel, true, fl6); -return udp_tunnel6_xmit_skb (dst, sk, skb,NULL , &fl6->saddr, - &fl6->daddr, tclass,ip6_dst_hoplimit (dst), - label,sctp_sk (sk)->udp_port, t->encap_port, false); +udp_tunnel6_xmit_skb (dst, sk, skb,NULL , &fl6->saddr, &fl6->daddr, + tclass,ip6_dst_hoplimit (dst), label, +sctp_sk (sk)->udp_port, t->encap_port, false); +return 0 ; }/* Returns the dst cache entry for the given source and destination ip
net/tipc/udp_media.c +5 -5
@@ -172,7 +172,7 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, struct udp_media_addr *dst, struct dst_cache *cache) { struct dst_entry *ndst; -int ttl, err =0 ; +int ttl, err;local_bh_disable (); ndst =dst_cache_get (cache);
@@ -217,13 +217,13 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, dst_cache_set_ip6(cache, ndst, &fl6.saddr); } ttl =ip6_dst_hoplimit (ndst); - err =udp_tunnel6_xmit_skb (ndst, ub->ubsock->sk, skb,NULL , - &src->ipv6, &dst->ipv6,0 , ttl,0 , - src->port, dst->port, false); +udp_tunnel6_xmit_skb (ndst, ub->ubsock->sk, skb,NULL , + &src->ipv6, &dst->ipv6,0 , ttl,0 , + src->port, dst->port, false);#endif }local_bh_enable (); -return err; +return 0 ; tx_error:local_bh_enable ();
Signature · 1 line
2.49.0
Re: [PATCH net-next 05/14] net: ipv6: Make udp_tunnel6_xmit_skb() void
Quoted 23 lines · Petr Machata
The function always returns zero, thus the return value does not carry any signal. Just make it void.
Most callers already ignore the return value. However:
- Refold arguments of the call from
sctp_v6_xmit()so that they fit into the 80-column limit.-
tipc_udp_xmit()initializes err from the return value, but that should already be always zero at that point. So there's no practical change, but elision of the assignment prompts a couple more tweaks to clean up the function.Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>---
Notes:
CC:Marcelo Ricardo Leitner <[email protected]> CC:[email protected]
CC:Jon Maloy <[email protected]> CC:[email protected]
Quoted 6 lines
include/net/udp_tunnel.h | 14 +++++++------- net/ipv6/ip6_udp_tunnel.c | 15 +++++++-------- net/sctp/ipv6.c | 7 ++++--- net/tipc/udp_media.c | 10 +++++----- 4 files changed, 23 insertions(+), 23 deletions(-)
PATCH 6/14 net: ipv6: Add a flags argument to ip6tunnel_xmit(), udp_tunnel6_xmit_skb()
In reply to Petr Machataip6tunnel_xmit() erases the contents of the SKB control block. In order to be able to set particular IP6CB flags on the SKB, add a corresponding parameter, and propagate it to udp_tunnel6_xmit_skb() as well.
In one of the following patches, VXLAN driver will use this facility to mark packets as subject to IPv6 multicast routing.
---
Notes:
CC:Pablo Neira Ayuso <[email protected]> CC:[email protected] CC:Andrew Lunn <[email protected]> CC:Antonio Quartulli <[email protected]> CC:"Jason A. Donenfeld" <[email protected]> CC:[email protected]
CC:Marcelo Ricardo Leitner <[email protected]> CC:[email protected]
CC:Jon Maloy <[email protected]> CC:[email protected]
drivers/net/bareudp.c | 3 ++- drivers/net/geneve.c | 3 ++- drivers/net/gtp.c | 2 +- drivers/net/ovpn/udp.c | 2 +- drivers/net/vxlan/vxlan_core.c | 3 ++- drivers/net/wireguard/socket.c | 2 +- include/net/ip6_tunnel.h | 3 ++- include/net/udp_tunnel.h | 3 ++- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/ip6_udp_tunnel.c | 5 +++-- net/sctp/ipv6.c | 2 +- net/tipc/udp_media.c | 2 +- 12 files changed, 19 insertions(+), 13 deletions(-)
drivers/net/bareudp.c +2 -1
@@ -431,7 +431,8 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev, &saddr, &daddr, prio, ttl, info->key.label, sport, bareudp->port, !test_bit (IP_TUNNEL_CSUM_BIT , - info->key.tun_flags)); + info->key.tun_flags), + 0);return 0 ; free_dst:
drivers/net/geneve.c +2 -1
@@ -1014,7 +1014,8 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, &saddr, &key->u.ipv6.dst, prio, ttl, info->key.label, sport, geneve->cfg.info.key.tp_dst, !test_bit (IP_TUNNEL_CSUM_BIT , - info->key.tun_flags)); + info->key.tun_flags), + 0); return 0; }#endif
drivers/net/gtp.c +1 -1
@@ -1316,7 +1316,7 @@ static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev)ip6_dst_hoplimit (&pktinfo.rt->dst),0 , pktinfo.gtph_port, pktinfo.gtph_port, - false); + false, 0);#else goto tx_err;#endif
drivers/net/ovpn/udp.c +1 -1
@@ -274,7 +274,7 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, skb->ignore_df =1 ;udp_tunnel6_xmit_skb (dst, sk, skb, skb->dev, &fl.saddr, &fl.daddr,0 ,ip6_dst_hoplimit (dst),0 , fl.fl6_sport, - fl.fl6_dport,udp_get_no_check6_tx (sk)); + fl.fl6_dport,udp_get_no_check6_tx (sk),0 ); ret =0 ; err:local_bh_enable ();
drivers/net/vxlan/vxlan_core.c +2 -1
@@ -2586,7 +2586,8 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,udp_tunnel6_xmit_skb (ndst, sock6->sock->sk, skb, dev, &saddr, &pkey->u.ipv6.dst, tos, ttl, - pkey->label, src_port, dst_port, !udp_sum); + pkey->label, src_port, dst_port, !udp_sum, +0 );#endif }vxlan_vnifilter_count (vxlan, vni,NULL ,VXLAN_VNI_STATS_TX , pkt_len);
drivers/net/wireguard/socket.c +1 -1
@@ -151,7 +151,7 @@ static int send6(struct wg_device *wg, struct sk_buff *skb, skb->ignore_df =1 ;udp_tunnel6_xmit_skb (dst, sock, skb, skb->dev, &fl.saddr, &fl.daddr, ds,ip6_dst_hoplimit (dst),0 , fl.fl6_sport, - fl.fl6_dport, false); + fl.fl6_dport, false,0 ); goto out; err:
include/net/ip6_tunnel.h +2 -1
@@ -152,11 +152,12 @@ int ip6_tnl_get_iflink(const struct net_device *dev);int ip6_tnl_change_mtu (struct net_device *dev,int new_mtu);static inline void ip6tunnel_xmit (struct sock *sk,struct sk_buff *skb, -struct net_device *dev) +struct net_device *dev,u16 ip6cb_flags) {int pkt_len, err;memset (skb->cb,0 ,sizeof (struct inet6_skb_parm )); +IP6CB (skb)->flags = ip6cb_flags; pkt_len = skb->len -skb_inner_network_offset (skb); err =ip6_local_out (dev_net (skb_dst (skb)->dev), sk, skb);
include/net/udp_tunnel.h +2 -1
@@ -158,7 +158,8 @@ void udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,const struct in6_addr *saddr, const struct in6_addr *daddr, __u8 prio, __u8 ttl, __be32 label, - __be16 src_port, __be16 dst_port, bool nocheck); + __be16 src_port, __be16 dst_port, bool nocheck, + u16 ip6cb_flags);void udp_tunnel_sock_release (struct socket *sock);
net/ipv6/ip6_tunnel.c +1 -1
@@ -1278,7 +1278,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, ipv6h->nexthdr = proto; ipv6h->saddr = fl6->saddr; ipv6h->daddr = fl6->daddr; -ip6tunnel_xmit (NULL , skb, dev); +ip6tunnel_xmit (NULL , skb, dev,0 );return 0 ; tx_err_link_failure:DEV_STATS_INC (dev, tx_carrier_errors);
net/ipv6/ip6_udp_tunnel.c +3 -2
@@ -80,7 +80,8 @@ void udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk,const struct in6_addr *saddr, const struct in6_addr *daddr, __u8 prio, __u8 ttl, __be32 label, - __be16 src_port, __be16 dst_port, bool nocheck) + __be16 src_port, __be16 dst_port, bool nocheck, + u16 ip6cb_flags) { struct udphdr *uh;struct ipv6hdr *ip6h;
@@ -108,7 +109,7 @@ void udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, ip6h->daddr = *daddr; ip6h->saddr = *saddr; -ip6tunnel_xmit (sk, skb, dev); +ip6tunnel_xmit (sk, skb, dev, ip6cb_flags); }EXPORT_SYMBOL_GPL (udp_tunnel6_xmit_skb);
net/sctp/ipv6.c +1 -1
@@ -263,7 +263,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t)udp_tunnel6_xmit_skb (dst, sk, skb,NULL , &fl6->saddr, &fl6->daddr, tclass,ip6_dst_hoplimit (dst), label, -sctp_sk (sk)->udp_port, t->encap_port, false); +sctp_sk (sk)->udp_port, t->encap_port, false,0 );return 0 ; }
net/tipc/udp_media.c +1 -1
@@ -219,7 +219,7 @@ static int tipc_udp_xmit(struct net *net, struct sk_buff *skb, ttl =ip6_dst_hoplimit (ndst);udp_tunnel6_xmit_skb (ndst, ub->ubsock->sk, skb,NULL , &src->ipv6, &dst->ipv6,0 , ttl,0 , - src->port, dst->port, false); + src->port, dst->port, false,0 );#endif }local_bh_enable ();
Signature · 1 line
2.49.0
Re: [PATCH net-next 06/14] net: ipv6: Add a flags argument to ip6tunnel_xmit(), udp_tunnel6_xmit_skb()
Quoted 23 lines · Petr Machata
ip6tunnel_xmit()erases the contents of the SKB control block. In order to be able to set particular IP6CB flags on the SKB, add a corresponding parameter, and propagate it toudp_tunnel6_xmit_skb()as well.In one of the following patches, VXLAN driver will use this facility to mark packets as subject to IPv6 multicast routing.
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>---
Notes:
CC:Pablo Neira Ayuso <[email protected]> CC:[email protected] CC:Andrew Lunn <[email protected]> CC:Antonio Quartulli <[email protected]> CC:"Jason A. Donenfeld" <[email protected]> CC:[email protected]
CC:Marcelo Ricardo Leitner <[email protected]> CC:[email protected]
CC:Jon Maloy <[email protected]> CC:[email protected]
Quoted 14 lines
drivers/net/bareudp.c | 3 ++- drivers/net/geneve.c | 3 ++- drivers/net/gtp.c | 2 +- drivers/net/ovpn/udp.c | 2 +- drivers/net/vxlan/vxlan_core.c | 3 ++- drivers/net/wireguard/socket.c | 2 +- include/net/ip6_tunnel.h | 3 ++- include/net/udp_tunnel.h | 3 ++- net/ipv6/ip6_tunnel.c | 2 +- net/ipv6/ip6_udp_tunnel.c | 5 +++-- net/sctp/ipv6.c | 2 +- net/tipc/udp_media.c | 2 +- 12 files changed, 19 insertions(+), 13 deletions(-)
PATCH 7/14 net: ipv6: ip6mr: Fix in/out netdev to pass to the FORWARD chain
In reply to Petr MachataThe netfilter hook is invoked with skb->dev for input netdevice, and vif_dev for output netdevice. However at the point of invocation, skb->dev is already set to vif_dev, and MR-forwarded packets are reported with in=out:
# ip6tables -A FORWARD -j LOG --log-prefix '[forw]' # cd tools/testing/selftests/net/forwarding # ./router_multicast.sh # dmesg | fgrep '[forw]' [ 1670.248245] [forw]IN=v5 OUT=v5 [...]
For reference, IPv4 MR code shows in and out as appropriate. Fix by caching skb->dev and using the updated value for output netdev.
---
Notes:
This never worked correctly, hence going through net-next.
---
CC: YOSHIFUJI Hideaki <[email protected]>
net/ipv6/ip6mr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv6/ip6mr.c +2 -1
@@ -2039,6 +2039,7 @@ static int ip6mr_forward2(struct net *net, struct mr_table *mrt, struct sk_buff *skb, int vifi) {struct vif_device *vif = &mrt->vif_table[vifi]; +struct net_device *indev = skb->dev;struct net_device *vif_dev;struct ipv6hdr *ipv6h;struct dst_entry *dst;
@@ -2101,7 +2102,7 @@ static int ip6mr_forward2(struct net *net, struct mr_table *mrt,IP6CB (skb)->flags |=IP6SKB_FORWARDED ;return NF_HOOK (NFPROTO_IPV6 ,NF_INET_FORWARD , - net,NULL , skb, skb->dev, vif_dev, + net,NULL , skb, indev, skb->dev, ip6mr_forward2_finish); out_free:
Signature · 1 line
2.49.0
Re: [PATCH net-next 07/14] net: ipv6: ip6mr: Fix in/out netdev to pass to the FORWARD chain
Quoted 19 lines · Petr Machata
The netfilter hook is invoked with
skb->devfor input netdevice, andvif_devfor output netdevice. However at the point of invocation,skb->devis already set tovif_dev, and MR-forwarded packets are reported with in=out:# ip6tables -A FORWARD -j LOG --log-prefix '[forw]' # cd tools/testing/selftests/net/forwarding # ./router_multicast.sh # dmesg | fgrep '[forw]' [ 1670.248245] [forw]IN=v5 OUT=v5 [...]For reference, IPv4 MR code shows in and out as appropriate. Fix by caching
skb->devand using the updated value for output netdev.Fixes 7bc570c8b4f7 ("[IPV6] MROUTE: Support multicast forwarding.")Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>---
Quoted 8 lines
Notes:
This never worked correctly, hence going through net-next.
---
CC: YOSHIFUJI Hideaki <[email protected]>net/ipv6/ip6mr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
PATCH 8/14 net: ipv6: ip6mr: Extract a helper out of ip6mr_forward2()
In reply to Petr MachataSome of the work of ip6mr_forward2() is specific to IPMR forwarding, and should not take place on the output path. In order to allow reuse of the common parts, extract out of the function a helper, ip6mr_prepare_forward().
--- net/ipv6/ip6mr.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
net/ipv6/ip6mr.c +16 -6
@@ -2035,11 +2035,10 @@ static inline int ip6mr_forward2_finish(struct net *net, struct sock *sk, struct* Processing handlers for ip6mr_forward */ -static int ip6mr_forward2 (struct net *net,struct mr_table *mrt, -struct sk_buff *skb,int vifi) +static int ip6mr_prepare_xmit (struct net *net,struct mr_table *mrt, +struct sk_buff *skb,int vifi) {struct vif_device *vif = &mrt->vif_table[vifi]; -struct net_device *indev = skb->dev;struct net_device *vif_dev;struct ipv6hdr *ipv6h;struct dst_entry *dst;
@@ -2098,6 +2097,20 @@ static int ip6mr_forward2(struct net *net, struct mr_table *mrt, ipv6h =ipv6_hdr (skb); ipv6h->hop_limit--; +return 0 ; + +out_free: +kfree_skb (skb); +return -1 ; +} + +static int ip6mr_forward2 (struct net *net,struct mr_table *mrt, +struct sk_buff *skb,int vifi) +{ +struct net_device *indev = skb->dev; + +if (ip6mr_prepare_xmit (net, mrt, skb, vifi)) +return 0 ;IP6CB (skb)->flags |=IP6SKB_FORWARDED ;
@@ -2105,9 +2118,6 @@ static int ip6mr_forward2(struct net *net, struct mr_table *mrt, net,NULL , skb, indev, skb->dev, ip6mr_forward2_finish); -out_free: -kfree_skb (skb); -return 0 ; }/* Called with rcu_read_lock() */
Signature · 1 line
2.49.0
Re: [PATCH net-next 08/14] net: ipv6: ip6mr: Extract a helper out of ip6mr_forward2()
Quoted 11 lines · Petr Machata
Some of the work of
ip6mr_forward2()is specific to IPMR forwarding, and should not take place on the output path. In order to allow reuse of the common parts, extract out of the function a helper,ip6mr_prepare_forward().Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>--- net/ipv6/ip6mr.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
PATCH 9/14 net: ipv6: Add ip6_mr_output()
In reply to Petr MachataMulticast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code today. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. Thus MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
To that end, this patch adds support to route locally generated multicast packets. The newly-added routines do largely what ip6_mr_input() and ip6_mr_forward() do: make an MR cache lookup to find where to send the packets, and use ip6_output() to send each of them. When no cache entry is found, the packet is punted to the daemon for resolution.
Similarly to the IPv4 case in a previous patch, the new logic is contingent on a newly-added IP6CB flag being set.
--- include/linux/ipv6.h | 1 + include/linux/mroute6.h | 7 +++ net/ipv6/ip6mr.c | 114 ++++++++++++++++++++++++++++++++++++++++ net/ipv6/route.c | 1 + 4 files changed, 123 insertions(+)
include/linux/ipv6.h +1 -0
@@ -156,6 +156,7 @@ struct inet6_skb_parm {#define IP6SKB_SEG6 256#define IP6SKB_FAKEJUMBO 512#define IP6SKB_MULTIPATH 1024 +#define IP6SKB_MCROUTE 2048 };#if defined(CONFIG_NET_L3_MASTER_DEV )
include/linux/mroute6.h +7 -0
@@ -31,6 +31,7 @@ extern int ip6_mroute_getsockopt(struct sock *, int, sockptr_t, sockptr_t);extern int ip6_mr_input (struct sk_buff *skb);extern int ip6mr_compat_ioctl (struct sock *sk,unsigned int cmd,void __user *arg);extern int ip6_mr_init (void ); +extern int ip6_mr_output (struct net *net,struct sock *sk,struct sk_buff *skb);extern void ip6_mr_cleanup (void );int ip6mr_ioctl (struct sock *sk,int cmd,void *arg);#else
@@ -58,6 +59,12 @@ static inline int ip6_mr_init(void)return 0 ; } +static inline int +ip6_mr_output (struct net *net,struct sock *sk,struct sk_buff *skb) +{ +return 0 ; +} +static inline void ip6_mr_cleanup (void ) {return ;
net/ipv6/ip6mr.c +114 -0
132 lines not on this page · raw message
net/ipv6/route.c +1 -0
@@ -1145,6 +1145,7 @@ static void ip6_rt_init_dst(struct rt6_info *rt, const struct fib6_result *res) rt->dst.input = ip6_input; }else if (ipv6_addr_type (&f6i->fib6_dst.addr) &IPV6_ADDR_MULTICAST ) { rt->dst.input = ip6_mc_input; + rt->dst.output = ip6_mr_output; }else { rt->dst.input = ip6_forward; }
Signature · 1 line
2.49.0
Re: [PATCH net-next 09/14] net: ipv6: Add ip6_mr_output()
Quoted 15 lines · Petr Machata
Multicast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code today. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. Thus MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
To that end, this patch adds support to route locally generated multicast packets. The newly-added routines do largely what
ip6_mr_input()andip6_mr_forward()do: make an MR cache lookup to find where to send the packets, and useip6_output()to send each of them. When no cache entry is found, the packet is punted to the daemon for resolution.Similarly to the IPv4 case in a previous patch, the new logic is contingent on a newly-added IP6CB flag being set.
Quoted 9 lines
Signed-off-by Petr Machata <[email protected]>Reviewed-by Ido Schimmel <[email protected]>--- include/linux/ipv6.h | 1 + include/linux/mroute6.h | 7 +++ net/ipv6/ip6mr.c | 114 ++++++++++++++++++++++++++++++++++++++++ net/ipv6/route.c | 1 + 4 files changed, 123 insertions(+)
Looks good to me,
PATCH 10/14 vxlan: Support MC routing in the underlay
In reply to Petr MachataLocally-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.
---
Notes:
CC:Andrew Lunn <[email protected]>
CC:Menglong Dong <[email protected]>
drivers/net/vxlan/vxlan_core.c | 22 ++++++++++++++++++++-- include/net/vxlan.h | 5 ++++- include/uapi/linux/if_link.h | 1 + 3 files changed, 25 insertions(+), 3 deletions(-)
drivers/net/vxlan/vxlan_core.c +20 -2
@@ -2451,6 +2451,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,rcu_read_lock ();if (addr_family ==AF_INET ) {struct vxlan_sock *sock4 =rcu_dereference (vxlan->vn4_sock); +u16 ipcb_flags =0 ;struct rtable *rt;__be16 df =0 ;__be32 saddr;
@@ -2467,6 +2468,9 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, goto tx_error; } +if (flags &VXLAN_F_MC_ROUTE ) + ipcb_flags |=IPSKB_MCROUTE ; +if (!info) {/* Bypass encapsulation if the destination is local */ 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,udp_tunnel_xmit_skb (rt, sock4->sock->sk, skb, saddr, pkey->u.ipv4.dst, tos, ttl, df, - src_port, dst_port, xnet, !udp_sum,0 ); + src_port, dst_port, xnet, !udp_sum, + ipcb_flags);#if IS_ENABLED (CONFIG_IPV6 ) } else {struct vxlan_sock *sock6 =rcu_dereference (vxlan->vn6_sock);struct in6_addr saddr; +u16 ip6cb_flags =0 ;if (!ifindex) ifindex = sock6->sock->sk->sk_bound_dev_if;
@@ -2542,6 +2548,9 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, goto tx_error; } +if (flags &VXLAN_F_MC_ROUTE ) + ip6cb_flags |=IP6SKB_MCROUTE ; +if (!info) {u32 rt6i_flags =dst_rt6_info (ndst)->rt6i_flags;
@@ -2587,7 +2596,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,udp_tunnel6_xmit_skb (ndst, sock6->sock->sk, skb, dev, &saddr, &pkey->u.ipv6.dst, tos, ttl, pkey->label, src_port, dst_port, !udp_sum, -0 ); + ip6cb_flags);#endif }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] = { [IFLA_VXLAN_LOCALBYPASS] = NLA_POLICY_MAX(NLA_U8, 1), [IFLA_VXLAN_LABEL_POLICY] = NLA_POLICY_MAX(NLA_U32, VXLAN_LABEL_MAX), [IFLA_VXLAN_RESERVED_BITS] = NLA_POLICY_EXACT_LEN(sizeof(struct vxlanhdr)), + [IFLA_VXLAN_MC_ROUTE] = NLA_POLICY_MAX(NLA_U8, 1), }; static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -4315,6 +4325,14 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],return err; } +if (data[IFLA_VXLAN_MC_ROUTE ]) { + err =vxlan_nl2flag (conf, data,IFLA_VXLAN_MC_ROUTE , +VXLAN_F_MC_ROUTE , changelink, + true, extack); +if (err) +return err; + } +if (tb[IFLA_MTU ]) {if (changelink) { NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_MTU],
include/net/vxlan.h +4 -1
@@ -332,6 +332,7 @@ struct vxlan_dev {#define VXLAN_F_VNIFILTER 0x20000#define VXLAN_F_MDB 0x40000#define VXLAN_F_LOCALBYPASS 0x80000 +#define VXLAN_F_MC_ROUTE 0x100000/* Flags that are used in the receive path. These flags must match in * order for a socket to be shareable
@@ -353,7 +354,9 @@ struct vxlan_dev { VXLAN_F_UDP_ZERO_CSUM6_RX | \ VXLAN_F_COLLECT_METADATA | \ VXLAN_F_VNIFILTER | \ - VXLAN_F_LOCALBYPASS) + VXLAN_F_LOCALBYPASS | \ + VXLAN_F_MC_ROUTE | \ + 0)struct net_device *vxlan_dev_create (struct net *net,const char *name,u8 name_assign_type,struct vxlan_config *conf);
include/uapi/linux/if_link.h +1 -0
@@ -1398,6 +1398,7 @@ enum {IFLA_VXLAN_LOCALBYPASS ,IFLA_VXLAN_LABEL_POLICY ,/* IPv6 flow label policy; ifla_vxlan_label_policy */ IFLA_VXLAN_RESERVED_BITS , +IFLA_VXLAN_MC_ROUTE , __IFLA_VXLAN_MAX };#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
Signature · 1 line
2.49.0
Re: [PATCH net-next 10/14] vxlan: Support MC routing in the underlay
Quoted 16 lines · Petr Machata
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()andip6_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]>---
Quoted 9 lines
Notes:
CC:Andrew Lunn <[email protected]>
CC:Menglong Dong <[email protected]>drivers/net/vxlan/vxlan_core.c | 22 ++++++++++++++++++++-- include/net/vxlan.h | 5 ++++- include/uapi/linux/if_link.h | 1 + 3 files changed, 25 insertions(+), 3 deletions(-)
PATCH 11/14 selftests: forwarding: lib: Move smcrouted helpers here
In reply to Petr Machatarouter_multicast.sh has several helpers for work with smcrouted. Extract them to lib.sh so that other selftests can use them as well. Convert the helpers to defer in the process, because that simplifies the interface quite a bit. Therefore have router_multicast.sh invoke defer_scopes_cleanup() in its cleanup() function.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]
tools/testing/selftests/net/forwarding/lib.sh | 31 +++++++++++++++++++ .../net/forwarding/router_multicast.sh | 31 +++---------------- 2 files changed, 35 insertions(+), 27 deletions(-)
tools/testing/selftests/net/forwarding/lib.sh +31 -0
@@ -37,6 +37,7 @@ declare -A NETIFS=( : "${TEAMD:=teamd}" : "${MCD:=smcrouted}" : "${MC_CLI:=smcroutectl}" +: "${MCD_TABLE_NAME:=selftests}" # Constants for netdevice bring-up: # Default time in seconds to wait for an interface to come up before giving up
@@ -1757,6 +1758,36 @@ mc_send() msend -g $groups -I $if_name -c 1 > /dev/null 2>&1 } +adf_mcd_start() +{ + local i + + check_command $MCD || return 1 + check_command $MC_CLI || return 1 + + local table_name="$MCD_TABLE_NAME" + local smcroutedir="$(mktemp -d)" + + defer rm -rf $smcroutedir + + for ((i = 1; i <= $NUM_NETIFS; ++i)); do + echo "phyint ${NETIFS[p$i]} enable" >> \ + $smcroutedir/$table_name.conf + done + + $MCD -N -I $table_name -f $smcroutedir/$table_name.conf \ + -P $smcroutedir/$table_name.pid + busywait "$BUSYWAIT_TIMEOUT" test -e $smcroutedir/$table_name.pid + defer kill_process $(cat $smcroutedir/$table_name.pid) +} + +mc_cli() +{ + local table_name="$MCD_TABLE_NAME" + + $MC_CLI -I $table_name "$@" +} + start_ip_monitor() { local mtype=$1; shift
tools/testing/selftests/net/forwarding/router_multicast.sh +4 -27
@@ -33,10 +33,6 @@ NUM_NETIFS=6 source lib.sh source tc_common.sh -require_command $MCD -require_command $MC_CLI -table_name=selftests - h1_create() { simple_if_init $h1 198.51.100.2/28 2001:db8:1::2/64
@@ -149,25 +145,6 @@ router_destroy() ip link set dev $rp1 down } -start_mcd() -{ - SMCROUTEDIR="$(mktemp -d)" - - for ((i = 1; i <= $NUM_NETIFS; ++i)); do - echo "phyint ${NETIFS[p$i]} enable" >> \ - $SMCROUTEDIR/$table_name.conf - done - - $MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \ - -P $SMCROUTEDIR/$table_name.pid -} - -kill_mcd() -{ - pkill $MCD - rm -rf $SMCROUTEDIR -} - setup_prepare() { h1=${NETIFS[p1]}
@@ -179,7 +156,7 @@ setup_prepare() rp3=${NETIFS[p5]} h3=${NETIFS[p6]} - start_mcd + adf_mcd_start || exit $EXIT_STATUS vrf_prepare
@@ -206,7 +183,7 @@ cleanup() vrf_cleanup - kill_mcd + defer_scopes_cleanup } create_mcast_sg()
@@ -216,7 +193,7 @@ create_mcast_sg() local mcast=$1; shift local dest_ifs=${@} - $MC_CLI -I $table_name add $if_name $s_addr $mcast $dest_ifs + mc_cli add $if_name $s_addr $mcast $dest_ifs } delete_mcast_sg()
@@ -226,7 +203,7 @@ delete_mcast_sg() local mcast=$1; shift local dest_ifs=${@} - $MC_CLI -I $table_name remove $if_name $s_addr $mcast $dest_ifs + mc_cli remove $if_name $s_addr $mcast $dest_ifs } mcast_v4()
Signature · 1 line
2.49.0
Re: [PATCH net-next 11/14] selftests: forwarding: lib: Move smcrouted helpers here
Quoted 9 lines · Petr Machata
router_multicast.shhas several helpers for work with smcrouted. Extract them tolib.shso that other selftests can use them as well. Convert the helpers to defer in the process, because that simplifies the interface quite a bit. Therefore haverouter_multicast.shinvokedefer_scopes_cleanup()in itscleanup()function.Signed-off-by Petr Machata <[email protected]>---
Quoted 8 lines
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]tools/testing/selftests/net/forwarding/lib.sh | 31 +++++++++++++++++++ .../net/forwarding/router_multicast.sh | 31 +++---------------- 2 files changed, 35 insertions(+), 27 deletions(-)
PATCH 12/14 selftests: net: lib: Add ip_link_has_flag()
In reply to Petr MachataAdd a helper to determine whether a given netdevice has a given flag.
Rewrite ip_link_is_up() in terms of the new helper.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]
tools/testing/selftests/net/lib.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
tools/testing/selftests/net/lib.sh +9 -3
@@ -547,13 +547,19 @@ ip_link_set_addr() defer ip link set dev "$name" address "$old_addr" } -ip_link_is_up() +ip_link_has_flag() { local name=$1; shift + local flag=$1; shift local state=$(ip -j link show "$name" | - jq -r '(.[].flags[] | select(. == "UP")) // "DOWN"') - [[ $state == "UP" ]] + jq --arg flag "$flag" 'any(.[].flags.[]; . == $flag)') + [[ $state == true ]] +} + +ip_link_is_up() +{ + ip_link_has_flag "$1" UP } ip_link_set_up()
Signature · 1 line
2.49.0
Re: [PATCH net-next 12/14] selftests: net: lib: Add ip_link_has_flag()
Quoted 5 lines · Petr Machata
Add a helper to determine whether a given netdevice has a given flag.
Rewrite
ip_link_is_up()in terms of the new helper.Signed-off-by Petr Machata <[email protected]>
Quoted 9 lines
---
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]tools/testing/selftests/net/lib.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
PATCH 13/14 selftests: forwarding: adf_mcd_start(): Allow configuring custom interfaces
In reply to Petr MachataTests may wish to add other interfaces to listen on. Notably locally generated traffic uses dummy interfaces. The multicast daemon needs to know about these so that it allows forming rules that involve these interfaces, and so that net.ipv4.conf.X.mc_forwarding is set for the interfaces.
To that end, allow passing in a list of interfaces to configure in addition to all the physical ones.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]
tools/testing/selftests/net/forwarding/lib.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+)
tools/testing/selftests/net/forwarding/lib.sh +12 -0
@@ -1760,6 +1760,8 @@ mc_send() adf_mcd_start() { + local ifs=("$@") + local if local i check_command $MCD || return 1
@@ -1775,6 +1777,16 @@ adf_mcd_start() $smcroutedir/$table_name.conf done + for if in ${ifs[@]}; do + if ! ip_link_has_flag "$if" MULTICAST; then + ip link set dev "$if" multicast on + defer ip link set dev "$if" multicast off + fi + + echo "phyint $if enable" >> \ + $smcroutedir/$table_name.conf + done + $MCD -N -I $table_name -f $smcroutedir/$table_name.conf \ -P $smcroutedir/$table_name.pid busywait "$BUSYWAIT_TIMEOUT" test -e $smcroutedir/$table_name.pid
Signature · 1 line
2.49.0
Re: [PATCH net-next 13/14] selftests: forwarding: adf_mcd_start(): Allow configuring custom interfaces
Quoted 9 lines · Petr Machata
Tests may wish to add other interfaces to listen on. Notably locally generated traffic uses dummy interfaces. The multicast daemon needs to know about these so that it allows forming rules that involve these interfaces, and so that net.ipv4.conf.X.mc_forwarding is set for the interfaces.
To that end, allow passing in a list of interfaces to configure in addition to all the physical ones.
Signed-off-by Petr Machata <[email protected]>
Quoted 9 lines
---
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]tools/testing/selftests/net/forwarding/lib.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+)
PATCH 14/14 selftests: forwarding: Add a test for verifying VXLAN MC underlay
In reply to Petr MachataAdd tests for MC-routing underlay VXLAN traffic.
---
Notes:
CC: Shuah Khan <[email protected]>
CC: [email protected]
.../testing/selftests/net/forwarding/Makefile | 1 + .../net/forwarding/vxlan_bridge_1q_mc_ul.sh | 757 ++++++++++++++++++ 2 files changed, 758 insertions(+) create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1q_mc_ul.sh
tools/testing/selftests/net/forwarding/Makefile +1 -0
@@ -102,6 +102,7 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \ vxlan_bridge_1d_port_8472.sh \ vxlan_bridge_1d.sh \ vxlan_bridge_1q_ipv6.sh \ + vxlan_bridge_1q_mc_ul.sh \ vxlan_bridge_1q_port_8472_ipv6.sh \ vxlan_bridge_1q_port_8472.sh \ vxlan_bridge_1q.sh \
tools/testing/selftests/net/forwarding/vxlan_bridge_1q_mc_ul.sh new file +757 -0
757 lines not on this page · raw message
Signature · 1 line
2.49.0
Jakub Kicinski
maintainerRe: [PATCH net-next 14/14] selftests: forwarding: Add a test for verifying VXLAN MC underlay
Quoted 1 line · On Mon, 9 Jun 2025 22:50:30 +0200 Petr Machata wrote:
Add tests for MC-routing underlay VXLAN traffic.
nit: we started using shellcheck, may be worth addressing the warning-level complaints?
Re: [PATCH net-next 14/14] selftests: forwarding: Add a test for verifying VXLAN MC underlay
Quoted 5 lines · Jakub Kicinski
Quoted 1 line · On Mon, 9 Jun 2025 22:50:30 +0200 Petr Machata wrote:
Add tests for MC-routing underlay VXLAN traffic.
nit: we started using shellcheck, may be worth addressing the warning-level complaints?
Sure. Sorry, I noticed and meant to do that, but it slipped my mind :-|
Jakub Kicinski
maintainerQuoted 6 lines · On Mon, 9 Jun 2025 22:50:16 +0200 Petr Machata wrote:
Multicast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. In practice that means that MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
I think this leads to kmemleaks:
unreferenced object 0xffff88800aabe740 (size 232):
comm "kworker/0:2", pid 471, jiffies 4295215616
hex dump (first 32 bytes):
00 40 df 08 80 88 ff ff 00 f7 5d 98 ff ff ff ff .@........].....
a1 55 19 95 ff ff ff ff 00 00 00 00 00 00 00 00 .U..............
backtrace (crc b1fabddb):kmem_cache_alloc_noprof (./include/linux/kmemleak.h:43 mm/slub.c:4152 mm/slub.c:4197 mm/slub.c:4204) dst_alloc (net/core/dst.c:89)
ip6_rt_pcpu_alloc (net/ipv6/route.c:342 net/ipv6/route.c:1419) ip6_pol_route (net/ipv6/route.c:1468 net/ipv6/route.c:2305) fib6_rule_lookup (./include/net/ip6_fib.h:617 net/ipv6/ip6_fib.c:326) ip6_route_output_flags (net/ipv6/route.c:2699) ip6_dst_lookup_tail.constprop.0 (net/ipv6/ip6_output.c:1128) ip6_dst_lookup_flow (net/ipv6/ip6_output.c:1260) udp_tunnel6_dst_lookup (net/ipv6/ip6_udp_tunnel.c:165 net/ipv6/ip6_udp_tunnel.c:135) ip6_udp_tunnel vxlan_xmit_one (drivers/net/vxlan/vxlan_core.c:2540 (discriminator 4)) vxlan vxlan_xmit (drivers/net/vxlan/vxlan_core.c:2809) vxlan dev_hard_start_xmit (./include/linux/netdevice.h:5215 ./include/linux/netdevice.h:5224 net/core/dev.c:3830 net/core/dev.c:3846) __dev_queue_xmit (net/core/dev.h:356 net/core/dev.c:4714) ip6_finish_output2 (./include/net/neighbour.h:539 net/ipv6/ip6_output.c:141) ip6_finish_output.constprop.0 (net/ipv6/ip6_output.c:215 net/ipv6/ip6_output.c:226)
mld_sendpack (net/ipv6/mcast.c:1872)
hit by netdevsim udp_tunnel_nic.sh
Also, do you have a branch with the iproute2 patches we could pull in the CI?
Quoted 11 lines · Jakub Kicinski
Quoted 6 lines · On Mon, 9 Jun 2025 22:50:16 +0200 Petr Machata wrote:
Multicast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. In practice that means that MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
I think this leads to kmemleaks:
[...]
hit by netdevsimudp_tunnel_nic.sh
Thanks, I'll take a look.
Quoted 2 lines
Also, do you have a branch with the iproute2 patches we could pull in the CI?
My bad, didn't think of it:
https://github.com/pmachata/iproute2/commits/vxlan_mc_ul/
Quoted 10 lines · Petr Machata
Quoted 8 lines · Jakub Kicinski
Quoted 6 lines · On Mon, 9 Jun 2025 22:50:16 +0200 Petr Machata wrote:
Multicast routing is today handled in the input path. Locally generated MC packets don't hit the IPMR code. Thus if a VXLAN remote address is multicast, the driver needs to set an OIF during route lookup. In practice that means that MC routing configuration needs to be kept in sync with the VXLAN FDB and MDB. Ideally, the VXLAN packets would be routed by the MC routing code instead.
Quoted 5 lines
Quoted 3 lines
I think this leads to kmemleaks:
[...]
hit by netdevsimudp_tunnel_nic.shThanks, I'll take a look.
Hmm, I can't reproduce this :-| I'm using the following incantation to build the kernel:
vng --build --config tools/testing/selftests/net/forwarding/config \
--config tools/testing/selftests/drivers/net/config \
--config tools/testing/selftests/drivers/net/netdevsim/config \
--config kernel/configs/debug.configAnd run the test like so:
vng -v --run . --user root --cpus 4 -- \
make -C tools/testing/selftests TARGETS=drivers/net/netdevsim \
TEST_PROGS=udp_tunnel_nic.sh TEST_GEN_PROGS="" run_testsvng -v --run . --user root --cpus 4 -- \
bash -c 'make -C tools/testing/selftests TARGETS=drivers/net/netdevsim \
TEST_PROGS=udp_tunnel_nic.sh TEST_GEN_PROGS="" run_tests; \
echo scan > /sys/kernel/debug/kmemleak; \
cat /sys/kernel/debug/kmemleak'Anything I'm missing, or is this what the CI is doing, more or less?
Could it actually have been caused by another test? The howto page mentions that the CI is running the tests one at a time, so I don't suppose that's a possibility.
I'll try to run a more fuller suite tomorrow and star at the code a bit to see if I might be missing an error branch or something.
Jakub Kicinski
maintainerQuoted 6 lines · On Wed, 11 Jun 2025 17:30:15 +0200 Petr Machata wrote:
Could it actually have been caused by another test? The howto page mentions that the CI is running the tests one at a time, so I don't suppose that's a possibility.
I'll try to run a more fuller suite tomorrow and star at the code a bit to see if I might be missing an error branch or something.
We also hit a crash in ipv6 fcnal.sh, too. Looks like this is either a kmemleak false positive or possibly related to the rtnl changes in ipv6. Either way I it's not related to you changes, sorry about that! :(
[ 2900.792890] BUG: kernel NULL pointer dereference, address: 0000000000000108 [ 2900.792961] #PF: supervisor read access in kernel mode [ 2900.793017] #PF: error_code(0x0000) - not-present page [ 2900.793053] PGD 8fd6067 P4D 8fd6067 PUD 6402067 PMD 0 [ 2900.793097] Oops: Oops: 0000 [#1] SMP NOPTI [ 2900.793127] CPU: 0 UID: 0 PID: 15652 Comm: nettest Not tainted 6.15.0-virtme #1 PREEMPT(voluntary) [ 2900.793200] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 2900.793245] RIP: 0010:ip6_pol_route+0x286/0x4a0 [ 2900.793290] Code: 0c 24 0f 85 fb 01 00 00 09 ca 0f 88 2f 01 00 00 e8 cf 11 43 ff 83 cb 08 48 8d 7c 24 18 e8 32 7b ff ff 0f b7 cb ba ff ff ff ff <4c> 8b 80 08 01 00 00 48 89 c6 49 89 c7 49 8d b8 80 06 00 00 4c 89 [ 2900.793422] RSP: 0018:ffffc08a0932f480 EFLAGS: 00010246 [ 2900.793460] RAX: 0000000000000000 RBX: 0000000000000008 RCX: 0000000000000008 [ 2900.793521] RDX: 00000000ffffffff RSI: ffffc08a0932f740 RDI: ffff9adac8c8f1a8 [ 2900.793580] RBP: ffff9adac87458c0 R08: 0000000000000000 R09: 0000000000000000 [ 2900.793635] R10: 0000000000000000 R11: 0000000000000040 R12: ffff9adac82e362c [ 2900.793692] R13: ffff9adac82e3600 R14: 0000000000000080 R15: 0000000000000000 [ 2900.793752] FS: 00007f3418913740(0000) GS:ffff9adb7373a000(0000) knlGS:0000000000000000 [ 2900.793816] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2900.793864] CR2: 0000000000000108 CR3: 0000000008007004 CR4: 0000000000772ef0 [ 2900.793920] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 2900.793977] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 2900.794031] PKRU: 55555554 [ 2900.794050] Call Trace: [ 2900.794070] <TASK> [ 2900.794090] ? __pfx_ip6_pol_route_output+0x10/0x10 [ 2900.794131] fib6_rule_action+0xe3/0x310 [ 2900.794166] fib_rules_lookup+0x1b2/0x2b0 [ 2900.794200] ? __pfx_ip6_pol_route_output+0x10/0x10 [ 2900.794241] fib6_rule_lookup+0xa9/0x270 [ 2900.794271] ? __pfx_ip6_pol_route_output+0x10/0x10 [ 2900.794310] ip6_route_output_flags+0xab/0x180 [ 2900.794353] ip6_dst_lookup_tail.constprop.0+0x282/0x340 [ 2900.794394] ip6_dst_lookup_flow+0x46/0xc0 [ 2900.794422] vrf_xmit+0x100/0x4a0 [ 2900.794459] dev_hard_start_xmit+0x8d/0x1c0
https://netdev-3.bots.linux.dev/vmksft-net/results/160541/vm-crash-thr0-0
From: Jakub Kicinski <[email protected]>
Date: Wed, 11 Jun 2025 13:23:20 -0700
Quoted 12 lines · On Wed, 11 Jun 2025 17:30:15 +0200 Petr Machata wrote:
Quoted 6 lines
Could it actually have been caused by another test? The howto page mentions that the CI is running the tests one at a time, so I don't suppose that's a possibility.
I'll try to run a more fuller suite tomorrow and star at the code a bit to see if I might be missing an error branch or something.
We also hit a crash in ipv6
fcnal.sh, too. Looks like this is either a kmemleak false positive or possibly related to the rtnl changes in ipv6. Either way I it's not related to you changes, sorry about that! :(
Quoted 8 lines
[ 2900.792890] BUG: kernel NULL pointer dereference, address: 0000000000000108 [ 2900.792961] #PF: supervisor read access in kernel mode [ 2900.793017] #PF: error_code(0x0000) - not-present page [ 2900.793053] PGD 8fd6067 P4D 8fd6067 PUD 6402067 PMD 0 [ 2900.793097] Oops: Oops: 0000 [#1] SMP NOPTI [ 2900.793127] CPU: 0 UID: 0 PID: 15652 Comm: nettest Not tainted 6.15.0-virtme #1 PREEMPT(voluntary) [ 2900.793200] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 2900.793245] RIP: 0010:ip6_pol_route+0x286/0x4a0
fwiw, my local syzkaller had the same splat on 6a325aed130b, where my IPv6 series hadn't landed, and syzbot had a similar one on f1b785f4c787, where my RTNL work was on the prep stage, so I think this is an old? bug :)
I'll see if the .syz repro in the report still works on the latest.
syzbot:
https://lore.kernel.org/netdev/[email protected]/
syzkaller:
---8<---
BUG: unable to handle page fault for address: 00007f93e4d51a23 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 12cd4c067 P4D 125130067 PUD 0 Oops: Oops: 0000 [#1] SMP CPU: 1 UID: 0 PID: 2259 Comm: syz.2.555 Not tainted 6.15.0-rc1-00220-g6a325aed130b #2 PREEMPT(voluntary) fb2957dd255dfc2983199dfa2ccdedc09370f316 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 RIP: 0010:arch_atomic_read arch/x86/include/asm/atomic.h:23 [inline] RIP: 0010:raw_atomic_read include/linux/atomic/atomic-arch-fallback.h:457 [inline] RIP: 0010:atomic_read include/linux/atomic/atomic-instrumented.h:33 [inline] RIP: 0010:rt_genid_ipv6 include/net/net_namespace.h:537 [inline] RIP: 0010:rt6_is_valid net/ipv6/route.c:1435 [inline] RIP: 0010:rt6_get_pcpu_route net/ipv6/route.c:1445 [inline] RIP: 0010:ip6_pol_route+0x301/0x9d0 net/ipv6/route.c:2298 Code: a9 fe 4d 85 ff 4c 8b 74 24 10 74 3b 41 8b 9f 98 00 00 00 31 ff 89 de e8 3d 37 a9 fe 85 db 74 33 49 8b 07 48 8b 80 08 01 00 00 <8b> a8 24 0a 00 00 89 df 89 ee e8 f0 34 a9 fe 39 eb 75 20 e8 67 33 RSP: 0018:ffa0000000c3ba20 EFLAGS: 00010202 RAX: 00007f93e4d50fff RBX: 000000001ac62540 RCX: 0000000000000002 RDX: ff11000005e99700 RSI: 000000001ac62540 RDI: 0000000000000000 RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000ffff0000 R11: 0000000000000002 R12: ffffffff829af127 R13: 0000000000000000 R14: ff110001053e2580 R15: ff1100012505f400 FS: 00007f190e8276c0(0000) GS:ff110001b79d2000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f93e4d51a23 CR3: 000000011d7b5004 CR4: 0000000000771ef0 DR0: 0000000080000001 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000600 PKRU: 80000000 Call Trace: <TASK> pol_lookup_func include/net/ip6_fib.h:616 [inline] fib6_rule_lookup+0xe8/0x2a0 net/ipv6/fib6_rules.c:120 ip6_route_output_flags_noref net/ipv6/route.c:2673 [inline] ip6_route_output_flags+0x188/0x260 net/ipv6/route.c:2685 ip6_route_output include/net/ip6_route.h:93 [inline] ip6_dst_lookup_tail+0x9a/0x7d0 net/ipv6/ip6_output.c:1128 ip6_dst_lookup_flow+0x47/0xe0 net/ipv6/ip6_output.c:1259 tcp_v6_connect+0x50c/0x8e0 net/ipv6/tcp_ipv6.c:277 mptcp_connect+0x389/0x680 net/mptcp/protocol.c:3683 __inet_stream_connect+0x11f/0x5c0 net/ipv4/af_inet.c:677 inet_stream_connect+0x36/0x50 net/ipv4/af_inet.c:748 __sys_connect_file net/socket.c:2038 [inline] __sys_connect+0x17b/0x220 net/socket.c:2057 __do_sys_connect net/socket.c:2063 [inline] __se_sys_connect net/socket.c:2060 [inline] __x64_sys_connect+0x1c/0x20 net/socket.c:2060 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xc8/0x1a0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7f19101bd169 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f190e827038 EFLAGS: 00000246 ORIG_RAX: 000000000000002a RAX: ffffffffffffffda RBX: 00007f19103d5fa0 RCX: 00007f19101bd169 RDX: 000000000000001c RSI: 0000200000000000 RDI: 0000000000000004 RBP: 00007f191023e730 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f19103d5fa0 R15: 00007f19104ffa28 </TASK> Modules linked in: CR2: 00007f93e4d51a23 ---[ end trace 0000000000000000 ]--- RIP: 0010:arch_atomic_read arch/x86/include/asm/atomic.h:23 [inline] RIP: 0010:raw_atomic_read include/linux/atomic/atomic-arch-fallback.h:457 [inline] RIP: 0010:atomic_read include/linux/atomic/atomic-instrumented.h:33 [inline] RIP: 0010:rt_genid_ipv6 include/net/net_namespace.h:537 [inline] RIP: 0010:rt6_is_valid net/ipv6/route.c:1435 [inline] RIP: 0010:rt6_get_pcpu_route net/ipv6/route.c:1445 [inline] RIP: 0010:ip6_pol_route+0x301/0x9d0 net/ipv6/route.c:2298 Code: a9 fe 4d 85 ff 4c 8b 74 24 10 74 3b 41 8b 9f 98 00 00 00 31 ff 89 de e8 3d 37 a9 fe 85 db 74 33 49 8b 07 48 8b 80 08 01 00 00 <8b> a8 24 0a 00 00 89 df 89 ee e8 f0 34 a9 fe 39 eb 75 20 e8 67 33 RSP: 0018:ffa0000000c3ba20 EFLAGS: 00010202 RAX: 00007f93e4d50fff RBX: 000000001ac62540 RCX: 0000000000000002 RDX: ff11000005e99700 RSI: 000000001ac62540 RDI: 0000000000000000 RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000ffff0000 R11: 0000000000000002 R12: ffffffff829af127 R13: 0000000000000000 R14: ff110001053e2580 R15: ff1100012505f400 FS: 00007f190e8276c0(0000) GS:ff110001b79d2000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f93e4d51a23 CR3: 000000011d7b5004 CR4: 0000000000771ef0 DR0: 0000000080000001 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000600 PKRU: 80000000 ---------------- Code disassembly (best guess): 0: a9 fe 4d 85 ff test $0xff854dfe,%eax 5: 4c 8b 74 24 10 mov 0x10(%rsp),%r14 a: 74 3b je 0x47 c: 41 8b 9f 98 00 00 00 mov 0x98(%r15),%ebx 13: 31 ff xor %edi,%edi 15: 89 de mov %ebx,%esi 17: e8 3d 37 a9 fe call 0xfea93759 1c: 85 db test %ebx,%ebx 1e: 74 33 je 0x53 20: 49 8b 07 mov (%r15),%rax 23: 48 8b 80 08 01 00 00 mov 0x108(%rax),%rax * 2a: 8b a8 24 0a 00 00 mov 0xa24(%rax),%ebp <-- trapping instruction 30: 89 df mov %ebx,%edi 32: 89 ee mov %ebp,%esi 34: e8 f0 34 a9 fe call 0xfea93529 39: 39 eb cmp %ebp,%ebx 3b: 75 20 jne 0x5d 3d: e8 .byte 0xe8 3e: 67 addr32 3f: 33 .byte 0x33
---8<---
Quoted 11 lines · Jakub Kicinski
Quoted 6 lines · On Wed, 11 Jun 2025 17:30:15 +0200 Petr Machata wrote:
Could it actually have been caused by another test? The howto page mentions that the CI is running the tests one at a time, so I don't suppose that's a possibility.
I'll try to run a more fuller suite tomorrow and star at the code a bit to see if I might be missing an error branch or something.
We also hit a crash in ipv6
fcnal.sh, too. Looks like this is either a kmemleak false positive or possibly related to the rtnl changes in ipv6. Either way I it's not related to you changes, sorry about that! :(
No problem.
Quoted 35 lines
[ 2900.792890] BUG: kernel NULL pointer dereference, address: 0000000000000108 [ 2900.792961] #PF: supervisor read access in kernel mode [ 2900.793017] #PF: error_code(0x0000) - not-present page [ 2900.793053] PGD 8fd6067 P4D 8fd6067 PUD 6402067 PMD 0 [ 2900.793097] Oops: Oops: 0000 [#1] SMP NOPTI [ 2900.793127] CPU: 0 UID: 0 PID: 15652 Comm: nettest Not tainted 6.15.0-virtme #1 PREEMPT(voluntary) [ 2900.793200] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 2900.793245] RIP: 0010:ip6_pol_route+0x286/0x4a0 [ 2900.793290] Code: 0c 24 0f 85 fb 01 00 00 09 ca 0f 88 2f 01 00 00 e8 cf 11 43 ff 83 cb 08 48 8d 7c 24 18 e8 32 7b ff ff 0f b7 cb ba ff ff ff ff <4c> 8b 80 08 01 00 00 48 89 c6 49 89 c7 49 8d b8 80 06 00 00 4c 89 [ 2900.793422] RSP: 0018:ffffc08a0932f480 EFLAGS: 00010246 [ 2900.793460] RAX: 0000000000000000 RBX: 0000000000000008 RCX: 0000000000000008 [ 2900.793521] RDX: 00000000ffffffff RSI: ffffc08a0932f740 RDI: ffff9adac8c8f1a8 [ 2900.793580] RBP: ffff9adac87458c0 R08: 0000000000000000 R09: 0000000000000000 [ 2900.793635] R10: 0000000000000000 R11: 0000000000000040 R12: ffff9adac82e362c [ 2900.793692] R13: ffff9adac82e3600 R14: 0000000000000080 R15: 0000000000000000 [ 2900.793752] FS: 00007f3418913740(0000) GS:ffff9adb7373a000(0000) knlGS:0000000000000000 [ 2900.793816] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2900.793864] CR2: 0000000000000108 CR3: 0000000008007004 CR4: 0000000000772ef0 [ 2900.793920] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 2900.793977] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 2900.794031] PKRU: 55555554 [ 2900.794050] Call Trace: [ 2900.794070] <TASK> [ 2900.794090] ? __pfx_ip6_pol_route_output+0x10/0x10 [ 2900.794131] fib6_rule_action+0xe3/0x310 [ 2900.794166] fib_rules_lookup+0x1b2/0x2b0 [ 2900.794200] ? __pfx_ip6_pol_route_output+0x10/0x10 [ 2900.794241] fib6_rule_lookup+0xa9/0x270 [ 2900.794271] ? __pfx_ip6_pol_route_output+0x10/0x10 [ 2900.794310] ip6_route_output_flags+0xab/0x180 [ 2900.794353] ip6_dst_lookup_tail.constprop.0+0x282/0x340 [ 2900.794394] ip6_dst_lookup_flow+0x46/0xc0 [ 2900.794422] vrf_xmit+0x100/0x4a0 [ 2900.794459] dev_hard_start_xmit+0x8d/0x1c0
Didn't see this issue either FWIW.