summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGergely Risko <gergely.risko@gmail.com>2023-01-19 14:40:41 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-02-01 08:27:25 +0100
commit7807871f28f867132d3f97babc4bfb00a32a9d57 (patch)
tree5a279691ee48004a5d1b9b607087df5b78919b9c
parentf9a22f6fa18712f28de6b47d6a116c371f629ca1 (diff)
downloadlinux-stable-7807871f28f867132d3f97babc4bfb00a32a9d57.tar.gz
linux-stable-7807871f28f867132d3f97babc4bfb00a32a9d57.tar.bz2
linux-stable-7807871f28f867132d3f97babc4bfb00a32a9d57.zip
ipv6: fix reachability confirmation with proxy_ndp
commit 9f535c870e493841ac7be390610ff2edec755762 upstream. When proxying IPv6 NDP requests, the adverts to the initial multicast solicits are correct and working. On the other hand, when later a reachability confirmation is requested (on unicast), no reply is sent. This causes the neighbor entry expiring on the sending node, which is mostly a non-issue, as a new multicast request is sent. There are routers, where the multicast requests are intentionally delayed, and in these environments the current implementation causes periodic packet loss for the proxied endpoints. The root cause is the erroneous decrease of the hop limit, as this is checked in ndisc.c and no answer is generated when it's 254 instead of the correct 255. Cc: stable@vger.kernel.org Fixes: 46c7655f0b56 ("ipv6: decrease hop limit counter in ip6_forward()") Signed-off-by: Gergely Risko <gergely.risko@gmail.com> Tested-by: Gergely Risko <gergely.risko@gmail.com> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/ipv6/ip6_output.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 675a80dd78ba..383442ded954 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -527,7 +527,20 @@ int ip6_forward(struct sk_buff *skb)
pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) {
int proxied = ip6_forward_proxy_check(skb);
if (proxied > 0) {
- hdr->hop_limit--;
+ /* It's tempting to decrease the hop limit
+ * here by 1, as we do at the end of the
+ * function too.
+ *
+ * But that would be incorrect, as proxying is
+ * not forwarding. The ip6_input function
+ * will handle this packet locally, and it
+ * depends on the hop limit being unchanged.
+ *
+ * One example is the NDP hop limit, that
+ * always has to stay 255, but other would be
+ * similar checks around RA packets, where the
+ * user can even change the desired limit.
+ */
return ip6_input(skb);
} else if (proxied < 0) {
__IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);