2022-04-15 08:34:02 +00:00
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
2022-05-30 10:14:14 +00:00
# This test is for the accept_untracked_na feature to
2022-04-15 08:34:02 +00:00
# enable RFC9131 behaviour. The following is the test-matrix.
# drop accept fwding behaviour
# ---- ------ ------ ----------------------------------------------
2022-05-30 10:14:14 +00:00
# 1 X X Don't update NC
# 0 0 X Don't update NC
# 0 1 0 Don't update NC
# 0 1 1 Add a STALE NC entry
2022-04-15 08:34:02 +00:00
ret = 0
# Kselftest framework requirement - SKIP code is 4.
ksft_skip = 4
PAUSE_ON_FAIL = no
PAUSE = no
HOST_NS = "ns-host"
ROUTER_NS = "ns-router"
HOST_INTF = "veth-host"
ROUTER_INTF = "veth-router"
ROUTER_ADDR = "2000:20::1"
HOST_ADDR = "2000:20::2"
SUBNET_WIDTH = 64
ROUTER_ADDR_WITH_MASK = " ${ ROUTER_ADDR } / ${ SUBNET_WIDTH } "
HOST_ADDR_WITH_MASK = " ${ HOST_ADDR } / ${ SUBNET_WIDTH } "
IP_HOST = " ip -6 -netns ${ HOST_NS } "
IP_HOST_EXEC = " ip netns exec ${ HOST_NS } "
IP_ROUTER = " ip -6 -netns ${ ROUTER_NS } "
IP_ROUTER_EXEC = " ip netns exec ${ ROUTER_NS } "
tcpdump_stdout =
tcpdump_stderr =
log_test( )
{
local rc = $1
local expected = $2
local msg = " $3 "
if [ ${ rc } -eq ${ expected } ] ; then
printf " TEST: %-60s [ OK ]\n" " ${ msg } "
nsuccess = $(( nsuccess+1))
else
ret = 1
nfail = $(( nfail+1))
printf " TEST: %-60s [FAIL]\n" " ${ msg } "
if [ " ${ PAUSE_ON_FAIL } " = "yes" ] ; then
echo
echo "hit enter to continue, 'q' to quit"
read a
[ " $a " = "q" ] && exit 1
fi
fi
if [ " ${ PAUSE } " = "yes" ] ; then
echo
echo "hit enter to continue, 'q' to quit"
read a
[ " $a " = "q" ] && exit 1
fi
}
setup( )
{
set -e
local drop_unsolicited_na = $1
2022-05-30 10:14:14 +00:00
local accept_untracked_na = $2
2022-04-15 08:34:02 +00:00
local forwarding = $3
# Setup two namespaces and a veth tunnel across them.
# On end of the tunnel is a router and the other end is a host.
ip netns add ${ HOST_NS }
ip netns add ${ ROUTER_NS }
${ IP_ROUTER } link add ${ ROUTER_INTF } type veth \
peer name ${ HOST_INTF } netns ${ HOST_NS }
# Enable IPv6 on both router and host, and configure static addresses.
# The router here is the DUT
# Setup router configuration as specified by the arguments.
# forwarding=0 case is to check that a non-router
# doesn't add neighbour entries.
ROUTER_CONF = net.ipv6.conf.${ ROUTER_INTF }
${ IP_ROUTER_EXEC } sysctl -qw \
${ ROUTER_CONF } .forwarding= ${ forwarding }
${ IP_ROUTER_EXEC } sysctl -qw \
${ ROUTER_CONF } .drop_unsolicited_na= ${ drop_unsolicited_na }
${ IP_ROUTER_EXEC } sysctl -qw \
2022-05-30 10:14:14 +00:00
${ ROUTER_CONF } .accept_untracked_na= ${ accept_untracked_na }
2022-04-15 08:34:02 +00:00
${ IP_ROUTER_EXEC } sysctl -qw ${ ROUTER_CONF } .disable_ipv6= 0
${ IP_ROUTER } addr add ${ ROUTER_ADDR_WITH_MASK } dev ${ ROUTER_INTF }
# Turn on ndisc_notify on host interface so that
# the host sends unsolicited NAs.
HOST_CONF = net.ipv6.conf.${ HOST_INTF }
${ IP_HOST_EXEC } sysctl -qw ${ HOST_CONF } .ndisc_notify= 1
${ IP_HOST_EXEC } sysctl -qw ${ HOST_CONF } .disable_ipv6= 0
${ IP_HOST } addr add ${ HOST_ADDR_WITH_MASK } dev ${ HOST_INTF }
set +e
}
start_tcpdump( ) {
set -e
tcpdump_stdout = ` mktemp`
tcpdump_stderr = ` mktemp`
${ IP_ROUTER_EXEC } timeout 15s \
tcpdump --immediate-mode -tpni ${ ROUTER_INTF } -c 1 \
" icmp6 && icmp6[0] == 136 && src ${ HOST_ADDR } " \
> ${ tcpdump_stdout } 2> /dev/null
set +e
}
cleanup_tcpdump( )
{
set -e
[ [ ! -z ${ tcpdump_stdout } ] ] && rm -f ${ tcpdump_stdout }
[ [ ! -z ${ tcpdump_stderr } ] ] && rm -f ${ tcpdump_stderr }
tcpdump_stdout =
tcpdump_stderr =
set +e
}
cleanup( )
{
cleanup_tcpdump
ip netns del ${ HOST_NS }
ip netns del ${ ROUTER_NS }
}
link_up( ) {
set -e
${ IP_ROUTER } link set dev ${ ROUTER_INTF } up
${ IP_HOST } link set dev ${ HOST_INTF } up
set +e
}
verify_ndisc( ) {
local drop_unsolicited_na = $1
2022-05-30 10:14:14 +00:00
local accept_untracked_na = $2
2022-04-15 08:34:02 +00:00
local forwarding = $3
neigh_show_output = $( ${ IP_ROUTER } neigh show \
to ${ HOST_ADDR } dev ${ ROUTER_INTF } nud stale)
if [ ${ drop_unsolicited_na } -eq 0 ] && \
2022-05-30 10:14:14 +00:00
[ ${ accept_untracked_na } -eq 1 ] && \
2022-04-15 08:34:02 +00:00
[ ${ forwarding } -eq 1 ] ; then
# Neighbour entry expected to be present for 011 case
[ [ ${ neigh_show_output } ] ]
else
# Neighbour entry expected to be absent for all other cases
[ [ -z ${ neigh_show_output } ] ]
fi
}
test_unsolicited_na_common( )
{
# Setup the test bed, but keep links down
setup $1 $2 $3
# Bring the link up, wait for the NA,
# and add a delay to ensure neighbour processing is done.
link_up
start_tcpdump
# Verify the neighbour table
verify_ndisc $1 $2 $3
}
test_unsolicited_na_combination( ) {
test_unsolicited_na_common $1 $2 $3
test_msg = ( "test_unsolicited_na: "
" drop_unsolicited_na= $1 "
2022-05-30 10:14:14 +00:00
" accept_untracked_na= $2 "
2022-04-15 08:34:02 +00:00
" forwarding= $3 " )
log_test $? 0 " ${ test_msg [*] } "
cleanup
}
test_unsolicited_na_combinations( ) {
2022-05-30 10:14:14 +00:00
# Args: drop_unsolicited_na accept_untracked_na forwarding
2022-04-15 08:34:02 +00:00
# Expect entry
test_unsolicited_na_combination 0 1 1
# Expect no entry
test_unsolicited_na_combination 0 0 0
test_unsolicited_na_combination 0 0 1
test_unsolicited_na_combination 0 1 0
test_unsolicited_na_combination 1 0 0
test_unsolicited_na_combination 1 0 1
test_unsolicited_na_combination 1 1 0
test_unsolicited_na_combination 1 1 1
}
###############################################################################
# usage
usage( )
{
cat <<EOF
usage: ${ 0 ##*/ } OPTS
-p Pause on fail
-P Pause after each test before cleanup
EOF
}
###############################################################################
# main
while getopts :pPh o
do
case $o in
p) PAUSE_ON_FAIL = yes; ;
P) PAUSE = yes; ;
h) usage; exit 0; ;
*) usage; exit 1; ;
esac
done
# make sure we don't pause twice
[ " ${ PAUSE } " = "yes" ] && PAUSE_ON_FAIL = no
if [ " $( id -u) " -ne 0 ] ; then
echo "SKIP: Need root privileges"
exit $ksft_skip ;
fi
if [ ! -x " $( command -v ip) " ] ; then
echo "SKIP: Could not run test without ip tool"
exit $ksft_skip
fi
if [ ! -x " $( command -v tcpdump) " ] ; then
echo "SKIP: Could not run test without tcpdump tool"
exit $ksft_skip
fi
# start clean
cleanup & > /dev/null
test_unsolicited_na_combinations
printf "\nTests passed: %3d\n" ${ nsuccess }
printf "Tests failed: %3d\n" ${ nfail }
exit $ret