| From 4b70d3092ce687fb903a901f6a20ff94b6a29048 Mon Sep 17 00:00:00 2001 |
| From: Wei Zhang <asuka.com@163.com> |
| Date: Thu, 29 Dec 2016 16:45:04 +0800 |
| Subject: [PATCH] net: fix incorrect original ingress device index in PKTINFO |
| |
| commit f0c16ba8933ed217c2688b277410b2a37ba81591 upstream. |
| |
| When we send a packet for our own local address on a non-loopback |
| interface (e.g. eth0), due to the change had been introduced from |
| commit 0b922b7a829c ("net: original ingress device index in PKTINFO"), the |
| original ingress device index would be set as the loopback interface. |
| However, the packet should be considered as if it is being arrived via the |
| sending interface (eth0), otherwise it would break the expectation of the |
| userspace application (e.g. the DHCPRELEASE message from dhcp_release |
| binary would be ignored by the dnsmasq daemon, since it come from lo which |
| is not the interface dnsmasq bind to) |
| |
| Fixes: 0b922b7a829c ("net: original ingress device index in PKTINFO") |
| Acked-by: David Ahern <dsa@cumulusnetworks.com> |
| Signed-off-by: Wei Zhang <asuka.com@163.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c |
| index 4964d1bdb390..193ee7ba3e22 100644 |
| --- a/net/ipv4/ip_sockglue.c |
| +++ b/net/ipv4/ip_sockglue.c |
| @@ -1199,8 +1199,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) |
| * which has interface index (iif) as the first member of the |
| * underlying inet{6}_skb_parm struct. This code then overlays |
| * PKTINFO_SKB_CB and in_pktinfo also has iif as the first |
| - * element so the iif is picked up from the prior IPCB |
| + * element so the iif is picked up from the prior IPCB. If iif |
| + * is the loopback interface, then return the sending interface |
| + * (e.g., process binds socket to eth0 for Tx which is |
| + * redirected to loopback in the rtable/dst). |
| */ |
| + if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX) |
| + pktinfo->ipi_ifindex = inet_iif(skb); |
| + |
| pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb); |
| } else { |
| pktinfo->ipi_ifindex = 0; |
| -- |
| 2.10.1 |
| |