1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Tests sysctl options {arp,ndisc}_evict_nocarrier={0,1} 5# 6# Create a veth pair and set IPs/routes on both. Then ping to establish 7# an entry in the ARP/ND table. Depending on the test set sysctl option to 8# 1 or 0. Set remote veth down which will cause local veth to go into a no 9# carrier state. Depending on the test check the ARP/ND table: 10# 11# {arp,ndisc}_evict_nocarrier=1 should contain no ARP/ND after no carrier 12# {arp,ndisc}_evict_nocarrer=0 should still contain the single ARP/ND entry 13# 14 15readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" 16readonly V4_ADDR0=10.0.10.1 17readonly V4_ADDR1=10.0.10.2 18readonly V6_ADDR0=2001:db8:91::1 19readonly V6_ADDR1=2001:db8:91::2 20nsid=100 21ret=0 22 23cleanup_v6() 24{ 25 ip netns del me 26 ip netns del peer 27 28 sysctl -w net.ipv6.conf.veth1.ndisc_evict_nocarrier=1 >/dev/null 2>&1 29 sysctl -w net.ipv6.conf.all.ndisc_evict_nocarrier=1 >/dev/null 2>&1 30} 31 32create_ns() 33{ 34 local n=${1} 35 36 ip netns del ${n} 2>/dev/null 37 38 ip netns add ${n} 39 ip netns set ${n} $((nsid++)) 40 ip -netns ${n} link set lo up 41} 42 43 44setup_v6() { 45 create_ns me 46 create_ns peer 47 48 IP="ip -netns me" 49 50 $IP li add veth1 type veth peer name veth2 51 $IP li set veth1 up 52 $IP -6 addr add $V6_ADDR0/64 dev veth1 nodad 53 $IP li set veth2 netns peer up 54 ip -netns peer -6 addr add $V6_ADDR1/64 dev veth2 nodad 55 56 ip netns exec me sysctl -w $1 >/dev/null 2>&1 57 58 # Establish an ND cache entry 59 ip netns exec me ping -6 -c1 -Iveth1 $V6_ADDR1 >/dev/null 2>&1 60 # Should have the veth1 entry in ND table 61 ip netns exec me ip -6 neigh get $V6_ADDR1 dev veth1 >/dev/null 2>&1 62 if [ $? -ne 0 ]; then 63 cleanup_v6 64 echo "failed" 65 exit 1 66 fi 67 68 # Set veth2 down, which will put veth1 in NOCARRIER state 69 ip netns exec peer ip link set veth2 down 70} 71 72setup_v4() { 73 ip netns add "${PEER_NS}" 74 ip link add name veth0 type veth peer name veth1 75 ip link set dev veth0 up 76 ip link set dev veth1 netns "${PEER_NS}" 77 ip netns exec "${PEER_NS}" ip link set dev veth1 up 78 ip addr add $V4_ADDR0/24 dev veth0 79 ip netns exec "${PEER_NS}" ip addr add $V4_ADDR1/24 dev veth1 80 ip netns exec ${PEER_NS} ip route add default via $V4_ADDR1 dev veth1 81 ip route add default via $V4_ADDR0 dev veth0 82 83 sysctl -w "$1" >/dev/null 2>&1 84 85 # Establish an ARP cache entry 86 ping -c1 -I veth0 $V4_ADDR1 -q >/dev/null 2>&1 87 # Should have the veth1 entry in ARP table 88 ip neigh get $V4_ADDR1 dev veth0 >/dev/null 2>&1 89 if [ $? -ne 0 ]; then 90 cleanup_v4 91 echo "failed" 92 exit 1 93 fi 94 95 # Set veth1 down, which will put veth0 in NOCARRIER state 96 ip netns exec "${PEER_NS}" ip link set veth1 down 97} 98 99cleanup_v4() { 100 ip neigh flush dev veth0 101 ip link del veth0 102 local -r ns="$(ip netns list|grep $PEER_NS)" 103 [ -n "$ns" ] && ip netns del $ns 2>/dev/null 104 105 sysctl -w net.ipv4.conf.veth0.arp_evict_nocarrier=1 >/dev/null 2>&1 106 sysctl -w net.ipv4.conf.all.arp_evict_nocarrier=1 >/dev/null 2>&1 107} 108 109# Run test when arp_evict_nocarrier = 1 (default). 110run_arp_evict_nocarrier_enabled() { 111 echo "run arp_evict_nocarrier=1 test" 112 setup_v4 "net.ipv4.conf.veth0.arp_evict_nocarrier=1" 113 114 # ARP table should be empty 115 ip neigh get $V4_ADDR1 dev veth0 >/dev/null 2>&1 116 117 if [ $? -eq 0 ];then 118 echo "failed" 119 ret=1 120 else 121 echo "ok" 122 fi 123 124 cleanup_v4 125} 126 127# Run test when arp_evict_nocarrier = 0 128run_arp_evict_nocarrier_disabled() { 129 echo "run arp_evict_nocarrier=0 test" 130 setup_v4 "net.ipv4.conf.veth0.arp_evict_nocarrier=0" 131 132 # ARP table should still contain the entry 133 ip neigh get $V4_ADDR1 dev veth0 >/dev/null 2>&1 134 135 if [ $? -eq 0 ];then 136 echo "ok" 137 else 138 echo "failed" 139 ret=1 140 fi 141 142 cleanup_v4 143} 144 145run_arp_evict_nocarrier_disabled_all() { 146 echo "run all.arp_evict_nocarrier=0 test" 147 setup_v4 "net.ipv4.conf.all.arp_evict_nocarrier=0" 148 149 # ARP table should still contain the entry 150 ip neigh get $V4_ADDR1 dev veth0 >/dev/null 2>&1 151 152 if [ $? -eq 0 ];then 153 echo "ok" 154 else 155 echo "failed" 156 fi 157 158 cleanup_v4 159} 160 161run_ndisc_evict_nocarrier_enabled() { 162 echo "run ndisc_evict_nocarrier=1 test" 163 164 setup_v6 "net.ipv6.conf.veth1.ndisc_evict_nocarrier=1" 165 166 ip netns exec me ip -6 neigh get $V6_ADDR1 dev veth1 >/dev/null 2>&1 167 168 if [ $? -eq 0 ];then 169 echo "failed" 170 ret=1 171 else 172 echo "ok" 173 fi 174 175 cleanup_v6 176} 177 178run_ndisc_evict_nocarrier_disabled() { 179 echo "run ndisc_evict_nocarrier=0 test" 180 181 setup_v6 "net.ipv6.conf.veth1.ndisc_evict_nocarrier=0" 182 183 ip netns exec me ip -6 neigh get $V6_ADDR1 dev veth1 >/dev/null 2>&1 184 185 if [ $? -eq 0 ];then 186 echo "ok" 187 else 188 echo "failed" 189 ret=1 190 fi 191 192 cleanup_v6 193} 194 195run_ndisc_evict_nocarrier_disabled_all() { 196 echo "run all.ndisc_evict_nocarrier=0 test" 197 198 setup_v6 "net.ipv6.conf.all.ndisc_evict_nocarrier=0" 199 200 ip netns exec me ip -6 neigh get $V6_ADDR1 dev veth1 >/dev/null 2>&1 201 202 if [ $? -eq 0 ];then 203 echo "ok" 204 else 205 echo "failed" 206 ret=1 207 fi 208 209 cleanup_v6 210} 211 212run_all_tests() { 213 run_arp_evict_nocarrier_enabled 214 run_arp_evict_nocarrier_disabled 215 run_arp_evict_nocarrier_disabled_all 216 run_ndisc_evict_nocarrier_enabled 217 run_ndisc_evict_nocarrier_disabled 218 run_ndisc_evict_nocarrier_disabled_all 219} 220 221if [ "$(id -u)" -ne 0 ];then 222 echo "SKIP: Need root privileges" 223 exit $ksft_skip; 224fi 225 226run_all_tests 227exit $ret 228