[PATCH net v2] net: ipv6: Fix ping to link-local addresses.

Subsystems: networking [general], the rest

STALE3653d

4 messages, 3 authors, 2016-08-15 · open the first message on its own page

[PATCH net v2] net: ipv6: Fix ping to link-local addresses.

From: Lorenzo Colitti <hidden>
Date: 2016-08-12 16:13:47

ping_v6_sendmsg does not set flowi6_oif in response to
sin6_scope_id or sk_bound_dev_if, so it is not possible to use
these APIs to ping an IPv6 address on a different interface.
Instead, it sets flowi6_iif, which is incorrect but harmless.

Stop setting flowi6_iif, and support various ways of setting oif
in the same priority order used by udpv6_sendmsg.

Tested: https://android-review.googlesource.com/#/c/254470/
Signed-off-by: Lorenzo Colitti <redacted>
---
 net/ipv6/ping.c | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index fed40d1..0900352 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -55,7 +55,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	struct icmp6hdr user_icmph;
 	int addr_type;
 	struct in6_addr *daddr;
-	int iif = 0;
+	int oif = 0;
 	struct flowi6 fl6;
 	int err;
 	struct dst_entry *dst;
@@ -78,25 +78,30 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 		if (u->sin6_family != AF_INET6) {
 			return -EAFNOSUPPORT;
 		}
-		if (sk->sk_bound_dev_if &&
-		    sk->sk_bound_dev_if != u->sin6_scope_id) {
-			return -EINVAL;
-		}
 		daddr = &(u->sin6_addr);
-		iif = u->sin6_scope_id;
+		if (__ipv6_addr_needs_scope_id(ipv6_addr_type(daddr)))
+			oif = u->sin6_scope_id;
 	} else {
 		if (sk->sk_state != TCP_ESTABLISHED)
 			return -EDESTADDRREQ;
 		daddr = &sk->sk_v6_daddr;
 	}
 
-	if (!iif)
-		iif = sk->sk_bound_dev_if;
+	if (!oif)
+		oif = sk->sk_bound_dev_if;
+
+	if (!oif)
+		oif = np->sticky_pktinfo.ipi6_ifindex;
+
+	if (!oif && ipv6_addr_is_multicast(daddr))
+		oif = np->mcast_oif;
+	else if (!oif)
+		oif = np->ucast_oif;
 
 	addr_type = ipv6_addr_type(daddr);
-	if (__ipv6_addr_needs_scope_id(addr_type) && !iif)
-		return -EINVAL;
-	if (addr_type & IPV6_ADDR_MAPPED)
+	if ((__ipv6_addr_needs_scope_id(addr_type) && !oif) ||
+	    (addr_type & IPV6_ADDR_MAPPED) ||
+	    (oif && sk->sk_bound_dev_if && oif != sk->sk_bound_dev_if))
 		return -EINVAL;
 
 	/* TODO: use ip6_datagram_send_ctl to get options from cmsg */
@@ -106,16 +111,12 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 	fl6.flowi6_proto = IPPROTO_ICMPV6;
 	fl6.saddr = np->saddr;
 	fl6.daddr = *daddr;
+	fl6.flowi6_oif = oif;
 	fl6.flowi6_mark = sk->sk_mark;
 	fl6.fl6_icmp_type = user_icmph.icmp6_type;
 	fl6.fl6_icmp_code = user_icmph.icmp6_code;
 	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
-	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
-		fl6.flowi6_oif = np->mcast_oif;
-	else if (!fl6.flowi6_oif)
-		fl6.flowi6_oif = np->ucast_oif;
-
 	ipc6.tclass = np->tclass;
 	fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
 
-- 
2.8.0.rc3.226.g39d4020

Re: [PATCH net v2] net: ipv6: Fix ping to link-local addresses.

From: David Miller <davem@davemloft.net>
Date: 2016-08-15 17:55:23

From: Lorenzo Colitti <redacted>
Date: Sat, 13 Aug 2016 01:13:38 +0900
ping_v6_sendmsg does not set flowi6_oif in response to
sin6_scope_id or sk_bound_dev_if, so it is not possible to use
these APIs to ping an IPv6 address on a different interface.
Instead, it sets flowi6_iif, which is incorrect but harmless.

Stop setting flowi6_iif, and support various ways of setting oif
in the same priority order used by udpv6_sendmsg.

Tested: https://android-review.googlesource.com/#/c/254470/
Signed-off-by: Lorenzo Colitti <redacted>
I'm expecting a new version of this patch with changes handling
the situation that VRF needs.

Just FYI...

Re: [PATCH net v2] net: ipv6: Fix ping to link-local addresses.

From: David Ahern <hidden>
Date: 2016-08-15 18:44:30

On 8/15/16 11:55 AM, David Miller wrote:
From: Lorenzo Colitti <redacted>
Date: Sat, 13 Aug 2016 01:13:38 +0900
quoted
ping_v6_sendmsg does not set flowi6_oif in response to
sin6_scope_id or sk_bound_dev_if, so it is not possible to use
these APIs to ping an IPv6 address on a different interface.
Instead, it sets flowi6_iif, which is incorrect but harmless.

Stop setting flowi6_iif, and support various ways of setting oif
in the same priority order used by udpv6_sendmsg.

Tested: https://android-review.googlesource.com/#/c/254470/
Signed-off-by: Lorenzo Colitti <redacted>
I'm expecting a new version of this patch with changes handling
the situation that VRF needs.
The vrf situation does not apply here - at least not yet. Maybe I am missing something but ping_v6_sendmsg does not support IPV6_PKTINFO, so the potential oif override of sk_bound_dev_if is not there.

I'll add this to the to-do list -- make IPv6 compatible with IPv4 wrt PKTINFO and then add in the VRF fix up discussed. 

Re: [PATCH net v2] net: ipv6: Fix ping to link-local addresses.

From: David Miller <davem@davemloft.net>
Date: 2016-08-15 19:19:32

From: David Ahern <redacted>
Date: Mon, 15 Aug 2016 12:44:27 -0600
On 8/15/16 11:55 AM, David Miller wrote:
quoted
From: Lorenzo Colitti <redacted>
Date: Sat, 13 Aug 2016 01:13:38 +0900
quoted
ping_v6_sendmsg does not set flowi6_oif in response to
sin6_scope_id or sk_bound_dev_if, so it is not possible to use
these APIs to ping an IPv6 address on a different interface.
Instead, it sets flowi6_iif, which is incorrect but harmless.

Stop setting flowi6_iif, and support various ways of setting oif
in the same priority order used by udpv6_sendmsg.

Tested: https://android-review.googlesource.com/#/c/254470/
Signed-off-by: Lorenzo Colitti <redacted>
I'm expecting a new version of this patch with changes handling
the situation that VRF needs.
The vrf situation does not apply here - at least not yet. Maybe I am
missing something but ping_v6_sendmsg does not support IPV6_PKTINFO,
so the potential oif override of sk_bound_dev_if is not there.

I'll add this to the to-do list -- make IPv6 compatible with IPv4
wrt PKTINFO and then add in the VRF fix up discussed.
Ok, thanks for explaining.

Patch applied, t hanks.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help