From: Mathieu Desnoyers <mathieu.desnoy...@efficios.com> Date: Tue, 11 Aug 2020 15:50:02 -0400
> @@ -465,6 +465,7 @@ static struct rtable *icmp_route_lookup(struct net *net, > int type, int code, > struct icmp_bxm *param) > { > + struct net_device *route_lookup_dev = NULL; > struct rtable *rt, *rt2; > struct flowi4 fl4_dec; > int err; > @@ -479,7 +480,17 @@ static struct rtable *icmp_route_lookup(struct net *net, > fl4->flowi4_proto = IPPROTO_ICMP; > fl4->fl4_icmp_type = type; > fl4->fl4_icmp_code = code; > - fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev); > + /* > + * The device used for looking up which routing table to use is > + * preferably the source whenever it is set, which should ensure > + * the icmp error can be sent to the source host, else fallback > + * on the destination device. > + */ > + if (skb_in->dev) > + route_lookup_dev = skb_in->dev; > + else if (skb_dst(skb_in)) > + route_lookup_dev = skb_dst(skb_in)->dev; > + fl4->flowi4_oif = l3mdev_master_ifindex(route_lookup_dev); The caller of icmp_route_lookup() uses the opposite prioritization of devices for determining the network namespace to use: if (rt->dst.dev) net = dev_net(rt->dst.dev); else if (skb_in->dev) net = dev_net(skb_in->dev); else goto out; Do we have to reverse the ordering there too? And when I read fallback in your commit message description, I imagined that you would have a two tiered lookup scheme. First you would be trying the skb_in->dev for a lookup (to accomodate the VRF case), and if that failed you'd try again with skb_dst()->dev.