250 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# This test is for the accept_untracked_na feature to5# enable RFC9131 behaviour. The following is the test-matrix.6# drop accept fwding behaviour7# ---- ------ ------ ----------------------------------------------8# 1 X X Don't update NC9# 0 0 X Don't update NC10# 0 1 0 Don't update NC11# 0 1 1 Add a STALE NC entry12 13source lib.sh14ret=015 16PAUSE_ON_FAIL=no17PAUSE=no18 19HOST_INTF="veth-host"20ROUTER_INTF="veth-router"21 22ROUTER_ADDR="2000:20::1"23HOST_ADDR="2000:20::2"24SUBNET_WIDTH=6425ROUTER_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=$134 local expected=$235 local msg="$3"36 37 if [ ${rc} -eq ${expected} ]; then38 printf " TEST: %-60s [ OK ]\n" "${msg}"39 nsuccess=$((nsuccess+1))40 else41 ret=142 nfail=$((nfail+1))43 printf " TEST: %-60s [FAIL]\n" "${msg}"44 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then45 echo46 echo "hit enter to continue, 'q' to quit"47 read a48 [ "$a" = "q" ] && exit 149 fi50 fi51 52 if [ "${PAUSE}" = "yes" ]; then53 echo54 echo "hit enter to continue, 'q' to quit"55 read a56 [ "$a" = "q" ] && exit 157 fi58}59 60setup()61{62 set -e63 64 local drop_unsolicited_na=$165 local accept_untracked_na=$266 local forwarding=$367 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_NS71 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 DUT81 # Setup router configuration as specified by the arguments.82 # forwarding=0 case is to check that a non-router83 # 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=092 ${IP_ROUTER} addr add ${ROUTER_ADDR_WITH_MASK} dev ${ROUTER_INTF}93 94 # Turn on ndisc_notify on host interface so that95 # the host sends unsolicited NAs.96 HOST_CONF=net.ipv6.conf.${HOST_INTF}97 ${IP_HOST_EXEC} sysctl -qw ${HOST_CONF}.ndisc_notify=198 ${IP_HOST_EXEC} sysctl -qw ${HOST_CONF}.disable_ipv6=099 ${IP_HOST} addr add ${HOST_ADDR_WITH_MASK} dev ${HOST_INTF}100 101 set +e102}103 104start_tcpdump() {105 set -e106 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/null112 set +e113}114 115cleanup_tcpdump()116{117 set -e118 [[ ! -z ${tcpdump_stdout} ]] && rm -f ${tcpdump_stdout}119 [[ ! -z ${tcpdump_stderr} ]] && rm -f ${tcpdump_stderr}120 tcpdump_stdout=121 tcpdump_stderr=122 set +e123}124 125cleanup()126{127 cleanup_tcpdump128 ip netns del ${HOST_NS}129 ip netns del ${ROUTER_NS}130}131 132link_up() {133 set -e134 ${IP_ROUTER} link set dev ${ROUTER_INTF} up135 ${IP_HOST} link set dev ${HOST_INTF} up136 set +e137}138 139verify_ndisc() {140 local drop_unsolicited_na=$1141 local accept_untracked_na=$2142 local forwarding=$3143 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 ]; then149 # Neighbour entry expected to be present for 011 case150 [[ ${neigh_show_output} ]]151 else152 # Neighbour entry expected to be absent for all other cases153 [[ -z ${neigh_show_output} ]]154 fi155}156 157test_unsolicited_na_common()158{159 # Setup the test bed, but keep links down160 setup $1 $2 $3161 162 # Bring the link up, wait for the NA,163 # and add a delay to ensure neighbour processing is done.164 link_up165 start_tcpdump166 167 # Verify the neighbour table168 verify_ndisc $1 $2 $3169 170}171 172test_unsolicited_na_combination() {173 test_unsolicited_na_common $1 $2 $3174 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 cleanup180}181 182test_unsolicited_na_combinations() {183 # Args: drop_unsolicited_na accept_untracked_na forwarding184 185 # Expect entry186 test_unsolicited_na_combination 0 1 1187 188 # Expect no entry189 test_unsolicited_na_combination 0 0 0190 test_unsolicited_na_combination 0 0 1191 test_unsolicited_na_combination 0 1 0192 test_unsolicited_na_combination 1 0 0193 test_unsolicited_na_combination 1 0 1194 test_unsolicited_na_combination 1 1 0195 test_unsolicited_na_combination 1 1 1196}197 198###############################################################################199# usage200 201usage()202{203 cat <<EOF204usage: ${0##*/} OPTS205 -p Pause on fail206 -P Pause after each test before cleanup207EOF208}209 210###############################################################################211# main212 213while getopts :pPh o214do215 case $o in216 p) PAUSE_ON_FAIL=yes;;217 P) PAUSE=yes;;218 h) usage; exit 0;;219 *) usage; exit 1;;220 esac221done222 223# make sure we don't pause twice224[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no225 226if [ "$(id -u)" -ne 0 ];then227 echo "SKIP: Need root privileges"228 exit $ksft_skip;229fi230 231if [ ! -x "$(command -v ip)" ]; then232 echo "SKIP: Could not run test without ip tool"233 exit $ksft_skip234fi235 236if [ ! -x "$(command -v tcpdump)" ]; then237 echo "SKIP: Could not run test without tcpdump tool"238 exit $ksft_skip239fi240 241# start clean242cleanup &> /dev/null243 244test_unsolicited_na_combinations245 246printf "\nTests passed: %3d\n" ${nsuccess}247printf "Tests failed: %3d\n" ${nfail}248 249exit $ret250