| From: Chris Friesen <chris.friesen@windriver.com> |
| Date: Fri, 8 Apr 2016 15:21:30 -0600 |
| Subject: route: do not cache fib route info on local routes with oif |
| |
| [ Upstream commit d6d5e999e5df67f8ec20b6be45e2229455ee3699 ] |
| |
| 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. |
| |
| 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. |
| |
| Sample dhcp_release command line: |
| |
| dhcp_release eth1 192.168.204.222 02:11:33:22:44:66 |
| |
| Signed-off-by: Allain Legacy <allain.legacy@windriver.com> |
| Signed off-by: Chris Friesen <chris.friesen@windriver.com> |
| Reviewed-by: Julian Anastasov <ja@ssi.bg> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/ipv4/route.c | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| --- a/net/ipv4/route.c |
| +++ b/net/ipv4/route.c |
| @@ -2604,6 +2604,18 @@ static struct rtable *__mkroute_output(c |
| */ |
| if (fi && res->prefixlen < 4) |
| fi = NULL; |
| + } else if ((type == RTN_LOCAL) && (orig_oif != 0) && |
| + (orig_oif != dev_out->ifindex)) { |
| + /* 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; |
| } |
| |
| rth = rt_dst_alloc(dev_out, |