History

net: Handle l3mdev in ip_tunnel_init_flow

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.

David Ahern committed 4 years ago

Commit db53cd31 parent 83daab04 files · +17 −9Browse files

Unified · Split

4 files
  1. drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +1 −1
  2. include/net/ip_tunnels.h +9 −2
  3. net/ipv4/ip_gre.c +2 −2
  4. net/ipv4/ip_tunnel.c +5 −4
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c+1−1
@@ -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))
include/net/ip_tunnels.h+9−2
@@ -243,11 +243,18 @@ static inline __be32 tunnel_id_to_key32(__be64 tun_id) · 242 unmodified lines
243static inline void ip_tunnel_init_flow(struct flowi4 *fl4,243static 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;
net/ipv4/ip_gre.c+2−2
@@ -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);
net/ipv4/ip_tunnel.c+5−4
@@ -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)