Message ID | 938b711c35ce3fa2b6f057cc23919e897a1e5c2b.1568061608.git.sbrivio@redhat.com |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | [net-next] ipv6: Don't use dst gateway directly in ip6_confirm_neigh() | expand |
On Mon, Sep 09, 2019 at 10:44:06PM +0200, Stefano Brivio wrote: > This is the equivalent of commit 2c6b55f45d53 ("ipv6: fix neighbour > resolution with raw socket") for ip6_confirm_neigh(): we can send a > packet with MSG_CONFIRM on a raw socket for a connected route, so the > gateway would be :: here, and we should pick the next hop using > rt6_nexthop() instead. > > This was found by code review and, to the best of my knowledge, doesn't > actually fix a practical issue: the destination address from the packet > is not considered while confirming a neighbour, as ip6_confirm_neigh() > calls choose_neigh_daddr() without passing the packet, so there are no > similar issues as the one fixed by said commit. > > A possible source of issues with the existing implementation might come > from the fact that, if we have a cached dst, we won't consider it, > while rt6_nexthop() takes care of that. I might just not be creative > enough to find a practical problem here: the only way to affect this > with cached routes is to have one coming from an ICMPv6 redirect, but > if the next hop is a directly connected host, there should be no > topology for which a redirect applies here, and tests with redirected > routes show no differences for MSG_CONFIRM (and MSG_PROBE) packets on > raw sockets destined to a directly connected host. > > However, directly using the dst gateway here is not consistent anymore > with neighbour resolution, and, in general, as we want the next hop, > using rt6_nexthop() looks like the only sane way to fetch it. > > Reported-by: Guillaume Nault <gnault@redhat.com> > Signed-off-by: Stefano Brivio <sbrivio@redhat.com> > --- > net/ipv6/route.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index 7a5d331cdefa..874641d4d2a1 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -227,7 +227,7 @@ static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr) > struct net_device *dev = dst->dev; > struct rt6_info *rt = (struct rt6_info *)dst; > > - daddr = choose_neigh_daddr(&rt->rt6i_gateway, NULL, daddr); > + daddr = choose_neigh_daddr(rt6_nexthop(rt, &in6addr_any), NULL, daddr); > if (!daddr) > return; > if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) > Acked-by: Guillaume Nault <gnault@redhat.com>
Le 09/09/2019 à 22:44, Stefano Brivio a écrit : > This is the equivalent of commit 2c6b55f45d53 ("ipv6: fix neighbour > resolution with raw socket") for ip6_confirm_neigh(): we can send a > packet with MSG_CONFIRM on a raw socket for a connected route, so the > gateway would be :: here, and we should pick the next hop using > rt6_nexthop() instead. > > This was found by code review and, to the best of my knowledge, doesn't > actually fix a practical issue: the destination address from the packet > is not considered while confirming a neighbour, as ip6_confirm_neigh() > calls choose_neigh_daddr() without passing the packet, so there are no > similar issues as the one fixed by said commit. > > A possible source of issues with the existing implementation might come > from the fact that, if we have a cached dst, we won't consider it, > while rt6_nexthop() takes care of that. I might just not be creative > enough to find a practical problem here: the only way to affect this > with cached routes is to have one coming from an ICMPv6 redirect, but > if the next hop is a directly connected host, there should be no > topology for which a redirect applies here, and tests with redirected > routes show no differences for MSG_CONFIRM (and MSG_PROBE) packets on > raw sockets destined to a directly connected host. > > However, directly using the dst gateway here is not consistent anymore > with neighbour resolution, and, in general, as we want the next hop, > using rt6_nexthop() looks like the only sane way to fetch it. > > Reported-by: Guillaume Nault <gnault@redhat.com> > Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
From: Stefano Brivio <sbrivio@redhat.com> Date: Mon, 9 Sep 2019 22:44:06 +0200 > This is the equivalent of commit 2c6b55f45d53 ("ipv6: fix neighbour > resolution with raw socket") for ip6_confirm_neigh(): we can send a > packet with MSG_CONFIRM on a raw socket for a connected route, so the > gateway would be :: here, and we should pick the next hop using > rt6_nexthop() instead. > > This was found by code review and, to the best of my knowledge, doesn't > actually fix a practical issue: the destination address from the packet > is not considered while confirming a neighbour, as ip6_confirm_neigh() > calls choose_neigh_daddr() without passing the packet, so there are no > similar issues as the one fixed by said commit. > > A possible source of issues with the existing implementation might come > from the fact that, if we have a cached dst, we won't consider it, > while rt6_nexthop() takes care of that. I might just not be creative > enough to find a practical problem here: the only way to affect this > with cached routes is to have one coming from an ICMPv6 redirect, but > if the next hop is a directly connected host, there should be no > topology for which a redirect applies here, and tests with redirected > routes show no differences for MSG_CONFIRM (and MSG_PROBE) packets on > raw sockets destined to a directly connected host. > > However, directly using the dst gateway here is not consistent anymore > with neighbour resolution, and, in general, as we want the next hop, > using rt6_nexthop() looks like the only sane way to fetch it. > > Reported-by: Guillaume Nault <gnault@redhat.com> > Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Applied.
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7a5d331cdefa..874641d4d2a1 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -227,7 +227,7 @@ static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr) struct net_device *dev = dst->dev; struct rt6_info *rt = (struct rt6_info *)dst; - daddr = choose_neigh_daddr(&rt->rt6i_gateway, NULL, daddr); + daddr = choose_neigh_daddr(rt6_nexthop(rt, &in6addr_any), NULL, daddr); if (!daddr) return; if (dev->flags & (IFF_NOARP | IFF_LOOPBACK))
This is the equivalent of commit 2c6b55f45d53 ("ipv6: fix neighbour resolution with raw socket") for ip6_confirm_neigh(): we can send a packet with MSG_CONFIRM on a raw socket for a connected route, so the gateway would be :: here, and we should pick the next hop using rt6_nexthop() instead. This was found by code review and, to the best of my knowledge, doesn't actually fix a practical issue: the destination address from the packet is not considered while confirming a neighbour, as ip6_confirm_neigh() calls choose_neigh_daddr() without passing the packet, so there are no similar issues as the one fixed by said commit. A possible source of issues with the existing implementation might come from the fact that, if we have a cached dst, we won't consider it, while rt6_nexthop() takes care of that. I might just not be creative enough to find a practical problem here: the only way to affect this with cached routes is to have one coming from an ICMPv6 redirect, but if the next hop is a directly connected host, there should be no topology for which a redirect applies here, and tests with redirected routes show no differences for MSG_CONFIRM (and MSG_PROBE) packets on raw sockets destined to a directly connected host. However, directly using the dst gateway here is not consistent anymore with neighbour resolution, and, in general, as we want the next hop, using rt6_nexthop() looks like the only sane way to fetch it. Reported-by: Guillaume Nault <gnault@redhat.com> Signed-off-by: Stefano Brivio <sbrivio@redhat.com> --- net/ipv6/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)