]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - tools/testing/selftests/net/fib_tests.sh
Merge tag 'kvm-x86-mmu-6.7' of https://github.com/kvm-x86/linux into HEAD
[thirdparty/kernel/stable.git] / tools / testing / selftests / net / fib_tests.sh
CommitLineData
607bd2e5
IS
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# This test is for checking IPv4 and IPv6 FIB behavior in response to
5# different events.
6
7ret=0
57aefc7c
SKSO
8# Kselftest framework requirement - SKIP code is 4.
9ksft_skip=4
607bd2e5 10
d69faad7 11# all tests in this script. Can be overridden with -t option
a63e10da
KFL
12TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
13 ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics \
14 ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
8ae9efb8
SY
15 ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
16 ipv4_mpath_list ipv6_mpath_list"
228ddb33 17
1c7447b4
DA
18VERBOSE=0
19PAUSE_ON_FAIL=no
7df15e6c 20PAUSE=no
a63e10da
KFL
21IP="$(which ip) -netns ns1"
22NS_EXEC="$(which ip) netns exec ns1"
607bd2e5 23
0360894a
DA
24which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
25
1056691b 26log_test()
607bd2e5 27{
1056691b
DA
28 local rc=$1
29 local expected=$2
30 local msg="$3"
31
32 if [ ${rc} -eq ${expected} ]; then
654d3a78 33 printf " TEST: %-60s [ OK ]\n" "${msg}"
37ce42c1 34 nsuccess=$((nsuccess+1))
1056691b 35 else
607bd2e5 36 ret=1
37ce42c1 37 nfail=$((nfail+1))
654d3a78 38 printf " TEST: %-60s [FAIL]\n" "${msg}"
1056691b
DA
39 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
40 echo
41 echo "hit enter to continue, 'q' to quit"
42 read a
43 [ "$a" = "q" ] && exit 1
44 fi
607bd2e5 45 fi
7df15e6c
DA
46
47 if [ "${PAUSE}" = "yes" ]; then
48 echo
49 echo "hit enter to continue, 'q' to quit"
50 read a
51 [ "$a" = "q" ] && exit 1
52 fi
607bd2e5
IS
53}
54
ee395a5e 55setup()
607bd2e5 56{
ee395a5e 57 set -e
a0e11da7 58 ip netns add ns1
228ddb33 59 ip netns set ns1 auto
171a4871 60 $IP link set dev lo up
a0e11da7
DA
61 ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
62 ip netns exec ns1 sysctl -qw net.ipv6.conf.all.forwarding=1
ee395a5e 63
171a4871
DA
64 $IP link add dummy0 type dummy
65 $IP link set dev dummy0 up
66 $IP address add 198.51.100.1/24 dev dummy0
67 $IP -6 address add 2001:db8:1::1/64 dev dummy0
ee395a5e
DA
68 set +e
69
70}
607bd2e5 71
ee395a5e
DA
72cleanup()
73{
171a4871 74 $IP link del dev dummy0 &> /dev/null
d226b1df 75 ip netns del ns1 &> /dev/null
a0e11da7 76 ip netns del ns2 &> /dev/null
607bd2e5
IS
77}
78
654d3a78
DA
79get_linklocal()
80{
81 local dev=$1
82 local addr
83
84 addr=$($IP -6 -br addr show dev ${dev} | \
85 awk '{
86 for (i = 3; i <= NF; ++i) {
87 if ($i ~ /^fe80/)
88 print $i
89 }
90 }'
91 )
92 addr=${addr/\/*}
93
94 [ -z "$addr" ] && return 1
95
96 echo $addr
97
98 return 0
99}
100
607bd2e5
IS
101fib_unreg_unicast_test()
102{
1056691b
DA
103 echo
104 echo "Single path route test"
607bd2e5 105
ee395a5e 106 setup
607bd2e5 107
1056691b 108 echo " Start point"
171a4871 109 $IP route get fibmatch 198.51.100.2 &> /dev/null
1056691b 110 log_test $? 0 "IPv4 fibmatch"
171a4871 111 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
1056691b 112 log_test $? 0 "IPv6 fibmatch"
607bd2e5 113
1056691b 114 set -e
171a4871 115 $IP link del dev dummy0
1056691b 116 set +e
607bd2e5 117
1056691b 118 echo " Nexthop device deleted"
171a4871 119 $IP route get fibmatch 198.51.100.2 &> /dev/null
1056691b 120 log_test $? 2 "IPv4 fibmatch - no route"
171a4871 121 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
1056691b 122 log_test $? 2 "IPv6 fibmatch - no route"
607bd2e5 123
ee395a5e 124 cleanup
607bd2e5
IS
125}
126
127fib_unreg_multipath_test()
128{
607bd2e5 129
1056691b
DA
130 echo
131 echo "Multipath route test"
132
ee395a5e 133 setup
607bd2e5 134
ee395a5e 135 set -e
171a4871
DA
136 $IP link add dummy1 type dummy
137 $IP link set dev dummy1 up
138 $IP address add 192.0.2.1/24 dev dummy1
139 $IP -6 address add 2001:db8:2::1/64 dev dummy1
607bd2e5 140
171a4871 141 $IP route add 203.0.113.0/24 \
607bd2e5
IS
142 nexthop via 198.51.100.2 dev dummy0 \
143 nexthop via 192.0.2.2 dev dummy1
171a4871 144 $IP -6 route add 2001:db8:3::/64 \
607bd2e5
IS
145 nexthop via 2001:db8:1::2 dev dummy0 \
146 nexthop via 2001:db8:2::2 dev dummy1
1056691b 147 set +e
607bd2e5 148
1056691b 149 echo " Start point"
171a4871 150 $IP route get fibmatch 203.0.113.1 &> /dev/null
1056691b 151 log_test $? 0 "IPv4 fibmatch"
171a4871 152 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
1056691b 153 log_test $? 0 "IPv6 fibmatch"
607bd2e5 154
1056691b 155 set -e
171a4871 156 $IP link del dev dummy0
1056691b 157 set +e
607bd2e5 158
1056691b 159 echo " One nexthop device deleted"
171a4871 160 $IP route get fibmatch 203.0.113.1 &> /dev/null
1056691b
DA
161 log_test $? 2 "IPv4 - multipath route removed on delete"
162
171a4871 163 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
607bd2e5 164 # In IPv6 we do not flush the entire multipath route.
1056691b 165 log_test $? 0 "IPv6 - multipath down to single path"
607bd2e5 166
1056691b 167 set -e
171a4871 168 $IP link del dev dummy1
1056691b 169 set +e
607bd2e5 170
1056691b 171 echo " Second nexthop device deleted"
171a4871 172 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
1056691b 173 log_test $? 2 "IPv6 - no route"
607bd2e5 174
ee395a5e 175 cleanup
607bd2e5
IS
176}
177
178fib_unreg_test()
179{
607bd2e5
IS
180 fib_unreg_unicast_test
181 fib_unreg_multipath_test
182}
183
5adb7683
IS
184fib_down_unicast_test()
185{
1056691b
DA
186 echo
187 echo "Single path, admin down"
5adb7683 188
ee395a5e 189 setup
5adb7683 190
1056691b 191 echo " Start point"
171a4871 192 $IP route get fibmatch 198.51.100.2 &> /dev/null
1056691b 193 log_test $? 0 "IPv4 fibmatch"
171a4871 194 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
1056691b 195 log_test $? 0 "IPv6 fibmatch"
5adb7683 196
1056691b 197 set -e
171a4871 198 $IP link set dev dummy0 down
1056691b 199 set +e
5adb7683 200
1056691b 201 echo " Route deleted on down"
171a4871 202 $IP route get fibmatch 198.51.100.2 &> /dev/null
1056691b 203 log_test $? 2 "IPv4 fibmatch"
171a4871 204 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
1056691b 205 log_test $? 2 "IPv6 fibmatch"
5adb7683 206
ee395a5e 207 cleanup
5adb7683
IS
208}
209
210fib_down_multipath_test_do()
211{
212 local down_dev=$1
213 local up_dev=$2
214
171a4871 215 $IP route get fibmatch 203.0.113.1 \
5adb7683 216 oif $down_dev &> /dev/null
1056691b 217 log_test $? 2 "IPv4 fibmatch on down device"
171a4871 218 $IP -6 route get fibmatch 2001:db8:3::1 \
5adb7683 219 oif $down_dev &> /dev/null
1056691b 220 log_test $? 2 "IPv6 fibmatch on down device"
5adb7683 221
171a4871 222 $IP route get fibmatch 203.0.113.1 \
5adb7683 223 oif $up_dev &> /dev/null
1056691b 224 log_test $? 0 "IPv4 fibmatch on up device"
171a4871 225 $IP -6 route get fibmatch 2001:db8:3::1 \
5adb7683 226 oif $up_dev &> /dev/null
1056691b 227 log_test $? 0 "IPv6 fibmatch on up device"
5adb7683 228
171a4871 229 $IP route get fibmatch 203.0.113.1 | \
5adb7683 230 grep $down_dev | grep -q "dead linkdown"
1056691b 231 log_test $? 0 "IPv4 flags on down device"
171a4871 232 $IP -6 route get fibmatch 2001:db8:3::1 | \
5adb7683 233 grep $down_dev | grep -q "dead linkdown"
1056691b 234 log_test $? 0 "IPv6 flags on down device"
5adb7683 235
171a4871 236 $IP route get fibmatch 203.0.113.1 | \
5adb7683 237 grep $up_dev | grep -q "dead linkdown"
1056691b 238 log_test $? 1 "IPv4 flags on up device"
171a4871 239 $IP -6 route get fibmatch 2001:db8:3::1 | \
5adb7683 240 grep $up_dev | grep -q "dead linkdown"
1056691b 241 log_test $? 1 "IPv6 flags on up device"
5adb7683
IS
242}
243
244fib_down_multipath_test()
245{
1056691b
DA
246 echo
247 echo "Admin down multipath"
5adb7683 248
ee395a5e 249 setup
5adb7683 250
ee395a5e 251 set -e
171a4871
DA
252 $IP link add dummy1 type dummy
253 $IP link set dev dummy1 up
5adb7683 254
171a4871
DA
255 $IP address add 192.0.2.1/24 dev dummy1
256 $IP -6 address add 2001:db8:2::1/64 dev dummy1
5adb7683 257
171a4871 258 $IP route add 203.0.113.0/24 \
5adb7683
IS
259 nexthop via 198.51.100.2 dev dummy0 \
260 nexthop via 192.0.2.2 dev dummy1
171a4871 261 $IP -6 route add 2001:db8:3::/64 \
5adb7683
IS
262 nexthop via 2001:db8:1::2 dev dummy0 \
263 nexthop via 2001:db8:2::2 dev dummy1
1056691b 264 set +e
5adb7683 265
1056691b 266 echo " Verify start point"
171a4871 267 $IP route get fibmatch 203.0.113.1 &> /dev/null
1056691b
DA
268 log_test $? 0 "IPv4 fibmatch"
269
171a4871 270 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
1056691b 271 log_test $? 0 "IPv6 fibmatch"
5adb7683 272
1056691b 273 set -e
171a4871 274 $IP link set dev dummy0 down
1056691b 275 set +e
5adb7683 276
1056691b 277 echo " One device down, one up"
5adb7683
IS
278 fib_down_multipath_test_do "dummy0" "dummy1"
279
1056691b 280 set -e
171a4871
DA
281 $IP link set dev dummy0 up
282 $IP link set dev dummy1 down
1056691b 283 set +e
5adb7683 284
1056691b 285 echo " Other device down and up"
5adb7683
IS
286 fib_down_multipath_test_do "dummy1" "dummy0"
287
1056691b 288 set -e
171a4871 289 $IP link set dev dummy0 down
1056691b 290 set +e
5adb7683 291
1056691b 292 echo " Both devices down"
171a4871 293 $IP route get fibmatch 203.0.113.1 &> /dev/null
1056691b 294 log_test $? 2 "IPv4 fibmatch"
171a4871 295 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
1056691b 296 log_test $? 2 "IPv6 fibmatch"
5adb7683 297
171a4871 298 $IP link del dev dummy1
ee395a5e 299 cleanup
5adb7683
IS
300}
301
302fib_down_test()
303{
5adb7683
IS
304 fib_down_unicast_test
305 fib_down_multipath_test
306}
307
1056691b 308# Local routes should not be affected when carrier changes.
82e45b6f
IS
309fib_carrier_local_test()
310{
1056691b
DA
311 echo
312 echo "Local carrier tests - single path"
82e45b6f 313
ee395a5e 314 setup
82e45b6f 315
ee395a5e 316 set -e
171a4871 317 $IP link set dev dummy0 carrier on
1056691b 318 set +e
82e45b6f 319
1056691b 320 echo " Start point"
171a4871 321 $IP route get fibmatch 198.51.100.1 &> /dev/null
1056691b 322 log_test $? 0 "IPv4 fibmatch"
171a4871 323 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
1056691b 324 log_test $? 0 "IPv6 fibmatch"
82e45b6f 325
171a4871 326 $IP route get fibmatch 198.51.100.1 | \
82e45b6f 327 grep -q "linkdown"
1056691b 328 log_test $? 1 "IPv4 - no linkdown flag"
171a4871 329 $IP -6 route get fibmatch 2001:db8:1::1 | \
82e45b6f 330 grep -q "linkdown"
1056691b 331 log_test $? 1 "IPv6 - no linkdown flag"
82e45b6f 332
1056691b 333 set -e
171a4871 334 $IP link set dev dummy0 carrier off
e2ba732a 335 sleep 1
1056691b 336 set +e
82e45b6f 337
1056691b 338 echo " Carrier off on nexthop"
171a4871 339 $IP route get fibmatch 198.51.100.1 &> /dev/null
1056691b 340 log_test $? 0 "IPv4 fibmatch"
171a4871 341 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
1056691b 342 log_test $? 0 "IPv6 fibmatch"
82e45b6f 343
171a4871 344 $IP route get fibmatch 198.51.100.1 | \
82e45b6f 345 grep -q "linkdown"
1056691b 346 log_test $? 1 "IPv4 - linkdown flag set"
171a4871 347 $IP -6 route get fibmatch 2001:db8:1::1 | \
82e45b6f 348 grep -q "linkdown"
1056691b 349 log_test $? 1 "IPv6 - linkdown flag set"
82e45b6f 350
1056691b 351 set -e
171a4871
DA
352 $IP address add 192.0.2.1/24 dev dummy0
353 $IP -6 address add 2001:db8:2::1/64 dev dummy0
1056691b 354 set +e
82e45b6f 355
1056691b 356 echo " Route to local address with carrier down"
171a4871 357 $IP route get fibmatch 192.0.2.1 &> /dev/null
1056691b 358 log_test $? 0 "IPv4 fibmatch"
171a4871 359 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
1056691b 360 log_test $? 0 "IPv6 fibmatch"
82e45b6f 361
171a4871 362 $IP route get fibmatch 192.0.2.1 | \
82e45b6f 363 grep -q "linkdown"
1056691b 364 log_test $? 1 "IPv4 linkdown flag set"
171a4871 365 $IP -6 route get fibmatch 2001:db8:2::1 | \
82e45b6f 366 grep -q "linkdown"
1056691b 367 log_test $? 1 "IPv6 linkdown flag set"
82e45b6f 368
ee395a5e 369 cleanup
82e45b6f
IS
370}
371
372fib_carrier_unicast_test()
373{
374 ret=0
375
1056691b
DA
376 echo
377 echo "Single path route carrier test"
378
ee395a5e 379 setup
82e45b6f 380
1056691b 381 set -e
171a4871 382 $IP link set dev dummy0 carrier on
1056691b 383 set +e
82e45b6f 384
1056691b 385 echo " Start point"
171a4871 386 $IP route get fibmatch 198.51.100.2 &> /dev/null
1056691b 387 log_test $? 0 "IPv4 fibmatch"
171a4871 388 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
1056691b 389 log_test $? 0 "IPv6 fibmatch"
82e45b6f 390
171a4871 391 $IP route get fibmatch 198.51.100.2 | \
82e45b6f 392 grep -q "linkdown"
1056691b 393 log_test $? 1 "IPv4 no linkdown flag"
171a4871 394 $IP -6 route get fibmatch 2001:db8:1::2 | \
82e45b6f 395 grep -q "linkdown"
1056691b 396 log_test $? 1 "IPv6 no linkdown flag"
82e45b6f 397
1056691b 398 set -e
171a4871 399 $IP link set dev dummy0 carrier off
af548a27 400 sleep 1
1056691b 401 set +e
82e45b6f 402
1056691b 403 echo " Carrier down"
171a4871 404 $IP route get fibmatch 198.51.100.2 &> /dev/null
1056691b 405 log_test $? 0 "IPv4 fibmatch"
171a4871 406 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
1056691b 407 log_test $? 0 "IPv6 fibmatch"
82e45b6f 408
171a4871 409 $IP route get fibmatch 198.51.100.2 | \
82e45b6f 410 grep -q "linkdown"
1056691b 411 log_test $? 0 "IPv4 linkdown flag set"
171a4871 412 $IP -6 route get fibmatch 2001:db8:1::2 | \
82e45b6f 413 grep -q "linkdown"
1056691b 414 log_test $? 0 "IPv6 linkdown flag set"
82e45b6f 415
1056691b 416 set -e
171a4871
DA
417 $IP address add 192.0.2.1/24 dev dummy0
418 $IP -6 address add 2001:db8:2::1/64 dev dummy0
1056691b 419 set +e
82e45b6f 420
1056691b 421 echo " Second address added with carrier down"
171a4871 422 $IP route get fibmatch 192.0.2.2 &> /dev/null
1056691b 423 log_test $? 0 "IPv4 fibmatch"
171a4871 424 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
1056691b 425 log_test $? 0 "IPv6 fibmatch"
82e45b6f 426
171a4871 427 $IP route get fibmatch 192.0.2.2 | \
82e45b6f 428 grep -q "linkdown"
1056691b 429 log_test $? 0 "IPv4 linkdown flag set"
171a4871 430 $IP -6 route get fibmatch 2001:db8:2::2 | \
82e45b6f 431 grep -q "linkdown"
1056691b 432 log_test $? 0 "IPv6 linkdown flag set"
82e45b6f 433
ee395a5e 434 cleanup
82e45b6f
IS
435}
436
437fib_carrier_test()
438{
82e45b6f
IS
439 fib_carrier_local_test
440 fib_carrier_unicast_test
441}
442
adb701d6
CW
443fib_rp_filter_test()
444{
445 echo
446 echo "IPv4 rp_filter tests"
447
448 setup
449
450 set -e
f6071e5e
PY
451 ip netns add ns2
452 ip netns set ns2 auto
453
454 ip -netns ns2 link set dev lo up
455
456 $IP link add name veth1 type veth peer name veth2
457 $IP link set dev veth2 netns ns2
458 $IP address add 192.0.2.1/24 dev veth1
459 ip -netns ns2 address add 192.0.2.1/24 dev veth2
460 $IP link set dev veth1 up
461 ip -netns ns2 link set dev veth2 up
462
adb701d6 463 $IP link set dev lo address 52:54:00:6a:c7:5e
f6071e5e
PY
464 $IP link set dev veth1 address 52:54:00:6a:c7:5e
465 ip -netns ns2 link set dev lo address 52:54:00:6a:c7:5e
466 ip -netns ns2 link set dev veth2 address 52:54:00:6a:c7:5e
467
468 # 1. (ns2) redirect lo's egress to veth2's egress
469 ip netns exec ns2 tc qdisc add dev lo parent root handle 1: fq_codel
470 ip netns exec ns2 tc filter add dev lo parent 1: protocol arp basic \
471 action mirred egress redirect dev veth2
472 ip netns exec ns2 tc filter add dev lo parent 1: protocol ip basic \
473 action mirred egress redirect dev veth2
474
475 # 2. (ns1) redirect veth1's ingress to lo's ingress
476 $NS_EXEC tc qdisc add dev veth1 ingress
477 $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \
478 action mirred ingress redirect dev lo
479 $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \
480 action mirred ingress redirect dev lo
481
482 # 3. (ns1) redirect lo's egress to veth1's egress
483 $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel
484 $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \
485 action mirred egress redirect dev veth1
486 $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \
487 action mirred egress redirect dev veth1
488
489 # 4. (ns2) redirect veth2's ingress to lo's ingress
490 ip netns exec ns2 tc qdisc add dev veth2 ingress
491 ip netns exec ns2 tc filter add dev veth2 ingress protocol arp basic \
492 action mirred ingress redirect dev lo
493 ip netns exec ns2 tc filter add dev veth2 ingress protocol ip basic \
494 action mirred ingress redirect dev lo
495
adb701d6
CW
496 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
497 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
498 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
f6071e5e
PY
499 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1
500 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.accept_local=1
501 ip netns exec ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1
adb701d6
CW
502 set +e
503
f6071e5e 504 run_cmd "ip netns exec ns2 ping -w1 -c1 192.0.2.1"
adb701d6
CW
505 log_test $? 0 "rp_filter passes local packets"
506
f6071e5e 507 run_cmd "ip netns exec ns2 ping -w1 -c1 127.0.0.1"
adb701d6
CW
508 log_test $? 0 "rp_filter passes loopback packets"
509
510 cleanup
511}
512
654d3a78
DA
513################################################################################
514# Tests on nexthop spec
515
516# run 'ip route add' with given spec
517add_rt()
518{
519 local desc="$1"
520 local erc=$2
521 local vrf=$3
522 local pfx=$4
523 local gw=$5
524 local dev=$6
525 local cmd out rc
526
527 [ "$vrf" = "-" ] && vrf="default"
528 [ -n "$gw" ] && gw="via $gw"
529 [ -n "$dev" ] && dev="dev $dev"
530
531 cmd="$IP route add vrf $vrf $pfx $gw $dev"
532 if [ "$VERBOSE" = "1" ]; then
533 printf "\n COMMAND: $cmd\n"
534 fi
535
536 out=$(eval $cmd 2>&1)
537 rc=$?
538 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
539 echo " $out"
540 fi
541 log_test $rc $erc "$desc"
542}
543
544fib4_nexthop()
545{
546 echo
547 echo "IPv4 nexthop tests"
548
549 echo "<<< write me >>>"
550}
551
552fib6_nexthop()
553{
554 local lldummy=$(get_linklocal dummy0)
555 local llv1=$(get_linklocal dummy0)
556
557 if [ -z "$lldummy" ]; then
558 echo "Failed to get linklocal address for dummy0"
559 return 1
560 fi
561 if [ -z "$llv1" ]; then
562 echo "Failed to get linklocal address for veth1"
563 return 1
564 fi
565
566 echo
567 echo "IPv6 nexthop tests"
568
569 add_rt "Directly connected nexthop, unicast address" 0 \
570 - 2001:db8:101::/64 2001:db8:1::2
571 add_rt "Directly connected nexthop, unicast address with device" 0 \
572 - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
573 add_rt "Gateway is linklocal address" 0 \
574 - 2001:db8:103::1/64 $llv1 "veth0"
575
576 # fails because LL address requires a device
577 add_rt "Gateway is linklocal address, no device" 2 \
578 - 2001:db8:104::1/64 $llv1
579
580 # local address can not be a gateway
581 add_rt "Gateway can not be local unicast address" 2 \
582 - 2001:db8:105::/64 2001:db8:1::1
583 add_rt "Gateway can not be local unicast address, with device" 2 \
584 - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
585 add_rt "Gateway can not be a local linklocal address" 2 \
586 - 2001:db8:107::1/64 $lldummy "dummy0"
587
588 # VRF tests
589 add_rt "Gateway can be local address in a VRF" 0 \
590 - 2001:db8:108::/64 2001:db8:51::2
591 add_rt "Gateway can be local address in a VRF, with device" 0 \
592 - 2001:db8:109::/64 2001:db8:51::2 "veth0"
593 add_rt "Gateway can be local linklocal address in a VRF" 0 \
594 - 2001:db8:110::1/64 $llv1 "veth0"
595
596 add_rt "Redirect to VRF lookup" 0 \
597 - 2001:db8:111::/64 "" "red"
598
599 add_rt "VRF route, gateway can be local address in default VRF" 0 \
600 red 2001:db8:112::/64 2001:db8:51::1
601
602 # local address in same VRF fails
603 add_rt "VRF route, gateway can not be a local address" 2 \
604 red 2001:db8:113::1/64 2001:db8:2::1
605 add_rt "VRF route, gateway can not be a local addr with device" 2 \
606 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
607}
608
609# Default VRF:
610# dummy0 - 198.51.100.1/24 2001:db8:1::1/64
611# veth0 - 192.0.2.1/24 2001:db8:51::1/64
612#
613# VRF red:
614# dummy1 - 192.168.2.1/24 2001:db8:2::1/64
615# veth1 - 192.0.2.2/24 2001:db8:51::2/64
616#
617# [ dummy0 veth0 ]--[ veth1 dummy1 ]
618
619fib_nexthop_test()
620{
621 setup
622
623 set -e
624
625 $IP -4 rule add pref 32765 table local
626 $IP -4 rule del pref 0
627 $IP -6 rule add pref 32765 table local
628 $IP -6 rule del pref 0
629
630 $IP link add red type vrf table 1
631 $IP link set red up
632 $IP -4 route add vrf red unreachable default metric 4278198272
633 $IP -6 route add vrf red unreachable default metric 4278198272
634
635 $IP link add veth0 type veth peer name veth1
636 $IP link set dev veth0 up
637 $IP address add 192.0.2.1/24 dev veth0
638 $IP -6 address add 2001:db8:51::1/64 dev veth0
639
640 $IP link set dev veth1 vrf red up
641 $IP address add 192.0.2.2/24 dev veth1
642 $IP -6 address add 2001:db8:51::2/64 dev veth1
643
644 $IP link add dummy1 type dummy
645 $IP link set dev dummy1 vrf red up
646 $IP address add 192.168.2.1/24 dev dummy1
647 $IP -6 address add 2001:db8:2::1/64 dev dummy1
648 set +e
649
650 sleep 1
651 fib4_nexthop
652 fib6_nexthop
653
654 (
655 $IP link del dev dummy1
656 $IP link del veth0
657 $IP link del red
658 ) 2>/dev/null
659 cleanup
660}
661
44bd0394
LW
662fib6_notify_test()
663{
664 setup
665
666 echo
667 echo "Fib6 info length calculation in route notify test"
668 set -e
669
670 for i in 10 20 30 40 50 60 70;
671 do
672 $IP link add dummy_$i type dummy
673 $IP link set dev dummy_$i up
674 $IP -6 address add 2001:$i::1/64 dev dummy_$i
675 done
676
677 $NS_EXEC ip monitor route &> errors.txt &
678 sleep 2
679
680 $IP -6 route add 2001::/64 \
681 nexthop via 2001:10::2 dev dummy_10 \
682 nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \
683 nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \
684 nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \
685 nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \
686 nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \
687 nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70
688
689 set +e
690
691 err=`cat errors.txt |grep "Message too long"`
692 if [ -z "$err" ];then
693 ret=0
694 else
695 ret=1
696 fi
697
698 log_test $ret 0 "ipv6 route add notify"
699
700 { kill %% && wait %%; } 2>/dev/null
701
702 #rm errors.txt
703
704 cleanup &> /dev/null
705}
706
707
708fib_notify_test()
709{
710 setup
711
712 echo
713 echo "Fib4 info length calculation in route notify test"
714
715 set -e
716
717 for i in 10 20 30 40 50 60 70;
718 do
719 $IP link add dummy_$i type dummy
720 $IP link set dev dummy_$i up
721 $IP address add 20.20.$i.2/24 dev dummy_$i
722 done
723
724 $NS_EXEC ip monitor route &> errors.txt &
725 sleep 2
726
727 $IP route add 10.0.0.0/24 \
728 nexthop via 20.20.10.1 dev dummy_10 \
729 nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \
730 nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \
731 nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \
732 nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \
733 nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \
734 nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70
735
736 set +e
737
738 err=`cat errors.txt |grep "Message too long"`
739 if [ -z "$err" ];then
740 ret=0
741 else
742 ret=1
743 fi
744
745 log_test $ret 0 "ipv4 route add notify"
746
747 { kill %% && wait %%; } 2>/dev/null
748
749 rm errors.txt
750
751 cleanup &> /dev/null
752}
753
a63e10da
KFL
754fib6_gc_test()
755{
756 setup
757
758 echo
759 echo "Fib6 garbage collection test"
760 set -e
761
762 EXPIRE=3
763
764 # Check expiration of routes every $EXPIRE seconds (GC)
765 $NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE
766
767 $IP link add dummy_10 type dummy
768 $IP link set dev dummy_10 up
769 $IP -6 address add 2001:10::1/64 dev dummy_10
770
771 $NS_EXEC sysctl -wq net.ipv6.route.flush=1
772
773 # Temporary routes
774 for i in $(seq 1 1000); do
775 # Expire route after $EXPIRE seconds
776 $IP -6 route add 2001:20::$i \
777 via 2001:10::2 dev dummy_10 expires $EXPIRE
778 done
779 sleep $(($EXPIRE * 2))
780 N_EXP_SLEEP=$($IP -6 route list |grep expires|wc -l)
781 if [ $N_EXP_SLEEP -ne 0 ]; then
782 echo "FAIL: expected 0 routes with expires, got $N_EXP_SLEEP"
783 ret=1
784 else
785 ret=0
786 fi
787
788 # Permanent routes
789 for i in $(seq 1 5000); do
790 $IP -6 route add 2001:30::$i \
791 via 2001:10::2 dev dummy_10
792 done
793 # Temporary routes
794 for i in $(seq 1 1000); do
795 # Expire route after $EXPIRE seconds
796 $IP -6 route add 2001:20::$i \
797 via 2001:10::2 dev dummy_10 expires $EXPIRE
798 done
799 sleep $(($EXPIRE * 2))
800 N_EXP_SLEEP=$($IP -6 route list |grep expires|wc -l)
801 if [ $N_EXP_SLEEP -ne 0 ]; then
802 echo "FAIL: expected 0 routes with expires," \
803 "got $N_EXP_SLEEP (5000 permanent routes)"
804 ret=1
805 else
806 ret=0
807 fi
808
809 set +e
810
811 log_test $ret 0 "ipv6 route garbage collection"
812
813 cleanup &> /dev/null
814}
815
ca7a03c4
JD
816fib_suppress_test()
817{
2c1dd4c1
DA
818 echo
819 echo "FIB rule with suppress_prefixlength"
820 setup
821
ca7a03c4
JD
822 $IP link add dummy1 type dummy
823 $IP link set dummy1 up
824 $IP -6 route add default dev dummy1
825 $IP -6 rule add table main suppress_prefixlength 0
2c1dd4c1 826 ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1
ca7a03c4
JD
827 $IP -6 rule del table main suppress_prefixlength 0
828 $IP link del dummy1
829
830 # If we got here without crashing, we're good.
2c1dd4c1
DA
831 log_test 0 0 "FIB rule suppress test"
832
833 cleanup
ca7a03c4
JD
834}
835
654d3a78 836################################################################################
f9a5a9d8
DA
837# Tests on route add and replace
838
839run_cmd()
840{
841 local cmd="$1"
842 local out
843 local stderr="2>/dev/null"
844
845 if [ "$VERBOSE" = "1" ]; then
846 printf " COMMAND: $cmd\n"
847 stderr=
848 fi
849
850 out=$(eval $cmd $stderr)
851 rc=$?
852 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
853 echo " $out"
854 fi
855
856 [ "$VERBOSE" = "1" ] && echo
857
858 return $rc
859}
860
a5f62298
DA
861check_expected()
862{
863 local out="$1"
864 local expected="$2"
865 local rc=0
866
867 [ "${out}" = "${expected}" ] && return 0
868
869 if [ -z "${out}" ]; then
870 if [ "$VERBOSE" = "1" ]; then
871 printf "\nNo route entry found\n"
872 printf "Expected:\n"
873 printf " ${expected}\n"
874 fi
875 return 1
876 fi
877
878 # tricky way to convert output to 1-line without ip's
879 # messy '\'; this drops all extra white space
880 out=$(echo ${out})
881 if [ "${out}" != "${expected}" ]; then
882 rc=1
883 if [ "${VERBOSE}" = "1" ]; then
884 printf " Unexpected route entry. Have:\n"
885 printf " ${out}\n"
886 printf " Expected:\n"
887 printf " ${expected}\n\n"
888 fi
889 fi
890
891 return $rc
892}
893
f9a5a9d8
DA
894# add route for a prefix, flushing any existing routes first
895# expected to be the first step of a test
896add_route6()
897{
898 local pfx="$1"
899 local nh="$2"
900 local out
901
902 if [ "$VERBOSE" = "1" ]; then
903 echo
904 echo " ##################################################"
905 echo
906 fi
907
908 run_cmd "$IP -6 ro flush ${pfx}"
909 [ $? -ne 0 ] && exit 1
910
911 out=$($IP -6 ro ls match ${pfx})
912 if [ -n "$out" ]; then
913 echo "Failed to flush routes for prefix used for tests."
914 exit 1
915 fi
916
917 run_cmd "$IP -6 ro add ${pfx} ${nh}"
918 if [ $? -ne 0 ]; then
919 echo "Failed to add initial route for test."
920 exit 1
921 fi
922}
923
924# add initial route - used in replace route tests
925add_initial_route6()
926{
927 add_route6 "2001:db8:104::/64" "$1"
928}
929
930check_route6()
931{
a0e11da7 932 local pfx
f9a5a9d8
DA
933 local expected="$1"
934 local out
935 local rc=0
936
a0e11da7
DA
937 set -- $expected
938 pfx=$1
939
f9a5a9d8 940 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')
a5f62298 941 check_expected "${out}" "${expected}"
f9a5a9d8
DA
942}
943
944route_cleanup()
945{
946 $IP li del red 2>/dev/null
947 $IP li del dummy1 2>/dev/null
948 $IP li del veth1 2>/dev/null
949 $IP li del veth3 2>/dev/null
950
951 cleanup &> /dev/null
952}
953
954route_setup()
955{
956 route_cleanup
957 setup
958
959 [ "${VERBOSE}" = "1" ] && set -x
960 set -e
961
a0e11da7 962 ip netns add ns2
228ddb33 963 ip netns set ns2 auto
a0e11da7
DA
964 ip -netns ns2 link set dev lo up
965 ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1
966 ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1
967
f9a5a9d8
DA
968 $IP li add veth1 type veth peer name veth2
969 $IP li add veth3 type veth peer name veth4
970
971 $IP li set veth1 up
972 $IP li set veth3 up
a0e11da7
DA
973 $IP li set veth2 netns ns2 up
974 $IP li set veth4 netns ns2 up
975 ip -netns ns2 li add dummy1 type dummy
976 ip -netns ns2 li set dummy1 up
f9a5a9d8 977
226407dd
DA
978 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad
979 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad
abb1860a 980 $IP addr add 172.16.101.1/24 dev veth1
abb1860a 981 $IP addr add 172.16.103.1/24 dev veth3
a0e11da7 982
226407dd
DA
983 ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad
984 ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad
985 ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad
a0e11da7
DA
986
987 ip -netns ns2 addr add 172.16.101.2/24 dev veth2
988 ip -netns ns2 addr add 172.16.103.2/24 dev veth4
989 ip -netns ns2 addr add 172.16.104.1/24 dev dummy1
abb1860a 990
a5f62298 991 set +e
f9a5a9d8
DA
992}
993
994# assumption is that basic add of a single path route works
995# otherwise just adding an address on an interface is broken
996ipv6_rt_add()
997{
998 local rc
999
1000 echo
1001 echo "IPv6 route add / append tests"
1002
1003 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1004 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1005 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"
1006 log_test $? 2 "Attempt to add duplicate route - gw"
1007
1008 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1009 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1010 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"
1011 log_test $? 2 "Attempt to add duplicate route - dev only"
1012
1013 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1014 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1015 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"
1016 log_test $? 2 "Attempt to add duplicate route - reject route"
1017
f9a5a9d8
DA
1018 # route append with same prefix adds a new route
1019 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1020 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1021 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"
1022 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1023 log_test $? 0 "Append nexthop to existing route - gw"
1024
f9a5a9d8
DA
1025 # insert mpath directly
1026 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1027 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1028 log_test $? 0 "Add multipath route"
1029
1030 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1031 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1032 log_test $? 2 "Attempt to add duplicate multipath route"
1033
1034 # insert of a second route without append but different metric
1035 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
1036 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"
1037 rc=$?
1038 if [ $rc -eq 0 ]; then
1039 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"
1040 rc=$?
1041 fi
1042 log_test $rc 0 "Route add with different metrics"
1043
1044 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"
1045 rc=$?
1046 if [ $rc -eq 0 ]; then
1047 check_route6 "2001:db8:104::/64 via 2001:db8:103::3 dev veth3 metric 256 2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
1048 rc=$?
1049 fi
1050 log_test $rc 0 "Route delete with metric"
1051}
654d3a78 1052
f9a5a9d8 1053ipv6_rt_replace_single()
607bd2e5 1054{
f9a5a9d8
DA
1055 # single path with single path
1056 #
1057 add_initial_route6 "via 2001:db8:101::2"
1058 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"
1059 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
1060 log_test $? 0 "Single path with single path"
1061
1062 # single path with multipath
1063 #
1064 add_initial_route6 "nexthop via 2001:db8:101::2"
1065 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"
1066 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1067 log_test $? 0 "Single path with multipath"
1068
f9a5a9d8
DA
1069 # single path with single path using MULTIPATH attribute
1070 #
1071 add_initial_route6 "via 2001:db8:101::2"
1072 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"
1073 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
1074 log_test $? 0 "Single path with single path via multipath attribute"
1075
1076 # route replace fails - invalid nexthop
1077 add_initial_route6 "via 2001:db8:101::2"
1078 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"
1079 if [ $? -eq 0 ]; then
1080 # previous command is expected to fail so if it returns 0
1081 # that means the test failed.
1082 log_test 0 1 "Invalid nexthop"
a511858c 1083 else
f9a5a9d8
DA
1084 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
1085 log_test $? 0 "Invalid nexthop"
a511858c 1086 fi
f9a5a9d8
DA
1087
1088 # replace non-existent route
1089 # - note use of change versus replace since ip adds NLM_F_CREATE
1090 # for replace
1091 add_initial_route6 "via 2001:db8:101::2"
1092 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"
1093 log_test $? 2 "Single path - replace of non-existent route"
1094}
1095
1096ipv6_rt_replace_mpath()
1097{
1098 # multipath with multipath
1099 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1100 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
1101 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::3 dev veth3 weight 1"
1102 log_test $? 0 "Multipath with multipath"
1103
1104 # multipath with single
1105 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1106 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"
1107 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
1108 log_test $? 0 "Multipath with single path"
1109
1110 # multipath with single
1111 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1112 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"
1113 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
1114 log_test $? 0 "Multipath with single path via multipath attribute"
1115
e404b8c7
BP
1116 # multipath with dev-only
1117 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1118 run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"
1119 check_route6 "2001:db8:104::/64 dev veth1 metric 1024"
1120 log_test $? 0 "Multipath with dev-only"
1121
f9a5a9d8
DA
1122 # route replace fails - invalid nexthop 1
1123 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1124 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"
1125 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1126 log_test $? 0 "Multipath - invalid first nexthop"
1127
1128 # route replace fails - invalid nexthop 2
1129 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1130 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"
1131 check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1132 log_test $? 0 "Multipath - invalid second nexthop"
1133
1134 # multipath non-existent route
1135 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1136 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
1137 log_test $? 2 "Multipath - replace of non-existent route"
1138}
1139
1140ipv6_rt_replace()
1141{
1142 echo
1143 echo "IPv6 route replace tests"
1144
1145 ipv6_rt_replace_single
1146 ipv6_rt_replace_mpath
1147}
1148
b9605161
GN
1149ipv6_rt_dsfield()
1150{
1151 echo
1152 echo "IPv6 route with dsfield tests"
1153
1154 run_cmd "$IP -6 route flush 2001:db8:102::/64"
1155
1156 # IPv6 doesn't support routing based on dsfield
1157 run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"
1158 log_test $? 2 "Reject route with dsfield"
1159}
1160
f9a5a9d8
DA
1161ipv6_route_test()
1162{
1163 route_setup
1164
1165 ipv6_rt_add
1166 ipv6_rt_replace
b9605161 1167 ipv6_rt_dsfield
f9a5a9d8
DA
1168
1169 route_cleanup
607bd2e5
IS
1170}
1171
d69faad7
DA
1172ip_addr_metric_check()
1173{
1174 ip addr help 2>&1 | grep -q metric
1175 if [ $? -ne 0 ]; then
1176 echo "iproute2 command does not support metric for addresses. Skipping test"
1177 return 1
1178 fi
1179
1180 return 0
1181}
1182
1183ipv6_addr_metric_test()
1184{
1185 local rc
1186
1187 echo
1188 echo "IPv6 prefix route tests"
1189
1190 ip_addr_metric_check || return 1
1191
1192 setup
1193
1194 set -e
1195 $IP li add dummy1 type dummy
1196 $IP li add dummy2 type dummy
1197 $IP li set dummy1 up
1198 $IP li set dummy2 up
1199
1200 # default entry is metric 256
1201 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"
1202 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"
1203 set +e
1204
1205 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"
1206 log_test $? 0 "Default metric"
1207
1208 set -e
1209 run_cmd "$IP -6 addr flush dev dummy1"
1210 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"
1211 set +e
1212
1213 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"
1214 log_test $? 0 "User specified metric on first device"
1215
1216 set -e
1217 run_cmd "$IP -6 addr flush dev dummy2"
1218 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"
1219 set +e
1220
1221 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"
1222 log_test $? 0 "User specified metric on second device"
1223
1224 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"
1225 rc=$?
1226 if [ $rc -eq 0 ]; then
1227 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"
1228 rc=$?
1229 fi
1230 log_test $rc 0 "Delete of address on first device"
1231
1232 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"
1233 rc=$?
1234 if [ $rc -eq 0 ]; then
1235 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1236 rc=$?
1237 fi
1238 log_test $rc 0 "Modify metric of address"
1239
1240 # verify prefix route removed on down
a0e11da7 1241 run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"
d69faad7
DA
1242 run_cmd "$IP li set dev dummy2 down"
1243 rc=$?
1244 if [ $rc -eq 0 ]; then
a5f62298
DA
1245 out=$($IP -6 ro ls match 2001:db8:104::/64)
1246 check_expected "${out}" ""
d69faad7
DA
1247 rc=$?
1248 fi
1249 log_test $rc 0 "Prefix route removed on link down"
1250
1251 # verify prefix route re-inserted with assigned metric
1252 run_cmd "$IP li set dev dummy2 up"
1253 rc=$?
1254 if [ $rc -eq 0 ]; then
1255 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1256 rc=$?
1257 fi
1258 log_test $rc 0 "Prefix route with metric on link up"
1259
0d29169a
HL
1260 # verify peer metric added correctly
1261 set -e
1262 run_cmd "$IP -6 addr flush dev dummy2"
1263 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"
1264 set +e
1265
1266 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
1267 log_test $? 0 "Set metric with peer route on local side"
0d29169a
HL
1268 check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
1269 log_test $? 0 "Set metric with peer route on peer side"
1270
1271 set -e
1272 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"
1273 set +e
1274
1275 check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"
1276 log_test $? 0 "Modify metric and peer address on local side"
1277 check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"
1278 log_test $? 0 "Modify metric and peer address on peer side"
1279
d69faad7
DA
1280 $IP li del dummy1
1281 $IP li del dummy2
1282 cleanup
1283}
1284
a0e11da7
DA
1285ipv6_route_metrics_test()
1286{
1287 local rc
1288
1289 echo
1290 echo "IPv6 routes with metrics"
1291
1292 route_setup
1293
1294 #
1295 # single path with metrics
1296 #
1297 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"
1298 rc=$?
1299 if [ $rc -eq 0 ]; then
1300 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"
1301 rc=$?
1302 fi
1303 log_test $rc 0 "Single path route with mtu metric"
1304
1305
1306 #
1307 # multipath via separate routes with metrics
1308 #
1309 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"
1310 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"
1311 rc=$?
1312 if [ $rc -eq 0 ]; then
1313 check_route6 "2001:db8:112::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1314 rc=$?
1315 fi
1316 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"
1317
1318 # second route is coalesced to first to make a multipath route.
1319 # MTU of the second path is hidden from display!
1320 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"
1321 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"
1322 rc=$?
1323 if [ $rc -eq 0 ]; then
1324 check_route6 "2001:db8:113::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1325 rc=$?
1326 fi
1327 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"
1328
1329 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"
1330 if [ $? -eq 0 ]; then
1331 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"
1332 log_test $? 0 " MTU of second leg"
1333 fi
1334
1335 #
1336 # multipath with metrics
1337 #
1338 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1339 rc=$?
1340 if [ $rc -eq 0 ]; then
1341 check_route6 "2001:db8:115::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
1342 rc=$?
1343 fi
1344 log_test $rc 0 "Multipath route with mtu metric"
1345
1346 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300
0360894a 1347 run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"
a0e11da7
DA
1348 log_test $? 0 "Using route with mtu metric"
1349
226407dd
DA
1350 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"
1351 log_test $? 2 "Invalid metric (fails metric_convert)"
1352
a0e11da7
DA
1353 route_cleanup
1354}
1355
abb1860a
DA
1356# add route for a prefix, flushing any existing routes first
1357# expected to be the first step of a test
1358add_route()
1359{
1360 local pfx="$1"
1361 local nh="$2"
1362 local out
1363
1364 if [ "$VERBOSE" = "1" ]; then
1365 echo
1366 echo " ##################################################"
1367 echo
1368 fi
1369
1370 run_cmd "$IP ro flush ${pfx}"
1371 [ $? -ne 0 ] && exit 1
1372
1373 out=$($IP ro ls match ${pfx})
1374 if [ -n "$out" ]; then
1375 echo "Failed to flush routes for prefix used for tests."
1376 exit 1
1377 fi
1378
1379 run_cmd "$IP ro add ${pfx} ${nh}"
1380 if [ $? -ne 0 ]; then
1381 echo "Failed to add initial route for test."
1382 exit 1
1383 fi
1384}
1385
1386# add initial route - used in replace route tests
1387add_initial_route()
1388{
1389 add_route "172.16.104.0/24" "$1"
1390}
1391
1392check_route()
1393{
a0e11da7 1394 local pfx
abb1860a
DA
1395 local expected="$1"
1396 local out
abb1860a 1397
a0e11da7
DA
1398 set -- $expected
1399 pfx=$1
1400 [ "${pfx}" = "unreachable" ] && pfx=$2
1401
abb1860a 1402 out=$($IP ro ls match ${pfx})
a5f62298 1403 check_expected "${out}" "${expected}"
abb1860a
DA
1404}
1405
1406# assumption is that basic add of a single path route works
1407# otherwise just adding an address on an interface is broken
1408ipv4_rt_add()
1409{
1410 local rc
1411
1412 echo
1413 echo "IPv4 route add / append tests"
1414
1415 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1416 add_route "172.16.104.0/24" "via 172.16.101.2"
1417 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"
1418 log_test $? 2 "Attempt to add duplicate route - gw"
1419
1420 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1421 add_route "172.16.104.0/24" "via 172.16.101.2"
1422 run_cmd "$IP ro add 172.16.104.0/24 dev veth3"
1423 log_test $? 2 "Attempt to add duplicate route - dev only"
1424
1425 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1426 add_route "172.16.104.0/24" "via 172.16.101.2"
1427 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1428 log_test $? 2 "Attempt to add duplicate route - reject route"
1429
1430 # iproute2 prepend only sets NLM_F_CREATE
1431 # - adds a new route; does NOT convert existing route to ECMP
1432 add_route "172.16.104.0/24" "via 172.16.101.2"
1433 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"
1434 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3 172.16.104.0/24 via 172.16.101.2 dev veth1"
1435 log_test $? 0 "Add new nexthop for existing prefix"
1436
1437 # route append with same prefix adds a new route
1438 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1439 add_route "172.16.104.0/24" "via 172.16.101.2"
1440 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1441 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.2 dev veth3"
1442 log_test $? 0 "Append nexthop to existing route - gw"
1443
1444 add_route "172.16.104.0/24" "via 172.16.101.2"
1445 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1446 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"
1447 log_test $? 0 "Append nexthop to existing route - dev only"
1448
1449 add_route "172.16.104.0/24" "via 172.16.101.2"
1450 run_cmd "$IP ro append unreachable 172.16.104.0/24"
1451 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"
1452 log_test $? 0 "Append nexthop to existing route - reject route"
1453
1454 run_cmd "$IP ro flush 172.16.104.0/24"
1455 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1456 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1457 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"
1458 log_test $? 0 "Append nexthop to existing reject route - gw"
1459
1460 run_cmd "$IP ro flush 172.16.104.0/24"
1461 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1462 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1463 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"
1464 log_test $? 0 "Append nexthop to existing reject route - dev only"
1465
1466 # insert mpath directly
1467 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1468 check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1469 log_test $? 0 "add multipath route"
1470
1471 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1472 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1473 log_test $? 2 "Attempt to add duplicate multipath route"
1474
1475 # insert of a second route without append but different metric
1476 add_route "172.16.104.0/24" "via 172.16.101.2"
1477 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"
1478 rc=$?
1479 if [ $rc -eq 0 ]; then
1480 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"
1481 rc=$?
1482 fi
1483 log_test $rc 0 "Route add with different metrics"
1484
1485 run_cmd "$IP ro del 172.16.104.0/24 metric 512"
1486 rc=$?
1487 if [ $rc -eq 0 ]; then
1488 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.3 dev veth3 metric 256"
1489 rc=$?
1490 fi
1491 log_test $rc 0 "Route delete with metric"
1492}
1493
1494ipv4_rt_replace_single()
1495{
1496 # single path with single path
1497 #
1498 add_initial_route "via 172.16.101.2"
1499 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"
1500 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1501 log_test $? 0 "Single path with single path"
1502
1503 # single path with multipath
1504 #
1505 add_initial_route "nexthop via 172.16.101.2"
1506 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"
1507 check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1508 log_test $? 0 "Single path with multipath"
1509
1510 # single path with reject
1511 #
1512 add_initial_route "nexthop via 172.16.101.2"
1513 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1514 check_route "unreachable 172.16.104.0/24"
1515 log_test $? 0 "Single path with reject route"
1516
1517 # single path with single path using MULTIPATH attribute
1518 #
1519 add_initial_route "via 172.16.101.2"
1520 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"
1521 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1522 log_test $? 0 "Single path with single path via multipath attribute"
1523
1524 # route replace fails - invalid nexthop
1525 add_initial_route "via 172.16.101.2"
1526 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"
1527 if [ $? -eq 0 ]; then
1528 # previous command is expected to fail so if it returns 0
1529 # that means the test failed.
1530 log_test 0 1 "Invalid nexthop"
1531 else
1532 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"
1533 log_test $? 0 "Invalid nexthop"
1534 fi
1535
1536 # replace non-existent route
1537 # - note use of change versus replace since ip adds NLM_F_CREATE
1538 # for replace
1539 add_initial_route "via 172.16.101.2"
1540 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"
1541 log_test $? 2 "Single path - replace of non-existent route"
1542}
1543
1544ipv4_rt_replace_mpath()
1545{
1546 # multipath with multipath
1547 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1548 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1549 check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.3 dev veth3 weight 1"
1550 log_test $? 0 "Multipath with multipath"
1551
1552 # multipath with single
1553 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1554 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"
1555 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1556 log_test $? 0 "Multipath with single path"
1557
1558 # multipath with single
1559 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1560 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"
1561 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1562 log_test $? 0 "Multipath with single path via multipath attribute"
1563
1564 # multipath with reject
1565 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1566 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1567 check_route "unreachable 172.16.104.0/24"
1568 log_test $? 0 "Multipath with reject route"
1569
1570 # route replace fails - invalid nexthop 1
1571 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1572 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"
1573 check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1574 log_test $? 0 "Multipath - invalid first nexthop"
1575
1576 # route replace fails - invalid nexthop 2
1577 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1578 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"
1579 check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1580 log_test $? 0 "Multipath - invalid second nexthop"
1581
1582 # multipath non-existent route
1583 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1584 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1585 log_test $? 2 "Multipath - replace of non-existent route"
1586}
1587
1588ipv4_rt_replace()
1589{
1590 echo
1591 echo "IPv4 route replace tests"
1592
1593 ipv4_rt_replace_single
1594 ipv4_rt_replace_mpath
1595}
1596
b87b04f5
DA
1597# checks that cached input route on VRF port is deleted
1598# when VRF is deleted
1599ipv4_local_rt_cache()
1600{
1601 run_cmd "ip addr add 10.0.0.1/32 dev lo"
1602 run_cmd "ip netns add test-ns"
1603 run_cmd "ip link add veth-outside type veth peer name veth-inside"
1604 run_cmd "ip link add vrf-100 type vrf table 1100"
1605 run_cmd "ip link set veth-outside master vrf-100"
1606 run_cmd "ip link set veth-inside netns test-ns"
1607 run_cmd "ip link set veth-outside up"
1608 run_cmd "ip link set vrf-100 up"
1609 run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"
1610 run_cmd "ip netns exec test-ns ip link set veth-inside up"
1611 run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside"
1612 run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside"
1613 run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1"
1614 run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1"
1615 run_cmd "ip link delete vrf-100"
1616
1617 # if we do not hang test is a success
1618 log_test $? 0 "Cached route removed from VRF port device"
1619}
1620
f55fbb6a
GN
1621ipv4_rt_dsfield()
1622{
1623 echo
1624 echo "IPv4 route with dsfield tests"
1625
1626 run_cmd "$IP route flush 172.16.102.0/24"
1627
1628 # New routes should reject dsfield options that interfere with ECN
1629 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"
1630 log_test $? 2 "Reject route with dsfield 0x01"
1631
1632 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"
1633 log_test $? 2 "Reject route with dsfield 0x02"
1634
1635 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"
1636 log_test $? 2 "Reject route with dsfield 0x03"
1637
1638 # A generic route that doesn't take DSCP into account
1639 run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"
1640
1641 # A more specific route for DSCP 0x10
1642 run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"
1643
1644 # DSCP 0x10 should match the specific route, no matter the ECN bits
1645 $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \
1646 grep -q "via 172.16.103.2"
1647 log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"
1648
1649 $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \
1650 grep -q "via 172.16.103.2"
1651 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"
1652
1653 $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \
1654 grep -q "via 172.16.103.2"
1655 log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"
1656
1657 $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \
1658 grep -q "via 172.16.103.2"
1659 log_test $? 0 "IPv4 route with DSCP and ECN:CE"
1660
1661 # Unknown DSCP should match the generic route, no matter the ECN bits
1662 $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \
1663 grep -q "via 172.16.101.2"
1664 log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"
1665
1666 $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \
1667 grep -q "via 172.16.101.2"
1668 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"
1669
1670 $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \
1671 grep -q "via 172.16.101.2"
1672 log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"
1673
1674 $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \
1675 grep -q "via 172.16.101.2"
1676 log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"
1677
1678 # Null DSCP should match the generic route, no matter the ECN bits
1679 $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \
1680 grep -q "via 172.16.101.2"
1681 log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"
1682
1683 $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \
1684 grep -q "via 172.16.101.2"
1685 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"
1686
1687 $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \
1688 grep -q "via 172.16.101.2"
1689 log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"
1690
1691 $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \
1692 grep -q "via 172.16.101.2"
1693 log_test $? 0 "IPv4 route with no DSCP and ECN:CE"
1694}
1695
abb1860a
DA
1696ipv4_route_test()
1697{
1698 route_setup
1699
1700 ipv4_rt_add
1701 ipv4_rt_replace
b87b04f5 1702 ipv4_local_rt_cache
f55fbb6a 1703 ipv4_rt_dsfield
abb1860a
DA
1704
1705 route_cleanup
1706}
1707
d69faad7
DA
1708ipv4_addr_metric_test()
1709{
1710 local rc
1711
1712 echo
1713 echo "IPv4 prefix route tests"
1714
1715 ip_addr_metric_check || return 1
1716
1717 setup
1718
1719 set -e
1720 $IP li add dummy1 type dummy
1721 $IP li add dummy2 type dummy
1722 $IP li set dummy1 up
1723 $IP li set dummy2 up
1724
1725 # default entry is metric 256
1726 run_cmd "$IP addr add dev dummy1 172.16.104.1/24"
1727 run_cmd "$IP addr add dev dummy2 172.16.104.2/24"
1728 set +e
1729
1730 check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2"
1731 log_test $? 0 "Default metric"
1732
1733 set -e
1734 run_cmd "$IP addr flush dev dummy1"
1735 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"
1736 set +e
1737
1738 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257"
1739 log_test $? 0 "User specified metric on first device"
1740
1741 set -e
1742 run_cmd "$IP addr flush dev dummy2"
1743 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"
1744 set +e
1745
1746 check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
1747 log_test $? 0 "User specified metric on second device"
1748
1749 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"
1750 rc=$?
1751 if [ $rc -eq 0 ]; then
1752 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
1753 rc=$?
1754 fi
1755 log_test $rc 0 "Delete of address on first device"
1756
1757 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"
1758 rc=$?
1759 if [ $rc -eq 0 ]; then
1760 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
1761 rc=$?
1762 fi
1763 log_test $rc 0 "Modify metric of address"
1764
1765 # verify prefix route removed on down
1766 run_cmd "$IP li set dev dummy2 down"
1767 rc=$?
1768 if [ $rc -eq 0 ]; then
a5f62298
DA
1769 out=$($IP ro ls match 172.16.104.0/24)
1770 check_expected "${out}" ""
d69faad7
DA
1771 rc=$?
1772 fi
1773 log_test $rc 0 "Prefix route removed on link down"
1774
1775 # verify prefix route re-inserted with assigned metric
1776 run_cmd "$IP li set dev dummy2 up"
1777 rc=$?
1778 if [ $rc -eq 0 ]; then
1779 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
1780 rc=$?
1781 fi
1782 log_test $rc 0 "Prefix route with metric on link up"
1783
37de3b35
PA
1784 # explicitly check for metric changes on edge scenarios
1785 run_cmd "$IP addr flush dev dummy2"
1786 run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"
1787 run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"
1788 rc=$?
1789 if [ $rc -eq 0 ]; then
1790 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"
1791 rc=$?
1792 fi
1793 log_test $rc 0 "Modify metric of .0/24 address"
1794
1795 run_cmd "$IP addr flush dev dummy2"
1796 run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
37de3b35
PA
1797 rc=$?
1798 if [ $rc -eq 0 ]; then
0d29169a
HL
1799 check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"
1800 rc=$?
1801 fi
1802 log_test $rc 0 "Set metric of address with peer route"
1803
1804 run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"
1805 rc=$?
1806 if [ $rc -eq 0 ]; then
1807 check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
37de3b35
PA
1808 rc=$?
1809 fi
0d29169a 1810 log_test $rc 0 "Modify metric and peer address for peer route"
37de3b35 1811
d69faad7
DA
1812 $IP li del dummy1
1813 $IP li del dummy2
1814 cleanup
1815}
1816
a0e11da7
DA
1817ipv4_route_metrics_test()
1818{
1819 local rc
1820
1821 echo
1822 echo "IPv4 route add / append tests"
1823
1824 route_setup
1825
1826 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"
1827 rc=$?
1828 if [ $rc -eq 0 ]; then
1829 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"
1830 rc=$?
1831 fi
1832 log_test $rc 0 "Single path route with mtu metric"
1833
1834
1835 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1836 rc=$?
1837 if [ $rc -eq 0 ]; then
1838 check_route "172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
1839 rc=$?
1840 fi
1841 log_test $rc 0 "Multipath route with mtu metric"
1842
1843 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300
1844 run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1"
1845 log_test $? 0 "Using route with mtu metric"
1846
226407dd
DA
1847 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"
1848 log_test $? 2 "Invalid metric (fails metric_convert)"
1849
a0e11da7
DA
1850 route_cleanup
1851}
1852
2386d748
DA
1853ipv4_del_addr_test()
1854{
1855 echo
1856 echo "IPv4 delete address route tests"
1857
1858 setup
1859
1860 set -e
1861 $IP li add dummy1 type dummy
1862 $IP li set dummy1 up
1863 $IP li add dummy2 type dummy
1864 $IP li set dummy2 up
1865 $IP li add red type vrf table 1111
1866 $IP li set red up
1867 $IP ro add vrf red unreachable default
1868 $IP li set dummy2 vrf red
1869
1870 $IP addr add dev dummy1 172.16.104.1/24
1871 $IP addr add dev dummy1 172.16.104.11/24
f96a3d74 1872 $IP addr add dev dummy1 172.16.104.12/24
c0d99934 1873 $IP addr add dev dummy1 172.16.104.13/24
2386d748
DA
1874 $IP addr add dev dummy2 172.16.104.1/24
1875 $IP addr add dev dummy2 172.16.104.11/24
f96a3d74 1876 $IP addr add dev dummy2 172.16.104.12/24
2386d748 1877 $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
f96a3d74 1878 $IP route add 172.16.106.0/24 dev lo src 172.16.104.12
c0d99934 1879 $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
2386d748 1880 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
f96a3d74 1881 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
2386d748
DA
1882 set +e
1883
1884 # removing address from device in vrf should only remove route from vrf table
f96a3d74
IS
1885 echo " Regular FIB info"
1886
2386d748
DA
1887 $IP addr del dev dummy2 172.16.104.11/24
1888 $IP ro ls vrf red | grep -q 172.16.105.0/24
1889 log_test $? 1 "Route removed from VRF when source address deleted"
1890
1891 $IP ro ls | grep -q 172.16.105.0/24
1892 log_test $? 0 "Route in default VRF not removed"
1893
1894 $IP addr add dev dummy2 172.16.104.11/24
1895 $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
1896
1897 $IP addr del dev dummy1 172.16.104.11/24
1898 $IP ro ls | grep -q 172.16.105.0/24
1899 log_test $? 1 "Route removed in default VRF when source address deleted"
1900
1901 $IP ro ls vrf red | grep -q 172.16.105.0/24
1902 log_test $? 0 "Route in VRF is not removed by address delete"
1903
f96a3d74
IS
1904 # removing address from device in vrf should only remove route from vrf
1905 # table even when the associated fib info only differs in table ID
1906 echo " Identical FIB info with different table ID"
1907
1908 $IP addr del dev dummy2 172.16.104.12/24
1909 $IP ro ls vrf red | grep -q 172.16.106.0/24
1910 log_test $? 1 "Route removed from VRF when source address deleted"
1911
1912 $IP ro ls | grep -q 172.16.106.0/24
1913 log_test $? 0 "Route in default VRF not removed"
1914
1915 $IP addr add dev dummy2 172.16.104.12/24
1916 $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
1917
1918 $IP addr del dev dummy1 172.16.104.12/24
1919 $IP ro ls | grep -q 172.16.106.0/24
1920 log_test $? 1 "Route removed in default VRF when source address deleted"
1921
1922 $IP ro ls vrf red | grep -q 172.16.106.0/24
1923 log_test $? 0 "Route in VRF is not removed by address delete"
1924
c0d99934
IS
1925 # removing address from device in default vrf should remove route from
1926 # the default vrf even when route was inserted with a table ID of 0.
1927 echo " Table ID 0"
1928
1929 $IP addr del dev dummy1 172.16.104.13/24
1930 $IP ro ls | grep -q 172.16.107.0/24
1931 log_test $? 1 "Route removed in default VRF when source address deleted"
1932
2386d748
DA
1933 $IP li del dummy1
1934 $IP li del dummy2
1935 cleanup
1936}
1937
429b55b4
HL
1938ipv6_del_addr_test()
1939{
1940 echo
1941 echo "IPv6 delete address route tests"
1942
1943 setup
1944
1945 set -e
1946 for i in $(seq 6); do
1947 $IP li add dummy${i} up type dummy
1948 done
1949
1950 $IP li add red up type vrf table 1111
1951 $IP ro add vrf red unreachable default
1952 for i in $(seq 4 6); do
1953 $IP li set dummy${i} vrf red
1954 done
1955
1956 $IP addr add dev dummy1 fe80::1/128
1957 $IP addr add dev dummy1 2001:db8:101::1/64
1958 $IP addr add dev dummy1 2001:db8:101::10/64
1959 $IP addr add dev dummy1 2001:db8:101::11/64
1960 $IP addr add dev dummy1 2001:db8:101::12/64
1961 $IP addr add dev dummy1 2001:db8:101::13/64
1962 $IP addr add dev dummy1 2001:db8:101::14/64
1963 $IP addr add dev dummy1 2001:db8:101::15/64
1964 $IP addr add dev dummy2 fe80::1/128
1965 $IP addr add dev dummy2 2001:db8:101::1/64
1966 $IP addr add dev dummy2 2001:db8:101::11/64
1967 $IP addr add dev dummy3 fe80::1/128
1968
1969 $IP addr add dev dummy4 2001:db8:101::1/64
1970 $IP addr add dev dummy4 2001:db8:101::10/64
1971 $IP addr add dev dummy4 2001:db8:101::11/64
1972 $IP addr add dev dummy4 2001:db8:101::12/64
1973 $IP addr add dev dummy4 2001:db8:101::13/64
1974 $IP addr add dev dummy4 2001:db8:101::14/64
1975 $IP addr add dev dummy5 2001:db8:101::1/64
1976 $IP addr add dev dummy5 2001:db8:101::11/64
1977
1978 # Single device using src address
1979 $IP route add 2001:db8:110::/64 dev dummy3 src 2001:db8:101::10
1980 # Two devices with the same source address
1981 $IP route add 2001:db8:111::/64 dev dummy3 src 2001:db8:101::11
1982 # VRF with single device using src address
1983 $IP route add vrf red 2001:db8:110::/64 dev dummy6 src 2001:db8:101::10
1984 # VRF with two devices using src address
1985 $IP route add vrf red 2001:db8:111::/64 dev dummy6 src 2001:db8:101::11
1986 # src address and nexthop dev in same VRF
1987 $IP route add 2001:db8:112::/64 dev dummy3 src 2001:db8:101::12
1988 $IP route add vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
1989 # src address and nexthop device in different VRF
1990 $IP route add 2001:db8:113::/64 dev lo src 2001:db8:101::13
1991 $IP route add vrf red 2001:db8:113::/64 dev lo src 2001:db8:101::13
1992 # table ID 0
1993 $IP route add table 0 2001:db8:115::/64 via 2001:db8:101::2 src 2001:db8:101::15
1994 # Link local source route
1995 $IP route add 2001:db8:116::/64 dev dummy2 src fe80::1
1996 $IP route add 2001:db8:117::/64 dev dummy3 src fe80::1
1997 set +e
1998
1999 echo " Single device using src address"
2000
2001 $IP addr del dev dummy1 2001:db8:101::10/64
2002 $IP -6 route show | grep -q "src 2001:db8:101::10 "
2003 log_test $? 1 "Prefsrc removed when src address removed on other device"
2004
2005 echo " Two devices with the same source address"
2006
2007 $IP addr del dev dummy1 2001:db8:101::11/64
2008 $IP -6 route show | grep -q "src 2001:db8:101::11 "
2009 log_test $? 0 "Prefsrc not removed when src address exist on other device"
2010
2011 $IP addr del dev dummy2 2001:db8:101::11/64
2012 $IP -6 route show | grep -q "src 2001:db8:101::11 "
2013 log_test $? 1 "Prefsrc removed when src address removed on all devices"
2014
2015 echo " VRF with single device using src address"
2016
2017 $IP addr del dev dummy4 2001:db8:101::10/64
2018 $IP -6 route show vrf red | grep -q "src 2001:db8:101::10 "
2019 log_test $? 1 "Prefsrc removed when src address removed on other device"
2020
2021 echo " VRF with two devices using src address"
2022
2023 $IP addr del dev dummy4 2001:db8:101::11/64
2024 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
2025 log_test $? 0 "Prefsrc not removed when src address exist on other device"
2026
2027 $IP addr del dev dummy5 2001:db8:101::11/64
2028 $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
2029 log_test $? 1 "Prefsrc removed when src address removed on all devices"
2030
2031 echo " src address and nexthop dev in same VRF"
2032
2033 $IP addr del dev dummy4 2001:db8:101::12/64
2034 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
2035 log_test $? 1 "Prefsrc removed from VRF when source address deleted"
2036 $IP -6 route show | grep -q " src 2001:db8:101::12 "
2037 log_test $? 0 "Prefsrc in default VRF not removed"
2038
2039 $IP addr add dev dummy4 2001:db8:101::12/64
2040 $IP route replace vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
2041 $IP addr del dev dummy1 2001:db8:101::12/64
2042 $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
2043 log_test $? 0 "Prefsrc not removed from VRF when source address exist"
2044 $IP -6 route show | grep -q " src 2001:db8:101::12 "
2045 log_test $? 1 "Prefsrc in default VRF removed"
2046
2047 echo " src address and nexthop device in different VRF"
2048
2049 $IP addr del dev dummy4 2001:db8:101::13/64
2050 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
2051 log_test $? 0 "Prefsrc not removed from VRF when nexthop dev in diff VRF"
2052 $IP -6 route show | grep -q "src 2001:db8:101::13 "
2053 log_test $? 0 "Prefsrc not removed in default VRF"
2054
2055 $IP addr add dev dummy4 2001:db8:101::13/64
2056 $IP addr del dev dummy1 2001:db8:101::13/64
2057 $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
2058 log_test $? 1 "Prefsrc removed from VRF when nexthop dev in diff VRF"
2059 $IP -6 route show | grep -q "src 2001:db8:101::13 "
2060 log_test $? 1 "Prefsrc removed in default VRF"
2061
2062 echo " Table ID 0"
2063
2064 $IP addr del dev dummy1 2001:db8:101::15/64
2065 $IP -6 route show | grep -q "src 2001:db8:101::15"
2066 log_test $? 1 "Prefsrc removed from default VRF when source address deleted"
2067
2068 echo " Link local source route"
2069 $IP addr del dev dummy1 fe80::1/128
2070 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
2071 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
2072 $IP addr del dev dummy2 fe80::1/128
2073 $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
2074 log_test $? 1 "Prefsrc removed when delete ll addr"
2075 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
2076 log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
2077 $IP addr add dev dummy1 fe80::1/128
2078 $IP addr del dev dummy3 fe80::1/128
2079 $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
2080 log_test $? 1 "Prefsrc removed even ll addr still exist on other dev"
2081
2082 for i in $(seq 6); do
2083 $IP li del dummy${i}
2084 done
2085 cleanup
2086}
2386d748 2087
228ddb33
DA
2088ipv4_route_v6_gw_test()
2089{
2090 local rc
2091
2092 echo
2093 echo "IPv4 route with IPv6 gateway tests"
2094
2095 route_setup
2096 sleep 2
2097
2098 #
2099 # single path route
2100 #
2101 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"
2102 rc=$?
2103 log_test $rc 0 "Single path route with IPv6 gateway"
2104 if [ $rc -eq 0 ]; then
2105 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"
2106 fi
2107
2108 run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1"
2109 log_test $rc 0 "Single path route with IPv6 gateway - ping"
2110
2111 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"
2112 rc=$?
2113 log_test $rc 0 "Single path route delete"
2114 if [ $rc -eq 0 ]; then
2115 check_route "172.16.112.0/24"
2116 fi
2117
2118 #
2119 # multipath - v6 then v4
2120 #
2121 run_cmd "$IP ro add 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
2122 rc=$?
2123 log_test $rc 0 "Multipath route add - v6 nexthop then v4"
2124 if [ $rc -eq 0 ]; then
2125 check_route "172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
2126 fi
2127
2128 run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
2129 log_test $? 2 " Multipath route delete - nexthops in wrong order"
2130
2131 run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
2132 log_test $? 0 " Multipath route delete exact match"
2133
2134 #
2135 # multipath - v4 then v6
2136 #
2137 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
2138 rc=$?
2139 log_test $rc 0 "Multipath route add - v4 nexthop then v6"
2140 if [ $rc -eq 0 ]; then
2141 check_route "172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 weight 1 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1"
2142 fi
2143
2144 run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
2145 log_test $? 2 " Multipath route delete - nexthops in wrong order"
2146
2147 run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
2148 log_test $? 0 " Multipath route delete exact match"
2149
2150 route_cleanup
2151}
a0e11da7 2152
88262182
IS
2153socat_check()
2154{
2155 if [ ! -x "$(command -v socat)" ]; then
2156 echo "socat command not found. Skipping test"
2157 return 1
2158 fi
2159
2160 return 0
2161}
2162
2163iptables_check()
2164{
2165 iptables -t mangle -L OUTPUT &> /dev/null
2166 if [ $? -ne 0 ]; then
2167 echo "iptables configuration not supported. Skipping test"
2168 return 1
2169 fi
2170
2171 return 0
2172}
2173
2174ip6tables_check()
2175{
2176 ip6tables -t mangle -L OUTPUT &> /dev/null
2177 if [ $? -ne 0 ]; then
2178 echo "ip6tables configuration not supported. Skipping test"
2179 return 1
2180 fi
2181
2182 return 0
2183}
2184
2185ipv4_mangle_test()
2186{
2187 local rc
2188
2189 echo
2190 echo "IPv4 mangling tests"
2191
2192 socat_check || return 1
2193 iptables_check || return 1
2194
2195 route_setup
2196 sleep 2
2197
2198 local tmp_file=$(mktemp)
2199 ip netns exec ns2 socat UDP4-LISTEN:54321,fork $tmp_file &
2200
2201 # Add a FIB rule and a route that will direct our connection to the
2202 # listening server.
2203 $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
2204 $IP route add table 123 172.16.101.0/24 dev veth1
2205
2206 # Add an unreachable route to the main table that will block our
2207 # connection in case the FIB rule is not hit.
2208 $IP route add unreachable 172.16.101.2/32
2209
2210 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2211 log_test $? 0 " Connection with correct parameters"
2212
2213 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"
2214 log_test $? 1 " Connection with incorrect parameters"
2215
2216 # Add a mangling rule and make sure connection is still successful.
2217 $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1
2218
2219 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2220 log_test $? 0 " Connection with correct parameters - mangling"
2221
2222 # Delete the mangling rule and make sure connection is still
2223 # successful.
2224 $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1
2225
2226 run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
2227 log_test $? 0 " Connection with correct parameters - no mangling"
2228
2229 # Verify connections were indeed successful on server side.
2230 [[ $(cat $tmp_file | wc -l) -eq 3 ]]
2231 log_test $? 0 " Connection check - server side"
2232
2233 $IP route del unreachable 172.16.101.2/32
2234 $IP route del table 123 172.16.101.0/24 dev veth1
2235 $IP rule del pref 100
2236
2237 { kill %% && wait %%; } 2>/dev/null
2238 rm $tmp_file
2239
2240 route_cleanup
2241}
2242
2243ipv6_mangle_test()
2244{
2245 local rc
2246
2247 echo
2248 echo "IPv6 mangling tests"
2249
2250 socat_check || return 1
2251 ip6tables_check || return 1
2252
2253 route_setup
2254 sleep 2
2255
2256 local tmp_file=$(mktemp)
2257 ip netns exec ns2 socat UDP6-LISTEN:54321,fork $tmp_file &
2258
2259 # Add a FIB rule and a route that will direct our connection to the
2260 # listening server.
2261 $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
2262 $IP -6 route add table 123 2001:db8:101::/64 dev veth1
2263
2264 # Add an unreachable route to the main table that will block our
2265 # connection in case the FIB rule is not hit.
2266 $IP -6 route add unreachable 2001:db8:101::2/128
2267
2268 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2269 log_test $? 0 " Connection with correct parameters"
2270
2271 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"
2272 log_test $? 1 " Connection with incorrect parameters"
2273
2274 # Add a mangling rule and make sure connection is still successful.
2275 $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1
2276
2277 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2278 log_test $? 0 " Connection with correct parameters - mangling"
2279
2280 # Delete the mangling rule and make sure connection is still
2281 # successful.
2282 $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1
2283
2284 run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
2285 log_test $? 0 " Connection with correct parameters - no mangling"
2286
2287 # Verify connections were indeed successful on server side.
2288 [[ $(cat $tmp_file | wc -l) -eq 3 ]]
2289 log_test $? 0 " Connection check - server side"
2290
2291 $IP -6 route del unreachable 2001:db8:101::2/128
2292 $IP -6 route del table 123 2001:db8:101::/64 dev veth1
2293 $IP -6 rule del pref 100
2294
2295 { kill %% && wait %%; } 2>/dev/null
2296 rm $tmp_file
2297
2298 route_cleanup
2299}
2300
25bd462f
IS
2301ip_neigh_get_check()
2302{
2303 ip neigh help 2>&1 | grep -q 'ip neigh get'
2304 if [ $? -ne 0 ]; then
2305 echo "iproute2 command does not support neigh get. Skipping test"
2306 return 1
2307 fi
2308
2309 return 0
2310}
2311
2312ipv4_bcast_neigh_test()
2313{
2314 local rc
2315
2316 echo
2317 echo "IPv4 broadcast neighbour tests"
2318
2319 ip_neigh_get_check || return 1
2320
2321 setup
2322
2323 set -e
2324 run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
2325 run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
2326
2327 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
2328 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2329
2330 run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"
2331
2332 run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"
2333 run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"
2334
2335 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2336 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2337
2338 run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"
2339 set +e
2340
2341 run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
2342 log_test $? 0 "Resolved neighbour for broadcast address"
2343
2344 run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2345 log_test $? 0 "Resolved neighbour for network broadcast address"
2346
2347 run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2348 log_test $? 2 "Unresolved neighbour for broadcast address"
2349
2350 run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2351 log_test $? 2 "Unresolved neighbour for network broadcast address"
2352
2353 cleanup
2354}
2355
8ae9efb8
SY
2356mpath_dep_check()
2357{
2358 if [ ! -x "$(command -v mausezahn)" ]; then
2359 echo "mausezahn command not found. Skipping test"
2360 return 1
2361 fi
2362
2363 if [ ! -x "$(command -v jq)" ]; then
2364 echo "jq command not found. Skipping test"
2365 return 1
2366 fi
2367
2368 if [ ! -x "$(command -v bc)" ]; then
2369 echo "bc command not found. Skipping test"
2370 return 1
2371 fi
2372
2373 if [ ! -x "$(command -v perf)" ]; then
2374 echo "perf command not found. Skipping test"
2375 return 1
2376 fi
2377
2378 perf list fib:* | grep -q fib_table_lookup
2379 if [ $? -ne 0 ]; then
2380 echo "IPv4 FIB tracepoint not found. Skipping test"
2381 return 1
2382 fi
2383
2384 perf list fib6:* | grep -q fib6_table_lookup
2385 if [ $? -ne 0 ]; then
2386 echo "IPv6 FIB tracepoint not found. Skipping test"
2387 return 1
2388 fi
2389
2390 return 0
2391}
2392
2393link_stats_get()
2394{
2395 local ns=$1; shift
2396 local dev=$1; shift
2397 local dir=$1; shift
2398 local stat=$1; shift
2399
2400 ip -n $ns -j -s link show dev $dev \
2401 | jq '.[]["stats64"]["'$dir'"]["'$stat'"]'
2402}
2403
2404list_rcv_eval()
2405{
2406 local file=$1; shift
2407 local expected=$1; shift
2408
2409 local count=$(tail -n 1 $file | jq '.["counter-value"] | tonumber | floor')
2410 local ratio=$(echo "scale=2; $count / $expected" | bc -l)
2411 local res=$(echo "$ratio >= 0.95" | bc)
2412 [[ $res -eq 1 ]]
2413 log_test $? 0 "Multipath route hit ratio ($ratio)"
2414}
2415
2416ipv4_mpath_list_test()
2417{
2418 echo
2419 echo "IPv4 multipath list receive tests"
2420
2421 mpath_dep_check || return 1
2422
2423 route_setup
2424
2425 set -e
2426 run_cmd "ip netns exec ns1 ethtool -K veth1 tcp-segmentation-offload off"
2427
2428 run_cmd "ip netns exec ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""
2429 run_cmd "ip netns exec ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""
2430 run_cmd "ip netns exec ns2 ethtool -K veth2 generic-receive-offload on"
2431 run_cmd "ip -n ns2 link add name nh1 up type dummy"
2432 run_cmd "ip -n ns2 link add name nh2 up type dummy"
2433 run_cmd "ip -n ns2 address add 172.16.201.1/24 dev nh1"
2434 run_cmd "ip -n ns2 address add 172.16.202.1/24 dev nh2"
2435 run_cmd "ip -n ns2 neigh add 172.16.201.2 lladdr 00:11:22:33:44:55 nud perm dev nh1"
2436 run_cmd "ip -n ns2 neigh add 172.16.202.2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"
2437 run_cmd "ip -n ns2 route add 203.0.113.0/24
2438 nexthop via 172.16.201.2 nexthop via 172.16.202.2"
2439 run_cmd "ip netns exec ns2 sysctl -qw net.ipv4.fib_multipath_hash_policy=1"
dbb13378
IS
2440 run_cmd "ip netns exec ns2 sysctl -qw net.ipv4.conf.veth2.rp_filter=0"
2441 run_cmd "ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0"
2442 run_cmd "ip netns exec ns2 sysctl -qw net.ipv4.conf.default.rp_filter=0"
8ae9efb8
SY
2443 set +e
2444
2445 local dmac=$(ip -n ns2 -j link show dev veth2 | jq -r '.[]["address"]')
2446 local tmp_file=$(mktemp)
2447 local cmd="ip netns exec ns1 mausezahn veth1 -a own -b $dmac
2448 -A 172.16.101.1 -B 203.0.113.1 -t udp 'sp=12345,dp=0-65535' -q"
2449
2450 # Packets forwarded in a list using a multipath route must not reuse a
2451 # cached result so that a flow always hits the same nexthop. In other
2452 # words, the FIB lookup tracepoint needs to be triggered for every
2453 # packet.
2454 local t0_rx_pkts=$(link_stats_get ns2 veth2 rx packets)
aa13e524 2455 run_cmd "perf stat -a -e fib:fib_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"
8ae9efb8
SY
2456 local t1_rx_pkts=$(link_stats_get ns2 veth2 rx packets)
2457 local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)
2458 list_rcv_eval $tmp_file $diff
2459
2460 rm $tmp_file
2461 route_cleanup
2462}
2463
2464ipv6_mpath_list_test()
2465{
2466 echo
2467 echo "IPv6 multipath list receive tests"
2468
2469 mpath_dep_check || return 1
2470
2471 route_setup
2472
2473 set -e
2474 run_cmd "ip netns exec ns1 ethtool -K veth1 tcp-segmentation-offload off"
2475
2476 run_cmd "ip netns exec ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""
2477 run_cmd "ip netns exec ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""
2478 run_cmd "ip netns exec ns2 ethtool -K veth2 generic-receive-offload on"
2479 run_cmd "ip -n ns2 link add name nh1 up type dummy"
2480 run_cmd "ip -n ns2 link add name nh2 up type dummy"
2481 run_cmd "ip -n ns2 -6 address add 2001:db8:201::1/64 dev nh1"
2482 run_cmd "ip -n ns2 -6 address add 2001:db8:202::1/64 dev nh2"
2483 run_cmd "ip -n ns2 -6 neigh add 2001:db8:201::2 lladdr 00:11:22:33:44:55 nud perm dev nh1"
2484 run_cmd "ip -n ns2 -6 neigh add 2001:db8:202::2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"
2485 run_cmd "ip -n ns2 -6 route add 2001:db8:301::/64
2486 nexthop via 2001:db8:201::2 nexthop via 2001:db8:202::2"
2487 run_cmd "ip netns exec ns2 sysctl -qw net.ipv6.fib_multipath_hash_policy=1"
2488 set +e
2489
2490 local dmac=$(ip -n ns2 -j link show dev veth2 | jq -r '.[]["address"]')
2491 local tmp_file=$(mktemp)
2492 local cmd="ip netns exec ns1 mausezahn -6 veth1 -a own -b $dmac
2493 -A 2001:db8:101::1 -B 2001:db8:301::1 -t udp 'sp=12345,dp=0-65535' -q"
2494
2495 # Packets forwarded in a list using a multipath route must not reuse a
2496 # cached result so that a flow always hits the same nexthop. In other
2497 # words, the FIB lookup tracepoint needs to be triggered for every
2498 # packet.
2499 local t0_rx_pkts=$(link_stats_get ns2 veth2 rx packets)
aa13e524 2500 run_cmd "perf stat -a -e fib6:fib6_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"
8ae9efb8
SY
2501 local t1_rx_pkts=$(link_stats_get ns2 veth2 rx packets)
2502 local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)
2503 list_rcv_eval $tmp_file $diff
2504
2505 rm $tmp_file
2506 route_cleanup
2507}
2508
654d3a78 2509################################################################################
1c7447b4 2510# usage
654d3a78 2511
1c7447b4 2512usage()
607bd2e5 2513{
1c7447b4
DA
2514 cat <<EOF
2515usage: ${0##*/} OPTS
2516
2517 -t <test> Test(s) to run (default: all)
2518 (options: $TESTS)
2519 -p Pause on fail
7df15e6c 2520 -P Pause after each test before cleanup
1c7447b4
DA
2521 -v verbose mode (show commands and output)
2522EOF
607bd2e5
IS
2523}
2524
1c7447b4
DA
2525################################################################################
2526# main
2527
b60417a9
RN
2528trap cleanup EXIT
2529
1c7447b4
DA
2530while getopts :t:pPhv o
2531do
2532 case $o in
2533 t) TESTS=$OPTARG;;
2534 p) PAUSE_ON_FAIL=yes;;
7df15e6c 2535 P) PAUSE=yes;;
1c7447b4
DA
2536 v) VERBOSE=$(($VERBOSE + 1));;
2537 h) usage; exit 0;;
2538 *) usage; exit 1;;
2539 esac
2540done
2541
2542PEER_CMD="ip netns exec ${PEER_NS}"
2543
7df15e6c
DA
2544# make sure we don't pause twice
2545[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
2546
607bd2e5
IS
2547if [ "$(id -u)" -ne 0 ];then
2548 echo "SKIP: Need root privileges"
57aefc7c 2549 exit $ksft_skip;
607bd2e5
IS
2550fi
2551
2552if [ ! -x "$(command -v ip)" ]; then
2553 echo "SKIP: Could not run test without ip tool"
57aefc7c 2554 exit $ksft_skip
607bd2e5
IS
2555fi
2556
2557ip route help 2>&1 | grep -q fibmatch
2558if [ $? -ne 0 ]; then
2559 echo "SKIP: iproute2 too old, missing fibmatch"
57aefc7c 2560 exit $ksft_skip
607bd2e5
IS
2561fi
2562
ee395a5e
DA
2563# start clean
2564cleanup &> /dev/null
2565
1c7447b4
DA
2566for t in $TESTS
2567do
2568 case $t in
2569 fib_unreg_test|unregister) fib_unreg_test;;
2570 fib_down_test|down) fib_down_test;;
2571 fib_carrier_test|carrier) fib_carrier_test;;
adb701d6 2572 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
1c7447b4 2573 fib_nexthop_test|nexthop) fib_nexthop_test;;
44bd0394
LW
2574 fib_notify_test|ipv4_notify) fib_notify_test;;
2575 fib6_notify_test|ipv6_notify) fib6_notify_test;;
ca7a03c4 2576 fib_suppress_test|suppress) fib_suppress_test;;
f9a5a9d8 2577 ipv6_route_test|ipv6_rt) ipv6_route_test;;
abb1860a 2578 ipv4_route_test|ipv4_rt) ipv4_route_test;;
d69faad7
DA
2579 ipv6_addr_metric) ipv6_addr_metric_test;;
2580 ipv4_addr_metric) ipv4_addr_metric_test;;
2386d748 2581 ipv4_del_addr) ipv4_del_addr_test;;
429b55b4 2582 ipv6_del_addr) ipv6_del_addr_test;;
a0e11da7
DA
2583 ipv6_route_metrics) ipv6_route_metrics_test;;
2584 ipv4_route_metrics) ipv4_route_metrics_test;;
228ddb33 2585 ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
88262182
IS
2586 ipv4_mangle) ipv4_mangle_test;;
2587 ipv6_mangle) ipv6_mangle_test;;
25bd462f 2588 ipv4_bcast_neigh) ipv4_bcast_neigh_test;;
a63e10da 2589 fib6_gc_test|ipv6_gc) fib6_gc_test;;
8ae9efb8
SY
2590 ipv4_mpath_list) ipv4_mpath_list_test;;
2591 ipv6_mpath_list) ipv6_mpath_list_test;;
1c7447b4
DA
2592
2593 help) echo "Test names: $TESTS"; exit 0;;
2594 esac
2595done
607bd2e5 2596
37ce42c1
DA
2597if [ "$TESTS" != "none" ]; then
2598 printf "\nTests passed: %3d\n" ${nsuccess}
2599 printf "Tests failed: %3d\n" ${nfail}
2600fi
607bd2e5
IS
2601
2602exit $ret