@@ -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
new file mode 100755
@@ -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 $?
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