Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/net: use tc rule to filter the na packet

Test arp_ndisc_untracked_subnets use tcpdump to filter the unsolicited
and untracked na messages. It set -e before calling tcpdump. But if
tcpdump filters 0 packet, it will return none zero, and cause the script
to exit.

Instead of using slow tcpdump to capture packets, let's using tc rule
to filter out the na message.

At the same time, fix function setup_v6 which only needs one parameter.
Move all the related helpers from forwarding lib.sh to net lib.sh.

Fixes: 0ea7b0a454ca ("selftests: net: arp_ndisc_untracked_subnets: test for arp_accept and accept_untracked_na")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240517010327.2631319-1-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Hangbin Liu and committed by
Paolo Abeni
ea63ac14 efb9f4f1

+75 -94
+17 -36
tools/testing/selftests/net/arp_ndisc_untracked_subnets.sh
··· 73 73 # namespaces. veth0 is veth-router, veth1 is veth-host. 74 74 # first, set up the inteface's link to the namespace 75 75 # then, set the interface "up" 76 - ip -6 -netns ${ROUTER_NS_V6} link add name ${ROUTER_INTF} \ 77 - type veth peer name ${HOST_INTF} 76 + ip -n ${ROUTER_NS_V6} link add name ${ROUTER_INTF} \ 77 + type veth peer name ${HOST_INTF} netns ${HOST_NS_V6} 78 78 79 - ip -6 -netns ${ROUTER_NS_V6} link set dev ${ROUTER_INTF} up 80 - ip -6 -netns ${ROUTER_NS_V6} link set dev ${HOST_INTF} netns \ 81 - ${HOST_NS_V6} 82 - 83 - ip -6 -netns ${HOST_NS_V6} link set dev ${HOST_INTF} up 84 - ip -6 -netns ${ROUTER_NS_V6} addr add \ 85 - ${ROUTER_ADDR_V6}/${PREFIX_WIDTH_V6} dev ${ROUTER_INTF} nodad 79 + # Add tc rule to filter out host na message 80 + tc -n ${ROUTER_NS_V6} qdisc add dev ${ROUTER_INTF} clsact 81 + tc -n ${ROUTER_NS_V6} filter add dev ${ROUTER_INTF} \ 82 + ingress protocol ipv6 pref 1 handle 101 \ 83 + flower src_ip ${HOST_ADDR_V6} ip_proto icmpv6 type 136 skip_hw action pass 86 84 87 85 HOST_CONF=net.ipv6.conf.${HOST_INTF} 88 86 ip netns exec ${HOST_NS_V6} sysctl -qw ${HOST_CONF}.ndisc_notify=1 89 87 ip netns exec ${HOST_NS_V6} sysctl -qw ${HOST_CONF}.disable_ipv6=0 90 - ip -6 -netns ${HOST_NS_V6} addr add ${HOST_ADDR_V6}/${PREFIX_WIDTH_V6} \ 91 - dev ${HOST_INTF} 92 - 93 88 ROUTER_CONF=net.ipv6.conf.${ROUTER_INTF} 94 - 95 89 ip netns exec ${ROUTER_NS_V6} sysctl -w \ 96 90 ${ROUTER_CONF}.forwarding=1 >/dev/null 2>&1 97 91 ip netns exec ${ROUTER_NS_V6} sysctl -w \ ··· 93 99 ip netns exec ${ROUTER_NS_V6} sysctl -w \ 94 100 ${ROUTER_CONF}.accept_untracked_na=${accept_untracked_na} \ 95 101 >/dev/null 2>&1 102 + 103 + ip -n ${ROUTER_NS_V6} link set dev ${ROUTER_INTF} up 104 + ip -n ${HOST_NS_V6} link set dev ${HOST_INTF} up 105 + ip -n ${ROUTER_NS_V6} addr add ${ROUTER_ADDR_V6}/${PREFIX_WIDTH_V6} \ 106 + dev ${ROUTER_INTF} nodad 107 + ip -n ${HOST_NS_V6} addr add ${HOST_ADDR_V6}/${PREFIX_WIDTH_V6} \ 108 + dev ${HOST_INTF} 96 109 set +e 97 110 } 98 111 ··· 163 162 arp_test_gratuitous 2 1 164 163 } 165 164 166 - cleanup_tcpdump() { 167 - set -e 168 - [[ ! -z ${tcpdump_stdout} ]] && rm -f ${tcpdump_stdout} 169 - [[ ! -z ${tcpdump_stderr} ]] && rm -f ${tcpdump_stderr} 170 - tcpdump_stdout= 171 - tcpdump_stderr= 172 - set +e 173 - } 174 - 175 - start_tcpdump() { 176 - set -e 177 - tcpdump_stdout=`mktemp` 178 - tcpdump_stderr=`mktemp` 179 - ip netns exec ${ROUTER_NS_V6} timeout 15s \ 180 - tcpdump --immediate-mode -tpni ${ROUTER_INTF} -c 1 \ 181 - "icmp6 && icmp6[0] == 136 && src ${HOST_ADDR_V6}" \ 182 - > ${tcpdump_stdout} 2> /dev/null 183 - set +e 184 - } 185 - 186 165 verify_ndisc() { 187 166 local accept_untracked_na=$1 188 167 local same_subnet=$2 ··· 203 222 HOST_ADDR_V6=2001:db8:abcd:0012::3 204 223 fi 205 224 fi 206 - setup_v6 $1 $2 207 - start_tcpdump 225 + setup_v6 $1 226 + slowwait_for_counter 15 1 \ 227 + tc_rule_handle_stats_get "dev ${ROUTER_INTF} ingress" 101 ".packets" "-n ${ROUTER_NS_V6}" 208 228 209 229 if verify_ndisc $1 $2; then 210 230 printf " TEST: %-60s [ OK ]\n" "${test_msg[*]}" ··· 213 231 printf " TEST: %-60s [FAIL]\n" "${test_msg[*]}" 214 232 fi 215 233 216 - cleanup_tcpdump 217 234 cleanup_v6 218 235 set +e 219 236 }
-58
tools/testing/selftests/net/forwarding/lib.sh
··· 129 129 130 130 source "$net_forwarding_dir/../lib.sh" 131 131 132 - # timeout in seconds 133 - slowwait() 134 - { 135 - local timeout_sec=$1; shift 136 - 137 - loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@" 138 - } 139 - 140 132 ############################################################################## 141 133 # Sanity checks 142 134 ··· 670 678 "$@" | grep -q trap 671 679 } 672 680 673 - until_counter_is() 674 - { 675 - local expr=$1; shift 676 - local current=$("$@") 677 - 678 - echo $((current)) 679 - ((current $expr)) 680 - } 681 - 682 - busywait_for_counter() 683 - { 684 - local timeout=$1; shift 685 - local delta=$1; shift 686 - 687 - local base=$("$@") 688 - busywait "$timeout" until_counter_is ">= $((base + delta))" "$@" 689 - } 690 - 691 - slowwait_for_counter() 692 - { 693 - local timeout=$1; shift 694 - local delta=$1; shift 695 - 696 - local base=$("$@") 697 - slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@" 698 - } 699 - 700 681 setup_wait_dev() 701 682 { 702 683 local dev=$1; shift ··· 986 1021 link_stats_rx_errors_get() 987 1022 { 988 1023 link_stats_get $1 rx errors 989 - } 990 - 991 - tc_rule_stats_get() 992 - { 993 - local dev=$1; shift 994 - local pref=$1; shift 995 - local dir=$1; shift 996 - local selector=${1:-.packets}; shift 997 - 998 - tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \ 999 - | jq ".[1].options.actions[].stats$selector" 1000 - } 1001 - 1002 - tc_rule_handle_stats_get() 1003 - { 1004 - local id=$1; shift 1005 - local handle=$1; shift 1006 - local selector=${1:-.packets}; shift 1007 - local netns=${1:-""}; shift 1008 - 1009 - tc $netns -j -s filter show $id \ 1010 - | jq ".[] | select(.options.handle == $handle) | \ 1011 - .options.actions[0].stats$selector" 1012 1024 } 1013 1025 1014 1026 ethtool_stats_get()
+58
tools/testing/selftests/net/lib.sh
··· 91 91 loopy_wait : "$timeout_ms" "$@" 92 92 } 93 93 94 + # timeout in seconds 95 + slowwait() 96 + { 97 + local timeout_sec=$1; shift 98 + 99 + loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@" 100 + } 101 + 102 + until_counter_is() 103 + { 104 + local expr=$1; shift 105 + local current=$("$@") 106 + 107 + echo $((current)) 108 + ((current $expr)) 109 + } 110 + 111 + busywait_for_counter() 112 + { 113 + local timeout=$1; shift 114 + local delta=$1; shift 115 + 116 + local base=$("$@") 117 + busywait "$timeout" until_counter_is ">= $((base + delta))" "$@" 118 + } 119 + 120 + slowwait_for_counter() 121 + { 122 + local timeout=$1; shift 123 + local delta=$1; shift 124 + 125 + local base=$("$@") 126 + slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@" 127 + } 128 + 94 129 cleanup_ns() 95 130 { 96 131 local ns="" ··· 184 149 ! $ns_exist && ns_list="$ns_list $ns" 185 150 done 186 151 NS_LIST="$NS_LIST $ns_list" 152 + } 153 + 154 + tc_rule_stats_get() 155 + { 156 + local dev=$1; shift 157 + local pref=$1; shift 158 + local dir=$1; shift 159 + local selector=${1:-.packets}; shift 160 + 161 + tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \ 162 + | jq ".[1].options.actions[].stats$selector" 163 + } 164 + 165 + tc_rule_handle_stats_get() 166 + { 167 + local id=$1; shift 168 + local handle=$1; shift 169 + local selector=${1:-.packets}; shift 170 + local netns=${1:-""}; shift 171 + 172 + tc $netns -j -s filter show $id \ 173 + | jq ".[] | select(.options.handle == $handle) | \ 174 + .options.actions[0].stats$selector" 187 175 }