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 13 source lib.sh 14 ret=0 15 16 PAUSE_ON_FAIL=no 17 PAUSE=no 18 19 HOST_INTF="veth-host" 20 ROUTER_INTF="veth-router" 21 22 ROUTER_ADDR="2000:20::1" 23 HOST_ADDR="2000:20::2" 24 SUBNET_WIDTH=64 25 ROUTER_ADDR_WITH_MASK="${ROUTER_ADDR}/${SUBNET_WIDTH}" 26 HOST_ADDR_WITH_MASK="${HOST_ADDR}/${SUBNET_WIDTH}" 27 28 tcpdump_stdout= 29 tcpdump_stderr= 30 31 log_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 60 setup() 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 104 start_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 115 cleanup_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 125 cleanup() 126 { 127 cleanup_tcpdump 128 ip netns del ${HOST_NS} 129 ip netns del ${ROUTER_NS} 130 } 131 132 link_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 139 verify_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 157 test_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 172 test_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 182 test_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 201 usage() 202 { 203 cat <<EOF 204 usage: ${0##*/} OPTS 205 -p Pause on fail 206 -P Pause after each test before cleanup 207 EOF 208 } 209 210 ############################################################################### 211 # main 212 213 while getopts :pPh o 214 do 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 221 done 222 223 # make sure we don't pause twice 224 [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 225 226 if [ "$(id -u)" -ne 0 ];then 227 echo "SKIP: Need root privileges" 228 exit $ksft_skip; 229 fi 230 231 if [ ! -x "$(command -v ip)" ]; then 232 echo "SKIP: Could not run test without ip tool" 233 exit $ksft_skip 234 fi 235 236 if [ ! -x "$(command -v tcpdump)" ]; then 237 echo "SKIP: Could not run test without tcpdump tool" 238 exit $ksft_skip 239 fi 240 241 # start clean 242 cleanup &> /dev/null 243 244 test_unsolicited_na_combinations 245 246 printf "\nTests passed: %3d\n" ${nsuccess} 247 printf "Tests failed: %3d\n" ${nfail} 248 249 exit $ret
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.