File Index
Files and directories
Sign in
FILE

ndisc_unsolicited_na_test.sh

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/ndisc_unsolicited_na_test.sh BASH
  1#!/bin/bash
  2# SPDX-License-Identifier: GPL-2.0
  3
  4# This test is for the accept_untracked_na feature to
  5# enable RFC9131 behaviour. The following is the test-matrix.
  6# drop   accept  fwding                   behaviour
  7# ----   ------  ------  ----------------------------------------------
  8#    1        X       X  Don't update NC
  9#    0        0       X  Don't update NC
 10#    0        1       0  Don't update NC
 11#    0        1       1  Add a STALE NC entry
 12
 13source lib.sh
 14ret=0
 15
 16PAUSE_ON_FAIL=no
 17PAUSE=no
 18
 19HOST_INTF="veth-host"
 20ROUTER_INTF="veth-router"
 21
 22ROUTER_ADDR="2000:20::1"
 23HOST_ADDR="2000:20::2"
 24SUBNET_WIDTH=64
 25ROUTER_ADDR_WITH_MASK="${ROUTER_ADDR}/${SUBNET_WIDTH}"
 26HOST_ADDR_WITH_MASK="${HOST_ADDR}/${SUBNET_WIDTH}"
 27
 28tcpdump_stdout=
 29tcpdump_stderr=
 30
 31log_test()
 32{
 33	local rc=$1
 34	local expected=$2
 35	local msg="$3"
 36
 37	if [ ${rc} -eq ${expected} ]; then
 38		printf "    TEST: %-60s  [ OK ]\n" "${msg}"
 39		nsuccess=$((nsuccess+1))
 40	else
 41		ret=1
 42		nfail=$((nfail+1))
 43		printf "    TEST: %-60s  [FAIL]\n" "${msg}"
 44		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
 45		echo
 46			echo "hit enter to continue, 'q' to quit"
 47			read a
 48			[ "$a" = "q" ] && exit 1
 49		fi
 50	fi
 51
 52	if [ "${PAUSE}" = "yes" ]; then
 53		echo
 54		echo "hit enter to continue, 'q' to quit"
 55		read a
 56		[ "$a" = "q" ] && exit 1
 57	fi
 58}
 59
 60setup()
 61{
 62	set -e
 63
 64	local drop_unsolicited_na=$1
 65	local accept_untracked_na=$2
 66	local forwarding=$3
 67
 68	# Setup two namespaces and a veth tunnel across them.
 69	# On end of the tunnel is a router and the other end is a host.
 70	setup_ns HOST_NS ROUTER_NS
 71	IP_HOST="ip -6 -netns ${HOST_NS}"
 72	IP_HOST_EXEC="ip netns exec ${HOST_NS}"
 73	IP_ROUTER="ip -6 -netns ${ROUTER_NS}"
 74	IP_ROUTER_EXEC="ip netns exec ${ROUTER_NS}"
 75
 76	${IP_ROUTER} link add ${ROUTER_INTF} type veth \
 77                peer name ${HOST_INTF} netns ${HOST_NS}
 78
 79	# Enable IPv6 on both router and host, and configure static addresses.
 80	# The router here is the DUT
 81	# Setup router configuration as specified by the arguments.
 82	# forwarding=0 case is to check that a non-router
 83	# doesn't add neighbour entries.
 84        ROUTER_CONF=net.ipv6.conf.${ROUTER_INTF}
 85	${IP_ROUTER_EXEC} sysctl -qw \
 86                ${ROUTER_CONF}.forwarding=${forwarding}
 87	${IP_ROUTER_EXEC} sysctl -qw \
 88                ${ROUTER_CONF}.drop_unsolicited_na=${drop_unsolicited_na}
 89	${IP_ROUTER_EXEC} sysctl -qw \
 90                ${ROUTER_CONF}.accept_untracked_na=${accept_untracked_na}
 91	${IP_ROUTER_EXEC} sysctl -qw ${ROUTER_CONF}.disable_ipv6=0
 92	${IP_ROUTER} addr add ${ROUTER_ADDR_WITH_MASK} dev ${ROUTER_INTF}
 93
 94	# Turn on ndisc_notify on host interface so that
 95	# the host sends unsolicited NAs.
 96	HOST_CONF=net.ipv6.conf.${HOST_INTF}
 97	${IP_HOST_EXEC} sysctl -qw ${HOST_CONF}.ndisc_notify=1
 98	${IP_HOST_EXEC} sysctl -qw ${HOST_CONF}.disable_ipv6=0
 99	${IP_HOST} addr add ${HOST_ADDR_WITH_MASK} dev ${HOST_INTF}
100
101	set +e
102}
103
104start_tcpdump() {
105	set -e
106	tcpdump_stdout=`mktemp`
107	tcpdump_stderr=`mktemp`
108	${IP_ROUTER_EXEC} timeout 15s \
109                tcpdump --immediate-mode -tpni ${ROUTER_INTF} -c 1 \
110                "icmp6 && icmp6[0] == 136 && src ${HOST_ADDR}" \
111                > ${tcpdump_stdout} 2> /dev/null
112	set +e
113}
114
115cleanup_tcpdump()
116{
117	set -e
118	[[ ! -z  ${tcpdump_stdout} ]] && rm -f ${tcpdump_stdout}
119	[[ ! -z  ${tcpdump_stderr} ]] && rm -f ${tcpdump_stderr}
120	tcpdump_stdout=
121	tcpdump_stderr=
122	set +e
123}
124
125cleanup()
126{
127	cleanup_tcpdump
128	ip netns del ${HOST_NS}
129	ip netns del ${ROUTER_NS}
130}
131
132link_up() {
133	set -e
134	${IP_ROUTER} link set dev ${ROUTER_INTF} up
135	${IP_HOST} link set dev ${HOST_INTF} up
136	set +e
137}
138
139verify_ndisc() {
140	local drop_unsolicited_na=$1
141	local accept_untracked_na=$2
142	local forwarding=$3
143
144	neigh_show_output=$(${IP_ROUTER} neigh show \
145                to ${HOST_ADDR} dev ${ROUTER_INTF} nud stale)
146	if [ ${drop_unsolicited_na} -eq 0 ] && \
147			[ ${accept_untracked_na} -eq 1 ] && \
148			[ ${forwarding} -eq 1 ]; then
149		# Neighbour entry expected to be present for 011 case
150		[[ ${neigh_show_output} ]]
151	else
152		# Neighbour entry expected to be absent for all other cases
153		[[ -z ${neigh_show_output} ]]
154	fi
155}
156
157test_unsolicited_na_common()
158{
159	# Setup the test bed, but keep links down
160	setup $1 $2 $3
161
162	# Bring the link up, wait for the NA,
163	# and add a delay to ensure neighbour processing is done.
164	link_up
165	start_tcpdump
166
167	# Verify the neighbour table
168	verify_ndisc $1 $2 $3
169
170}
171
172test_unsolicited_na_combination() {
173	test_unsolicited_na_common $1 $2 $3
174	test_msg=("test_unsolicited_na: "
175		"drop_unsolicited_na=$1 "
176		"accept_untracked_na=$2 "
177		"forwarding=$3")
178	log_test $? 0 "${test_msg[*]}"
179	cleanup
180}
181
182test_unsolicited_na_combinations() {
183	# Args: drop_unsolicited_na accept_untracked_na forwarding
184
185	# Expect entry
186	test_unsolicited_na_combination 0 1 1
187
188	# Expect no entry
189	test_unsolicited_na_combination 0 0 0
190	test_unsolicited_na_combination 0 0 1
191	test_unsolicited_na_combination 0 1 0
192	test_unsolicited_na_combination 1 0 0
193	test_unsolicited_na_combination 1 0 1
194	test_unsolicited_na_combination 1 1 0
195	test_unsolicited_na_combination 1 1 1
196}
197
198###############################################################################
199# usage
200
201usage()
202{
203	cat <<EOF
204usage: ${0##*/} OPTS
205        -p          Pause on fail
206        -P          Pause after each test before cleanup
207EOF
208}
209
210###############################################################################
211# main
212
213while getopts :pPh o
214do
215	case $o in
216		p) PAUSE_ON_FAIL=yes;;
217		P) PAUSE=yes;;
218		h) usage; exit 0;;
219		*) usage; exit 1;;
220	esac
221done
222
223# make sure we don't pause twice
224[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
225
226if [ "$(id -u)" -ne 0 ];then
227	echo "SKIP: Need root privileges"
228	exit $ksft_skip;
229fi
230
231if [ ! -x "$(command -v ip)" ]; then
232	echo "SKIP: Could not run test without ip tool"
233	exit $ksft_skip
234fi
235
236if [ ! -x "$(command -v tcpdump)" ]; then
237	echo "SKIP: Could not run test without tcpdump tool"
238	exit $ksft_skip
239fi
240
241# start clean
242cleanup &> /dev/null
243
244test_unsolicited_na_combinations
245
246printf "\nTests passed: %3d\n" ${nsuccess}
247printf "Tests failed: %3d\n"   ${nfail}
248
249exit $ret
~/ Read-only file preview.