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