Skip to contentSkip to conversation

netns: Fix duplicate address detection (dad)

PATCH New Dan Rue 3 participants 4 messages Nov 21, 2017 – Nov 22, 2017

lore
Share & tools
lore

Dan Rue

author
#0 lore raw

PATCH 1/1 netns: Fix duplicate address detection (dad)

Symptoms (+ command, error):
netns_comm_ip_ipv6_ioctl:
+ ip netns exec tst_net_ns1 ping6 -q -c2 -I veth1 fd00::2
connect: Cannot assign requested address

netns_comm_ip_ipv6_netlink:
+ ip netns exec tst_net_ns0 ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_ioctl:
+ ns_exec 6689 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_netlin:
+ ns_exec 6891 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

The error is coming from ping6, which is trying to get an IP address for veth0 (due to -I veth0), but cannot, because the interface is not immediately available due to dad. The existing code to disable dad is disables it for the virtual interfaces, but it needs to be disabled for all interfaces in the network namespace to be effective.

Also, changed it to use sysctl -w because I think it is a little cleaner to read and understand.

Lastly, dropped setting accept_ra. It does not seem to be necessary to disable.

---
 testcases/kernel/containers/netns/netns_helper.sh | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
testcases/kernel/containers/netns/netns_helper.sh +4 -6
index a95cdf206..95add0544 100755
@@ -256,12 +256,10 @@ netns_set_ip()
 	# there is no other host with the same address, the address is
 	# considered to be "tentative" (attempts to bind() to the address fail
 	# with EADDRNOTAVAIL) which may cause problems for tests using ipv6.
-	echo 0 | $NS_EXEC $NS_HANDLE0 $NS_TYPE \
-		tee /proc/sys/net/ipv6/conf/veth0/accept_dad \
-		/proc/sys/net/ipv6/conf/veth0/accept_ra >/dev/null
-	echo 0 | $NS_EXEC $NS_HANDLE1 $NS_TYPE \
-		tee /proc/sys/net/ipv6/conf/veth1/accept_dad \
-		/proc/sys/net/ipv6/conf/veth1/accept_ra >/dev/null
+	$NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+	$NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.veth0.accept_dad=0
+	$NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+	$NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.veth1.accept_dad=0
 
 	case $USE_IFCONFIG in
 	1)
Signature · 1 line
2.14.3
#1 lore raw

PATCH 1/1 netns: Fix duplicate address detection (dad)

Quoted 40 lines · Dan Rue

Symptoms (+ command, error):
netns_comm_ip_ipv6_ioctl:
+ ip netns exec tst_net_ns1 ping6 -q -c2 -I veth1 fd00::2
connect: Cannot assign requested address

netns_comm_ip_ipv6_netlink:
+ ip netns exec tst_net_ns0 ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_ioctl:
+ ns_exec 6689 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_netlin:
+ ns_exec 6891 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

The error is coming from ping6, which is trying to get an IP address for veth0 (due to -I veth0), but cannot, because the interface is not immediately available due to dad. The existing code to disable dad is disables it for the virtual interfaces, but it needs to be disabled for all interfaces in the network namespace to be effective.

Also, changed it to use sysctl -w because I think it is a little cleaner to read and understand.

Lastly, dropped setting accept_ra. It does not seem to be necessary to disable.

---
 testcases/kernel/containers/netns/netns_helper.sh | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
testcases/kernel/containers/netns/netns_helper.sh +0 -0
index a95cdf206..95add0544 100755
@@ -256,12 +256,10 @@ netns_set_ip()
        # there is no other host with the same address, the address is

testcases/kernel/containers/netns/netns_helper.sh netns_set_ip() · line 260

Quoted 10 lines
testcases/kernel/containers/netns/netns_helper.sh +2 -6
        # considered to be "tentative" (attempts to bind() to the address fail
        # with EADDRNOTAVAIL) which may cause problems for tests using ipv6.
-       echo 0 | $NS_EXEC $NS_HANDLE0 $NS_TYPE \
-               tee /proc/sys/net/ipv6/conf/veth0/accept_dad \
-               /proc/sys/net/ipv6/conf/veth0/accept_ra >/dev/null
-       echo 0 | $NS_EXEC $NS_HANDLE1 $NS_TYPE \
-               tee /proc/sys/net/ipv6/conf/veth1/accept_dad \
-               /proc/sys/net/ipv6/conf/veth1/accept_ra >/dev/null
+       $NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+       $NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.veth0.accept_dad=0

Seems we have already disabled DAD for all interfaces via 'net.ipv6.conf.all.accept_dad=0', I wonder if it's necessary to do the repeat setting for veth0 device?

testcases/kernel/containers/netns/netns_helper.sh netns_set_ip() · line 262

Quoted 2 lines
testcases/kernel/containers/netns/netns_helper.sh +2 -0
+       $NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+       $NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.veth1.accept_dad=0

Here as well.

Quoted 5 lines
testcases/kernel/containers/netns/netns_helper.sh +0 -1
        case $USE_IFCONFIG in
        1)
--

2.14.3

Anyway, this method works to me.

Signature · 2 lines
Li Wang
[email protected]
#2 lore raw

