Ido reported that the commit referenced in the Fixes tag broke a gre use case with dummy devices. Add a check to ip_tunnel_init_flow to see if the oif is an l3mdev port and if so set the oif to 0 to avoid the oif comparison in fib_lookup_good_nhc.
Unified · Split
| @@ -423,7 +423,7 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev, · 422 unmodified lines | |||
| 423 | 423 | ||
| 424 | parms = mlxsw_sp_ipip_netdev_parms4(to_dev); | 424 | parms = mlxsw_sp_ipip_netdev_parms4(to_dev); |
| 425 | ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, | 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 | rt = ip_route_output_key(tun->net, &fl4); | 428 | rt = ip_route_output_key(tun->net, &fl4); |
| 429 | if (IS_ERR(rt)) | 429 | if (IS_ERR(rt)) |
| @@ -243,11 +243,18 @@ static inline __be32 tunnel_id_to_key32(__be64 tun_id) · 242 unmodified lines | |||
| 243 | static inline void ip_tunnel_init_flow(struct flowi4 *fl4, | 243 | static inline void ip_tunnel_init_flow(struct flowi4 *fl4, |
| 244 | int proto, | 244 | int proto, |
| 245 | __be32 daddr, __be32 saddr, | 245 | __be32 daddr, __be32 saddr, |
| 246 | __be32 key, __u8 tos, int oif, | 246 | __be32 key, __u8 tos, |
| 247 | struct net *net, int oif, | ||
| 247 | __u32 mark, __u32 tun_inner_hash) | 248 | __u32 mark, __u32 tun_inner_hash) |
| 248 | { | 249 | { |
| 249 | memset(fl4, 0, sizeof(*fl4)); | 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 | fl4->daddr = daddr; | 258 | fl4->daddr = daddr; |
| 252 | fl4->saddr = saddr; | 259 | fl4->saddr = saddr; |
| 253 | fl4->flowi4_tos = tos; | 260 | fl4->flowi4_tos = tos; |
| @@ -605,8 +605,8 @@ static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) · 604 unmodified lines | |||
| 605 | key = &info->key; | 605 | key = &info->key; |
| 606 | ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, | 606 | ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, |
| 607 | tunnel_id_to_key32(key->tun_id), | 607 | tunnel_id_to_key32(key->tun_id), |
| 608 | key->tos & ~INET_ECN_MASK, 0, skb->mark, | 608 | key->tos & ~INET_ECN_MASK, dev_net(dev), 0, |
| 609 | skb_get_hash(skb)); | 609 | skb->mark, skb_get_hash(skb)); |
| 610 | rt = ip_route_output_key(dev_net(dev), &fl4); | 610 | rt = ip_route_output_key(dev_net(dev), &fl4); |
| 611 | if (IS_ERR(rt)) | 611 | if (IS_ERR(rt)) |
| 612 | return PTR_ERR(rt); | 612 | return PTR_ERR(rt); |
| @@ -294,8 +294,8 @@ static int ip_tunnel_bind_dev(struct net_device *dev) · 293 unmodified lines | |||
| 294 | 294 | ||
| 295 | ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, | 295 | ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, |
| 296 | iph->saddr, tunnel->parms.o_key, | 296 | iph->saddr, tunnel->parms.o_key, |
| 297 | RT_TOS(iph->tos), tunnel->parms.link, | 297 | RT_TOS(iph->tos), dev_net(dev), |
| 298 | tunnel->fwmark, 0); | 298 | tunnel->parms.link, tunnel->fwmark, 0); |
| 299 | rt = ip_route_output_key(tunnel->net, &fl4); | 299 | rt = ip_route_output_key(tunnel->net, &fl4); |
| 300 | 300 | ||
| 301 | if (!IS_ERR(rt)) { | 301 | if (!IS_ERR(rt)) { |
| @@ -570,7 +570,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, · 268 unmodified lines | |||
| 570 | } | 570 | } |
| 571 | ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, | 571 | ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, |
| 572 | tunnel_id_to_key32(key->tun_id), RT_TOS(tos), | 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 | if (tunnel->encap.type != TUNNEL_ENCAP_NONE) | 574 | if (tunnel->encap.type != TUNNEL_ENCAP_NONE) |
| 575 | goto tx_error; | 575 | goto tx_error; |
| 576 | 576 | ||
| @@ -726,7 +726,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, · 149 unmodified lines | |||
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, | 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 | tunnel->fwmark, skb_get_hash(skb)); | 731 | tunnel->fwmark, skb_get_hash(skb)); |
| 731 | 732 | ||
| 732 | if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) | 733 | if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) |