diff mbox series

[PATCHv2,net,2/2] kselftest: add a selftest for ipv6 dad and rs sending

Message ID 83eec0770eee543174b90ba4e08d371a72565f0c.1673483994.git.lucien.xin@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: fix nsna_ping not working in team | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 2 maintainers not CCed: linux-kselftest@vger.kernel.org shuah@kernel.org
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success net selftest script(s) already in Makefile
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? WARNING: line length of 83 exceeds 80 columns WARNING: line length of 84 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 88 exceeds 80 columns WARNING: line length of 92 exceeds 80 columns WARNING: line length of 95 exceeds 80 columns WARNING: line length of 97 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Xin Long Jan. 12, 2023, 12:41 a.m. UTC
This patch is to test all these factors and their combinations
that may enable/disable ipv6 DAD or RS on a slave port or dev.
For DAD, it includes:

  - sysctl "net.ipv6.conf.all.accept_dad"
  - sysctl "net.ipv6.conf.$dev_name.accept_dad"
  - inet6_ifaddr flag "IFA_F_NODAD"
  - netdev priv_flags "IFF_NO_ADDRCONF"

and for rs, it includes:

  - sysctl "net.ipv6.conf.$dev_name.accept_ra"
  - sysctl "net.ipv6.conf.$dev_name.router_solicitations"
  - netdev priv_flags "IFF_NO_ADDRCONF"

The test uses team/bond ports to have IFF_NO_ADDRCONF priv_flags
set, and "ip addr add ... nodad" to have IFA_F_NODAD flag set.
It uses "ip6tables" to count the DAD or RS packets during the
port or dev goes up.

Note that the bridge port is also tested as slave ports without
IFF_NO_ADDRCONF flag.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 tools/testing/selftests/net/Makefile       |   1 +
 tools/testing/selftests/net/ipv6_dad_rs.sh | 111 +++++++++++++++++++++
 2 files changed, 112 insertions(+)
 create mode 100755 tools/testing/selftests/net/ipv6_dad_rs.sh
diff mbox series

Patch

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 3007e98a6d64..4a9905d10212 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -75,6 +75,7 @@  TEST_GEN_PROGS += so_incoming_cpu
 TEST_PROGS += sctp_vrf.sh
 TEST_GEN_FILES += sctp_hello
 TEST_GEN_FILES += csum
+TEST_PROGS += ipv6_dad_rs.sh
 
 TEST_FILES := settings
 
diff --git a/tools/testing/selftests/net/ipv6_dad_rs.sh b/tools/testing/selftests/net/ipv6_dad_rs.sh
new file mode 100755
index 000000000000..064afe806ce4
--- /dev/null
+++ b/tools/testing/selftests/net/ipv6_dad_rs.sh
@@ -0,0 +1,111 @@ 
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Testing for DAD/RS on Ports/Devices.
+# TOPO: ns0 (link0) <---> (link1) ns1
+
+setup() {
+	local mac_addr
+	local ip6_addr
+
+	ip net add ns0
+	ip net add ns1
+	ip net exec ns0 ip link add link0 type veth peer link1 netns ns1
+	ip net exec ns0 ip link set link0 up
+
+	# The test uses global addrs, so drop the pkts for link-local addrs.
+	mac_addr=`ip net exec ns1 cat /sys/class/net/link1/address`
+	ip6_addr="ff02::1:ff${mac_addr:9:2}:${mac_addr:12:2}${mac_addr:15:2}"
+	ip net exec ns1 ip6tables -A OUTPUT -d $ip6_addr -j DROP
+}
+
+cleanup() {
+	ip net del ns1
+	ip net del ns0
+}
+
+check_pkts() {
+	local CNT=0
+
+	while ip net exec ns0 ip6tables -t raw -L -v | \
+		grep link0 | awk '$1 != "0" {exit 1}'; do
+		[ $((CNT++)) = "30" ] && return 1
+		sleep 0.1
+	done
+}
+
+do_test() {
+	local master_type="$1"
+	local icmpv6_type="$2"
+	local pkt_exp="$3"
+	local pkt_rcv="0"
+	local dad="$4"
+
+	ip net exec ns1 ip link set link1 down
+	[ $master_type != "veth" ] && {
+		ip net exec ns1 ip link add master_dev1 type $master_type
+		ip net exec ns1 ip link set link1 master master_dev1
+	}
+
+	ip net exec ns0 ip6tables -t raw -A PREROUTING -i link0 \
+		-p ipv6-icmp --icmpv6-type $icmpv6_type -j ACCEPT
+
+	ip net exec ns1 ip addr add 2000::1/64 dev link1 $dad
+	ip net exec ns1 ip link set link1 up
+	check_pkts && pkt_rcv="1"
+
+	ip net exec ns1 ip addr del 2000::1/64 dev link1 $dad
+	ip net exec ns0 ip6tables -t raw -D PREROUTING -i link0 \
+		-p ipv6-icmp --icmpv6-type $icmpv6_type -j ACCEPT
+
+	[ $master_type != "veth" ] &&
+		ip net exec ns1 ip link del master_dev1
+	test "$pkt_exp" = "$pkt_rcv"
+}
+
+test_rs() {
+	local rs=1
+
+	echo "- link_ra: $link_ra, link_rs: $link_rs"
+	ip net exec ns1 sysctl -qw net.ipv6.conf.link1.accept_ra=$link_ra
+	ip net exec ns1 sysctl -qw net.ipv6.conf.link1.router_solicitations=$link_rs
+
+	[ "$link_ra" = "0" -o  "$link_rs" = "0" ] && rs=0
+	do_test veth router-solicitation $rs   && echo "  veth device (RS $rs): PASS" &&
+	do_test bridge router-solicitation $rs && echo "  bridge port (RS $rs): PASS" &&
+	do_test bond router-solicitation 0     && echo "  bond slave  (RS 0): PASS" &&
+	do_test team router-solicitation 0     && echo "  team port   (RS 0): PASS"
+}
+
+test_dad() {
+	local nodad=""
+	local ns=1
+
+	echo "- all_dad: $all_dad, link_dad: $link_dad, addr_nodad: $addr_nodad"
+	ip net exec ns1 sysctl -qw net.ipv6.conf.all.accept_dad=$all_dad
+	ip net exec ns1 sysctl -qw net.ipv6.conf.link1.accept_dad=$link_dad
+
+	[ "$all_dad" = "0" -a "$link_dad" = "0" ] && ns=0
+	[ "$addr_nodad" = "1" ] && nodad="nodad"  && ns=0
+	do_test veth neighbor-solicitation $ns $nodad   && echo "  veth device (NS $ns): PASS" &&
+	do_test bridge neighbor-solicitation $ns $nodad && echo "  bridge port (NS $ns): PASS" &&
+	do_test bond neighbor-solicitation 0 $dad       && echo "  bond slave  (NS 0): PASS" &&
+	do_test team neighbor-solicitation 0 $dad       && echo "  team port   (NS 0): PASS"
+}
+
+trap cleanup EXIT
+setup && echo "Testing for DAD/RS on Ports/Devices:" && {
+	for all_dad in 0 1; do
+		for link_dad in 0 1; do
+			for addr_nodad in 0 1; do
+				test_dad || exit $?
+			done
+		done
+	done
+	for link_ra in 0 1; do
+		for link_rs in 0 1; do
+			test_rs || exit $?
+		done
+	done
+}
+exit $?