Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'l3mdev-fix-ip-tunnel-case-after-recent-l3mdev-change'

David Ahern says:

====================
l3mdev: Fix ip tunnel case after recent l3mdev change

Second patch provides a fix for ip tunnels after the recent l3mdev change
that avoids touching the oif in the flow struct. First patch preemptively
provides a fix to an existing function that the second patch uses.
====================

Link: https://lore.kernel.org/r/20220413174320.28989-1-dsahern@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+18 -10
+1 -1
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
··· 423 423 424 424 parms = mlxsw_sp_ipip_netdev_parms4(to_dev); 425 425 ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, 426 - 0, 0, parms.link, tun->fwmark, 0); 426 + 0, 0, dev_net(to_dev), parms.link, tun->fwmark, 0); 427 427 428 428 rt = ip_route_output_key(tun->net, &fl4); 429 429 if (IS_ERR(rt))
+9 -2
include/net/ip_tunnels.h
··· 243 243 static inline void ip_tunnel_init_flow(struct flowi4 *fl4, 244 244 int proto, 245 245 __be32 daddr, __be32 saddr, 246 - __be32 key, __u8 tos, int oif, 246 + __be32 key, __u8 tos, 247 + struct net *net, int oif, 247 248 __u32 mark, __u32 tun_inner_hash) 248 249 { 249 250 memset(fl4, 0, sizeof(*fl4)); 250 - fl4->flowi4_oif = oif; 251 + 252 + if (oif) { 253 + fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index_rcu(net, oif); 254 + /* Legacy VRF/l3mdev use case */ 255 + fl4->flowi4_oif = fl4->flowi4_l3mdev ? 0 : oif; 256 + } 257 + 251 258 fl4->daddr = daddr; 252 259 fl4->saddr = saddr; 253 260 fl4->flowi4_tos = tos;
+2 -2
net/ipv4/ip_gre.c
··· 605 605 key = &info->key; 606 606 ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, 607 607 tunnel_id_to_key32(key->tun_id), 608 - key->tos & ~INET_ECN_MASK, 0, skb->mark, 609 - skb_get_hash(skb)); 608 + key->tos & ~INET_ECN_MASK, dev_net(dev), 0, 609 + skb->mark, skb_get_hash(skb)); 610 610 rt = ip_route_output_key(dev_net(dev), &fl4); 611 611 if (IS_ERR(rt)) 612 612 return PTR_ERR(rt);
+5 -4
net/ipv4/ip_tunnel.c
··· 294 294 295 295 ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, 296 296 iph->saddr, tunnel->parms.o_key, 297 - RT_TOS(iph->tos), tunnel->parms.link, 298 - tunnel->fwmark, 0); 297 + RT_TOS(iph->tos), dev_net(dev), 298 + tunnel->parms.link, tunnel->fwmark, 0); 299 299 rt = ip_route_output_key(tunnel->net, &fl4); 300 300 301 301 if (!IS_ERR(rt)) { ··· 570 570 } 571 571 ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, 572 572 tunnel_id_to_key32(key->tun_id), RT_TOS(tos), 573 - 0, skb->mark, skb_get_hash(skb)); 573 + dev_net(dev), 0, skb->mark, skb_get_hash(skb)); 574 574 if (tunnel->encap.type != TUNNEL_ENCAP_NONE) 575 575 goto tx_error; 576 576 ··· 726 726 } 727 727 728 728 ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, 729 - tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link, 729 + tunnel->parms.o_key, RT_TOS(tos), 730 + dev_net(dev), tunnel->parms.link, 730 731 tunnel->fwmark, skb_get_hash(skb)); 731 732 732 733 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
+1 -1
net/l3mdev/l3mdev.c
··· 147 147 148 148 dev = dev_get_by_index_rcu(net, ifindex); 149 149 while (dev && !netif_is_l3_master(dev)) 150 - dev = netdev_master_upper_dev_get(dev); 150 + dev = netdev_master_upper_dev_get_rcu(dev); 151 151 152 152 return dev ? dev->ifindex : 0; 153 153 }