Commit ea63ac14 authored by Hangbin Liu's avatar Hangbin Liu Committed by Paolo Abeni
Browse files

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: 0ea7b0a4 ("selftests: net: arp_ndisc_untracked_subnets: test for arp_accept and accept_untracked_na")
Signed-off-by: default avatarHangbin Liu <liuhangbin@gmail.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240517010327.2631319-1-liuhangbin@gmail.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent efb9f4f1
Loading
Loading
Loading
Loading
+17 −36
Original line number Diff line number Diff line
@@ -73,25 +73,19 @@ setup_v6() {
	# namespaces. veth0 is veth-router, veth1 is veth-host.
	# first, set up the inteface's link to the namespace
	# then, set the interface "up"
	ip -6 -netns ${ROUTER_NS_V6} link add name ${ROUTER_INTF} \
		type veth peer name ${HOST_INTF}

	ip -6 -netns ${ROUTER_NS_V6} link set dev ${ROUTER_INTF} up
	ip -6 -netns ${ROUTER_NS_V6} link set dev ${HOST_INTF} netns \
		${HOST_NS_V6}
	ip -n ${ROUTER_NS_V6} link add name ${ROUTER_INTF} \
		type veth peer name ${HOST_INTF} netns ${HOST_NS_V6}

	ip -6 -netns ${HOST_NS_V6} link set dev ${HOST_INTF} up
	ip -6 -netns ${ROUTER_NS_V6} addr add \
		${ROUTER_ADDR_V6}/${PREFIX_WIDTH_V6} dev ${ROUTER_INTF} nodad
	# Add tc rule to filter out host na message
	tc -n ${ROUTER_NS_V6} qdisc add dev ${ROUTER_INTF} clsact
	tc -n ${ROUTER_NS_V6} filter add dev ${ROUTER_INTF} \
		ingress protocol ipv6 pref 1 handle 101 \
		flower src_ip ${HOST_ADDR_V6} ip_proto icmpv6 type 136 skip_hw action pass

	HOST_CONF=net.ipv6.conf.${HOST_INTF}
	ip netns exec ${HOST_NS_V6} sysctl -qw ${HOST_CONF}.ndisc_notify=1
	ip netns exec ${HOST_NS_V6} sysctl -qw ${HOST_CONF}.disable_ipv6=0
	ip -6 -netns ${HOST_NS_V6} addr add ${HOST_ADDR_V6}/${PREFIX_WIDTH_V6} \
		dev ${HOST_INTF}

	ROUTER_CONF=net.ipv6.conf.${ROUTER_INTF}

	ip netns exec ${ROUTER_NS_V6} sysctl -w \
		${ROUTER_CONF}.forwarding=1 >/dev/null 2>&1
	ip netns exec ${ROUTER_NS_V6} sysctl -w \
@@ -99,6 +93,13 @@ setup_v6() {
	ip netns exec ${ROUTER_NS_V6} sysctl -w \
		${ROUTER_CONF}.accept_untracked_na=${accept_untracked_na} \
		>/dev/null 2>&1

	ip -n ${ROUTER_NS_V6} link set dev ${ROUTER_INTF} up
	ip -n ${HOST_NS_V6} link set dev ${HOST_INTF} up
	ip -n ${ROUTER_NS_V6} addr add ${ROUTER_ADDR_V6}/${PREFIX_WIDTH_V6} \
		dev ${ROUTER_INTF} nodad
	ip -n ${HOST_NS_V6} addr add ${HOST_ADDR_V6}/${PREFIX_WIDTH_V6} \
		dev ${HOST_INTF}
	set +e
}

@@ -162,26 +163,6 @@ arp_test_gratuitous_combinations() {
	arp_test_gratuitous 2 1
}

cleanup_tcpdump() {
	set -e
	[[ ! -z  ${tcpdump_stdout} ]] && rm -f ${tcpdump_stdout}
	[[ ! -z  ${tcpdump_stderr} ]] && rm -f ${tcpdump_stderr}
	tcpdump_stdout=
	tcpdump_stderr=
	set +e
}

start_tcpdump() {
	set -e
	tcpdump_stdout=`mktemp`
	tcpdump_stderr=`mktemp`
	ip netns exec ${ROUTER_NS_V6} timeout 15s \
		tcpdump --immediate-mode -tpni ${ROUTER_INTF} -c 1 \
		"icmp6 && icmp6[0] == 136 && src ${HOST_ADDR_V6}" \
		> ${tcpdump_stdout} 2> /dev/null
	set +e
}

verify_ndisc() {
	local accept_untracked_na=$1
	local same_subnet=$2
@@ -222,8 +203,9 @@ ndisc_test_untracked_advertisements() {
			HOST_ADDR_V6=2001:db8:abcd:0012::3
		fi
	fi
	setup_v6 $1 $2
	start_tcpdump
	setup_v6 $1
	slowwait_for_counter 15 1 \
		tc_rule_handle_stats_get "dev ${ROUTER_INTF} ingress" 101 ".packets" "-n ${ROUTER_NS_V6}"

	if verify_ndisc $1 $2; then
		printf "    TEST: %-60s  [ OK ]\n" "${test_msg[*]}"
@@ -231,7 +213,6 @@ ndisc_test_untracked_advertisements() {
		printf "    TEST: %-60s  [FAIL]\n" "${test_msg[*]}"
	fi

	cleanup_tcpdump
	cleanup_v6
	set +e
}
+0 −58
Original line number Diff line number Diff line
@@ -129,14 +129,6 @@ fi

source "$net_forwarding_dir/../lib.sh"

# timeout in seconds
slowwait()
{
	local timeout_sec=$1; shift

	loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@"
}

##############################################################################
# Sanity checks

@@ -678,33 +670,6 @@ wait_for_trap()
	"$@" | grep -q trap
}

until_counter_is()
{
	local expr=$1; shift
	local current=$("$@")

	echo $((current))
	((current $expr))
}

busywait_for_counter()
{
	local timeout=$1; shift
	local delta=$1; shift

	local base=$("$@")
	busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"
}

slowwait_for_counter()
{
	local timeout=$1; shift
	local delta=$1; shift

	local base=$("$@")
	slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@"
}

setup_wait_dev()
{
	local dev=$1; shift
@@ -1023,29 +988,6 @@ link_stats_rx_errors_get()
	link_stats_get $1 rx errors
}

tc_rule_stats_get()
{
	local dev=$1; shift
	local pref=$1; shift
	local dir=$1; shift
	local selector=${1:-.packets}; shift

	tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \
	    | jq ".[1].options.actions[].stats$selector"
}

tc_rule_handle_stats_get()
{
	local id=$1; shift
	local handle=$1; shift
	local selector=${1:-.packets}; shift
	local netns=${1:-""}; shift

	tc $netns -j -s filter show $id \
	    | jq ".[] | select(.options.handle == $handle) | \
		  .options.actions[0].stats$selector"
}

ethtool_stats_get()
{
	local dev=$1; shift
+58 −0
Original line number Diff line number Diff line
@@ -91,6 +91,41 @@ busywait()
	loopy_wait : "$timeout_ms" "$@"
}

# timeout in seconds
slowwait()
{
	local timeout_sec=$1; shift

	loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@"
}

until_counter_is()
{
	local expr=$1; shift
	local current=$("$@")

	echo $((current))
	((current $expr))
}

busywait_for_counter()
{
	local timeout=$1; shift
	local delta=$1; shift

	local base=$("$@")
	busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"
}

slowwait_for_counter()
{
	local timeout=$1; shift
	local delta=$1; shift

	local base=$("$@")
	slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@"
}

cleanup_ns()
{
	local ns=""
@@ -150,3 +185,26 @@ setup_ns()
	done
	NS_LIST="$NS_LIST $ns_list"
}

tc_rule_stats_get()
{
	local dev=$1; shift
	local pref=$1; shift
	local dir=$1; shift
	local selector=${1:-.packets}; shift

	tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \
	    | jq ".[1].options.actions[].stats$selector"
}

tc_rule_handle_stats_get()
{
	local id=$1; shift
	local handle=$1; shift
	local selector=${1:-.packets}; shift
	local netns=${1:-""}; shift

	tc $netns -j -s filter show $id \
	    | jq ".[] | select(.options.handle == $handle) | \
		  .options.actions[0].stats$selector"
}