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