PATCH 1/1 netns: Fix duplicate address detection (dad)

In reply to Dan Rue
Quoted 17 lines · Dan Rue

Symptoms (+ command, error):
netns_comm_ip_ipv6_ioctl:
+ ip netns exec tst_net_ns1 ping6 -q -c2 -I veth1 fd00::2
connect: Cannot assign requested address

netns_comm_ip_ipv6_netlink:
+ ip netns exec tst_net_ns0 ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_ioctl:
+ ns_exec 6689 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_netlin:
+ ns_exec 6891 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

Quoted 5 lines

The error is coming from ping6, which is trying to get an IP address for veth0 (due to -I veth0), but cannot, because the interface is not immediately available due to dad. The existing code to disable dad is disables it for the virtual interfaces, but it needs to be disabled for all interfaces in the network namespace to be effective.

Looks like Linux 4.14 specific and it's fixed with the following patch:
094009531612 ("ipv6: set all.accept_dad to 0 by default")

I'm not sure if we need to change the test-case if we want to catch similar bug with backward compatibility...

Thanks,
Alexey

Quoted 29 lines

Also, changed it to use sysctl -w because I think it is a little cleaner to read and understand.

Lastly, dropped setting accept_ra. It does not seem to be necessary to disable.

---
 testcases/kernel/containers/netns/netns_helper.sh | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
testcases/kernel/containers/netns/netns_helper.sh +4 -6
index a95cdf206..95add0544 100755
@@ -256,12 +256,10 @@ netns_set_ip()
 	# there is no other host with the same address, the address is
 	# considered to be "tentative" (attempts to bind() to the address fail
 	# with EADDRNOTAVAIL) which may cause problems for tests using ipv6.
-	echo 0 | $NS_EXEC $NS_HANDLE0 $NS_TYPE \
-		tee /proc/sys/net/ipv6/conf/veth0/accept_dad \
-		/proc/sys/net/ipv6/conf/veth0/accept_ra >/dev/null
-	echo 0 | $NS_EXEC $NS_HANDLE1 $NS_TYPE \
-		tee /proc/sys/net/ipv6/conf/veth1/accept_dad \
-		/proc/sys/net/ipv6/conf/veth1/accept_ra >/dev/null
+	$NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+	$NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.veth0.accept_dad=0
+	$NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+	$NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.veth1.accept_dad=0
author
#3 lore raw

PATCH 1/1 netns: Fix duplicate address detection (dad)

Quoted 25 lines · Alexey Kodanev
Quoted 17 lines · Dan Rue

Symptoms (+ command, error):
netns_comm_ip_ipv6_ioctl:
+ ip netns exec tst_net_ns1 ping6 -q -c2 -I veth1 fd00::2
connect: Cannot assign requested address

netns_comm_ip_ipv6_netlink:
+ ip netns exec tst_net_ns0 ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_ioctl:
+ ns_exec 6689 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

netns_comm_ns_exec_ipv6_netlin:
+ ns_exec 6891 net ping6 -q -c2 -I veth0 fd00::3
connect: Cannot assign requested address

Quoted 5 lines

The error is coming from ping6, which is trying to get an IP address for veth0 (due to -I veth0), but cannot, because the interface is not immediately available due to dad. The existing code to disable dad is disables it for the virtual interfaces, but it needs to be disabled for all interfaces in the network namespace to be effective.

Quoted 5 lines

Looks like Linux 4.14 specific and it's fixed with the following patch:
094009531612 ("ipv6: set all.accept_dad to 0 by default")

I'm not sure if we need to change the test-case if we want to catch similar bug with backward compatibility...

Good find! I'm happy withdrawing this patch.

Quoted 33 lines

Thanks,
Alexey

Quoted 29 lines

Also, changed it to use sysctl -w because I think it is a little cleaner to read and understand.

Lastly, dropped setting accept_ra. It does not seem to be necessary to disable.

---
 testcases/kernel/containers/netns/netns_helper.sh | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
testcases/kernel/containers/netns/netns_helper.sh +4 -6
index a95cdf206..95add0544 100755
@@ -256,12 +256,10 @@ netns_set_ip()
 	# there is no other host with the same address, the address is
 	# considered to be "tentative" (attempts to bind() to the address fail
 	# with EADDRNOTAVAIL) which may cause problems for tests using ipv6.
-	echo 0 | $NS_EXEC $NS_HANDLE0 $NS_TYPE \
-		tee /proc/sys/net/ipv6/conf/veth0/accept_dad \
-		/proc/sys/net/ipv6/conf/veth0/accept_ra >/dev/null
-	echo 0 | $NS_EXEC $NS_HANDLE1 $NS_TYPE \
-		tee /proc/sys/net/ipv6/conf/veth1/accept_dad \
-		/proc/sys/net/ipv6/conf/veth1/accept_ra >/dev/null
+	$NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+	$NS_EXEC $NS_HANDLE0 $NS_TYPE sysctl -w net.ipv6.conf.veth0.accept_dad=0
+	$NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.all.accept_dad=0
+	$NS_EXEC $NS_HANDLE1 $NS_TYPE sysctl -w net.ipv6.conf.veth1.accept_dad=0