Hello, On Thu, 7 Apr 2016, Chris Friesen wrote:
> Hi, > > We think we may have found a bug in the handling of ipv4 route caching, > and are curious what you think. > > For local routes that require a particular output interface we do not > want to cache the result. Caching the result causes incorrect behaviour > when there are multiple source addresses on the interface. The end > result being that if the intended recipient is waiting on that interface > for the packet he won't receive it because it will be delivered on the > loopback interface and the IP_PKTINFO ipi_ifindex will be set to the > loopback interface as well. So, if we store some orig_oif in rt_iif that is specific (cached in nexthop) to some device, this orig_oif should match the device. The only case when this is violated is when we redirect traffic to lo. Any attempts to store eth1 in rt_iif for nexthop cache for lo should be avoided. > This can be tested by running a program such as "dhcp_release" which > attempts to inject a packet on a particular interface so that it is > received by another program on the same board. The receiving process > should see an IP_PKTINFO ipi_ifndex value of the source interface > (e.g., eth1) instead of the loopback interface (e.g., lo). The packet > will still appear on the loopback interface in tcpdump but the important > aspect is that the CMSG info is correct. > > For what it's worth, here's a patch that we've applied locally to deal > with the issue. > > Chris > > > > Signed-off-by: Allain Legacy <allain.leg...@windriver.com> > Signed-off-by: Chris Friesen <chris.frie...@windriver.com> > > diff --git a/net/ipv4/route.c b/net/ipv4/route.c > index 02c6229..e965d4b 100644 > --- a/net/ipv4/route.c > +++ b/net/ipv4/route.c > @@ -2045,6 +2045,17 @@ static struct rtable *__mkroute_output(const struct > fib_result *res, > */ > if (fi && res->prefixlen < 4) > fi = NULL; > + } else if ((type == RTN_LOCAL) && (orig_oif != 0)) { So, we can be more specific. Can this work?: } else if ((type == RTN_LOCAL) && (orig_oif != 0) && (orig_oif != dev_out->ifindex)) { I.e. we should allow to cache orig_oif=LOOPBACK_IFINDEX but eth1 should not be cached. > + /* For local routes that require a particular output interface > + * we do not want to cache the result. Caching the result > + * causes incorrect behaviour when there are multiple source > + * addresses on the interface, the end result being that if > the > + * intended recipient is waiting on that interface for the > + * packet he won't receive it because it will be delivered on > + * the loopback interface and the IP_PKTINFO ipi_ifindex will > + * be set to the loopback interface as well. > + */ > + fi = NULL; > } > > fnhe = NULL; Regards -- Julian Anastasov <j...@ssi.bg>