Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
8# Kselftest framework requirement - SKIP code is 4.
9ksft_skip=4
10
11# all tests in this script. Can be overridden with -t option
12TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter"
13
14VERBOSE=0
15PAUSE_ON_FAIL=no
16PAUSE=no
17IP="ip -netns ns1"
18NS_EXEC="ip netns exec ns1"
19
20log_test()
21{
22 local rc=$1
23 local expected=$2
24 local msg="$3"
25
26 if [ ${rc} -eq ${expected} ]; then
27 printf " TEST: %-60s [ OK ]\n" "${msg}"
28 nsuccess=$((nsuccess+1))
29 else
30 ret=1
31 nfail=$((nfail+1))
32 printf " TEST: %-60s [FAIL]\n" "${msg}"
33 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
34 echo
35 echo "hit enter to continue, 'q' to quit"
36 read a
37 [ "$a" = "q" ] && exit 1
38 fi
39 fi
40
41 if [ "${PAUSE}" = "yes" ]; then
42 echo
43 echo "hit enter to continue, 'q' to quit"
44 read a
45 [ "$a" = "q" ] && exit 1
46 fi
47}
48
49setup()
50{
51 set -e
52 ip netns add ns1
53 ip netns set ns1 auto
54 $IP link set dev lo up
55 ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
56 ip netns exec ns1 sysctl -qw net.ipv6.conf.all.forwarding=1
57
58 $IP link add dummy0 type dummy
59 $IP link set dev dummy0 up
60 $IP address add 198.51.100.1/24 dev dummy0
61 $IP -6 address add 2001:db8:1::1/64 dev dummy0
62 set +e
63
64}
65
66cleanup()
67{
68 $IP link del dev dummy0 &> /dev/null
69 ip netns del ns1
70 ip netns del ns2 &> /dev/null
71}
72
73get_linklocal()
74{
75 local dev=$1
76 local addr
77
78 addr=$($IP -6 -br addr show dev ${dev} | \
79 awk '{
80 for (i = 3; i <= NF; ++i) {
81 if ($i ~ /^fe80/)
82 print $i
83 }
84 }'
85 )
86 addr=${addr/\/*}
87
88 [ -z "$addr" ] && return 1
89
90 echo $addr
91
92 return 0
93}
94
95fib_unreg_unicast_test()
96{
97 echo
98 echo "Single path route test"
99
100 setup
101
102 echo " Start point"
103 $IP route get fibmatch 198.51.100.2 &> /dev/null
104 log_test $? 0 "IPv4 fibmatch"
105 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
106 log_test $? 0 "IPv6 fibmatch"
107
108 set -e
109 $IP link del dev dummy0
110 set +e
111
112 echo " Nexthop device deleted"
113 $IP route get fibmatch 198.51.100.2 &> /dev/null
114 log_test $? 2 "IPv4 fibmatch - no route"
115 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
116 log_test $? 2 "IPv6 fibmatch - no route"
117
118 cleanup
119}
120
121fib_unreg_multipath_test()
122{
123
124 echo
125 echo "Multipath route test"
126
127 setup
128
129 set -e
130 $IP link add dummy1 type dummy
131 $IP link set dev dummy1 up
132 $IP address add 192.0.2.1/24 dev dummy1
133 $IP -6 address add 2001:db8:2::1/64 dev dummy1
134
135 $IP route add 203.0.113.0/24 \
136 nexthop via 198.51.100.2 dev dummy0 \
137 nexthop via 192.0.2.2 dev dummy1
138 $IP -6 route add 2001:db8:3::/64 \
139 nexthop via 2001:db8:1::2 dev dummy0 \
140 nexthop via 2001:db8:2::2 dev dummy1
141 set +e
142
143 echo " Start point"
144 $IP route get fibmatch 203.0.113.1 &> /dev/null
145 log_test $? 0 "IPv4 fibmatch"
146 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
147 log_test $? 0 "IPv6 fibmatch"
148
149 set -e
150 $IP link del dev dummy0
151 set +e
152
153 echo " One nexthop device deleted"
154 $IP route get fibmatch 203.0.113.1 &> /dev/null
155 log_test $? 2 "IPv4 - multipath route removed on delete"
156
157 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
158 # In IPv6 we do not flush the entire multipath route.
159 log_test $? 0 "IPv6 - multipath down to single path"
160
161 set -e
162 $IP link del dev dummy1
163 set +e
164
165 echo " Second nexthop device deleted"
166 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
167 log_test $? 2 "IPv6 - no route"
168
169 cleanup
170}
171
172fib_unreg_test()
173{
174 fib_unreg_unicast_test
175 fib_unreg_multipath_test
176}
177
178fib_down_unicast_test()
179{
180 echo
181 echo "Single path, admin down"
182
183 setup
184
185 echo " Start point"
186 $IP route get fibmatch 198.51.100.2 &> /dev/null
187 log_test $? 0 "IPv4 fibmatch"
188 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
189 log_test $? 0 "IPv6 fibmatch"
190
191 set -e
192 $IP link set dev dummy0 down
193 set +e
194
195 echo " Route deleted on down"
196 $IP route get fibmatch 198.51.100.2 &> /dev/null
197 log_test $? 2 "IPv4 fibmatch"
198 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
199 log_test $? 2 "IPv6 fibmatch"
200
201 cleanup
202}
203
204fib_down_multipath_test_do()
205{
206 local down_dev=$1
207 local up_dev=$2
208
209 $IP route get fibmatch 203.0.113.1 \
210 oif $down_dev &> /dev/null
211 log_test $? 2 "IPv4 fibmatch on down device"
212 $IP -6 route get fibmatch 2001:db8:3::1 \
213 oif $down_dev &> /dev/null
214 log_test $? 2 "IPv6 fibmatch on down device"
215
216 $IP route get fibmatch 203.0.113.1 \
217 oif $up_dev &> /dev/null
218 log_test $? 0 "IPv4 fibmatch on up device"
219 $IP -6 route get fibmatch 2001:db8:3::1 \
220 oif $up_dev &> /dev/null
221 log_test $? 0 "IPv6 fibmatch on up device"
222
223 $IP route get fibmatch 203.0.113.1 | \
224 grep $down_dev | grep -q "dead linkdown"
225 log_test $? 0 "IPv4 flags on down device"
226 $IP -6 route get fibmatch 2001:db8:3::1 | \
227 grep $down_dev | grep -q "dead linkdown"
228 log_test $? 0 "IPv6 flags on down device"
229
230 $IP route get fibmatch 203.0.113.1 | \
231 grep $up_dev | grep -q "dead linkdown"
232 log_test $? 1 "IPv4 flags on up device"
233 $IP -6 route get fibmatch 2001:db8:3::1 | \
234 grep $up_dev | grep -q "dead linkdown"
235 log_test $? 1 "IPv6 flags on up device"
236}
237
238fib_down_multipath_test()
239{
240 echo
241 echo "Admin down multipath"
242
243 setup
244
245 set -e
246 $IP link add dummy1 type dummy
247 $IP link set dev dummy1 up
248
249 $IP address add 192.0.2.1/24 dev dummy1
250 $IP -6 address add 2001:db8:2::1/64 dev dummy1
251
252 $IP route add 203.0.113.0/24 \
253 nexthop via 198.51.100.2 dev dummy0 \
254 nexthop via 192.0.2.2 dev dummy1
255 $IP -6 route add 2001:db8:3::/64 \
256 nexthop via 2001:db8:1::2 dev dummy0 \
257 nexthop via 2001:db8:2::2 dev dummy1
258 set +e
259
260 echo " Verify start point"
261 $IP route get fibmatch 203.0.113.1 &> /dev/null
262 log_test $? 0 "IPv4 fibmatch"
263
264 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
265 log_test $? 0 "IPv6 fibmatch"
266
267 set -e
268 $IP link set dev dummy0 down
269 set +e
270
271 echo " One device down, one up"
272 fib_down_multipath_test_do "dummy0" "dummy1"
273
274 set -e
275 $IP link set dev dummy0 up
276 $IP link set dev dummy1 down
277 set +e
278
279 echo " Other device down and up"
280 fib_down_multipath_test_do "dummy1" "dummy0"
281
282 set -e
283 $IP link set dev dummy0 down
284 set +e
285
286 echo " Both devices down"
287 $IP route get fibmatch 203.0.113.1 &> /dev/null
288 log_test $? 2 "IPv4 fibmatch"
289 $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
290 log_test $? 2 "IPv6 fibmatch"
291
292 $IP link del dev dummy1
293 cleanup
294}
295
296fib_down_test()
297{
298 fib_down_unicast_test
299 fib_down_multipath_test
300}
301
302# Local routes should not be affected when carrier changes.
303fib_carrier_local_test()
304{
305 echo
306 echo "Local carrier tests - single path"
307
308 setup
309
310 set -e
311 $IP link set dev dummy0 carrier on
312 set +e
313
314 echo " Start point"
315 $IP route get fibmatch 198.51.100.1 &> /dev/null
316 log_test $? 0 "IPv4 fibmatch"
317 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
318 log_test $? 0 "IPv6 fibmatch"
319
320 $IP route get fibmatch 198.51.100.1 | \
321 grep -q "linkdown"
322 log_test $? 1 "IPv4 - no linkdown flag"
323 $IP -6 route get fibmatch 2001:db8:1::1 | \
324 grep -q "linkdown"
325 log_test $? 1 "IPv6 - no linkdown flag"
326
327 set -e
328 $IP link set dev dummy0 carrier off
329 sleep 1
330 set +e
331
332 echo " Carrier off on nexthop"
333 $IP route get fibmatch 198.51.100.1 &> /dev/null
334 log_test $? 0 "IPv4 fibmatch"
335 $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
336 log_test $? 0 "IPv6 fibmatch"
337
338 $IP route get fibmatch 198.51.100.1 | \
339 grep -q "linkdown"
340 log_test $? 1 "IPv4 - linkdown flag set"
341 $IP -6 route get fibmatch 2001:db8:1::1 | \
342 grep -q "linkdown"
343 log_test $? 1 "IPv6 - linkdown flag set"
344
345 set -e
346 $IP address add 192.0.2.1/24 dev dummy0
347 $IP -6 address add 2001:db8:2::1/64 dev dummy0
348 set +e
349
350 echo " Route to local address with carrier down"
351 $IP route get fibmatch 192.0.2.1 &> /dev/null
352 log_test $? 0 "IPv4 fibmatch"
353 $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
354 log_test $? 0 "IPv6 fibmatch"
355
356 $IP route get fibmatch 192.0.2.1 | \
357 grep -q "linkdown"
358 log_test $? 1 "IPv4 linkdown flag set"
359 $IP -6 route get fibmatch 2001:db8:2::1 | \
360 grep -q "linkdown"
361 log_test $? 1 "IPv6 linkdown flag set"
362
363 cleanup
364}
365
366fib_carrier_unicast_test()
367{
368 ret=0
369
370 echo
371 echo "Single path route carrier test"
372
373 setup
374
375 set -e
376 $IP link set dev dummy0 carrier on
377 set +e
378
379 echo " Start point"
380 $IP route get fibmatch 198.51.100.2 &> /dev/null
381 log_test $? 0 "IPv4 fibmatch"
382 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
383 log_test $? 0 "IPv6 fibmatch"
384
385 $IP route get fibmatch 198.51.100.2 | \
386 grep -q "linkdown"
387 log_test $? 1 "IPv4 no linkdown flag"
388 $IP -6 route get fibmatch 2001:db8:1::2 | \
389 grep -q "linkdown"
390 log_test $? 1 "IPv6 no linkdown flag"
391
392 set -e
393 $IP link set dev dummy0 carrier off
394 sleep 1
395 set +e
396
397 echo " Carrier down"
398 $IP route get fibmatch 198.51.100.2 &> /dev/null
399 log_test $? 0 "IPv4 fibmatch"
400 $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
401 log_test $? 0 "IPv6 fibmatch"
402
403 $IP route get fibmatch 198.51.100.2 | \
404 grep -q "linkdown"
405 log_test $? 0 "IPv4 linkdown flag set"
406 $IP -6 route get fibmatch 2001:db8:1::2 | \
407 grep -q "linkdown"
408 log_test $? 0 "IPv6 linkdown flag set"
409
410 set -e
411 $IP address add 192.0.2.1/24 dev dummy0
412 $IP -6 address add 2001:db8:2::1/64 dev dummy0
413 set +e
414
415 echo " Second address added with carrier down"
416 $IP route get fibmatch 192.0.2.2 &> /dev/null
417 log_test $? 0 "IPv4 fibmatch"
418 $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
419 log_test $? 0 "IPv6 fibmatch"
420
421 $IP route get fibmatch 192.0.2.2 | \
422 grep -q "linkdown"
423 log_test $? 0 "IPv4 linkdown flag set"
424 $IP -6 route get fibmatch 2001:db8:2::2 | \
425 grep -q "linkdown"
426 log_test $? 0 "IPv6 linkdown flag set"
427
428 cleanup
429}
430
431fib_carrier_test()
432{
433 fib_carrier_local_test
434 fib_carrier_unicast_test
435}
436
437fib_rp_filter_test()
438{
439 echo
440 echo "IPv4 rp_filter tests"
441
442 setup
443
444 set -e
445 $IP link set dev lo address 52:54:00:6a:c7:5e
446 $IP link set dummy0 address 52:54:00:6a:c7:5e
447 $IP link add dummy1 type dummy
448 $IP link set dummy1 address 52:54:00:6a:c7:5e
449 $IP link set dev dummy1 up
450 $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
451 $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
452 $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
453
454 $NS_EXEC tc qd add dev dummy1 parent root handle 1: fq_codel
455 $NS_EXEC tc filter add dev dummy1 parent 1: protocol arp basic action mirred egress redirect dev lo
456 $NS_EXEC tc filter add dev dummy1 parent 1: protocol ip basic action mirred egress redirect dev lo
457 set +e
458
459 run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 198.51.100.1"
460 log_test $? 0 "rp_filter passes local packets"
461
462 run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 127.0.0.1"
463 log_test $? 0 "rp_filter passes loopback packets"
464
465 cleanup
466}
467
468################################################################################
469# Tests on nexthop spec
470
471# run 'ip route add' with given spec
472add_rt()
473{
474 local desc="$1"
475 local erc=$2
476 local vrf=$3
477 local pfx=$4
478 local gw=$5
479 local dev=$6
480 local cmd out rc
481
482 [ "$vrf" = "-" ] && vrf="default"
483 [ -n "$gw" ] && gw="via $gw"
484 [ -n "$dev" ] && dev="dev $dev"
485
486 cmd="$IP route add vrf $vrf $pfx $gw $dev"
487 if [ "$VERBOSE" = "1" ]; then
488 printf "\n COMMAND: $cmd\n"
489 fi
490
491 out=$(eval $cmd 2>&1)
492 rc=$?
493 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
494 echo " $out"
495 fi
496 log_test $rc $erc "$desc"
497}
498
499fib4_nexthop()
500{
501 echo
502 echo "IPv4 nexthop tests"
503
504 echo "<<< write me >>>"
505}
506
507fib6_nexthop()
508{
509 local lldummy=$(get_linklocal dummy0)
510 local llv1=$(get_linklocal dummy0)
511
512 if [ -z "$lldummy" ]; then
513 echo "Failed to get linklocal address for dummy0"
514 return 1
515 fi
516 if [ -z "$llv1" ]; then
517 echo "Failed to get linklocal address for veth1"
518 return 1
519 fi
520
521 echo
522 echo "IPv6 nexthop tests"
523
524 add_rt "Directly connected nexthop, unicast address" 0 \
525 - 2001:db8:101::/64 2001:db8:1::2
526 add_rt "Directly connected nexthop, unicast address with device" 0 \
527 - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
528 add_rt "Gateway is linklocal address" 0 \
529 - 2001:db8:103::1/64 $llv1 "veth0"
530
531 # fails because LL address requires a device
532 add_rt "Gateway is linklocal address, no device" 2 \
533 - 2001:db8:104::1/64 $llv1
534
535 # local address can not be a gateway
536 add_rt "Gateway can not be local unicast address" 2 \
537 - 2001:db8:105::/64 2001:db8:1::1
538 add_rt "Gateway can not be local unicast address, with device" 2 \
539 - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
540 add_rt "Gateway can not be a local linklocal address" 2 \
541 - 2001:db8:107::1/64 $lldummy "dummy0"
542
543 # VRF tests
544 add_rt "Gateway can be local address in a VRF" 0 \
545 - 2001:db8:108::/64 2001:db8:51::2
546 add_rt "Gateway can be local address in a VRF, with device" 0 \
547 - 2001:db8:109::/64 2001:db8:51::2 "veth0"
548 add_rt "Gateway can be local linklocal address in a VRF" 0 \
549 - 2001:db8:110::1/64 $llv1 "veth0"
550
551 add_rt "Redirect to VRF lookup" 0 \
552 - 2001:db8:111::/64 "" "red"
553
554 add_rt "VRF route, gateway can be local address in default VRF" 0 \
555 red 2001:db8:112::/64 2001:db8:51::1
556
557 # local address in same VRF fails
558 add_rt "VRF route, gateway can not be a local address" 2 \
559 red 2001:db8:113::1/64 2001:db8:2::1
560 add_rt "VRF route, gateway can not be a local addr with device" 2 \
561 red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
562}
563
564# Default VRF:
565# dummy0 - 198.51.100.1/24 2001:db8:1::1/64
566# veth0 - 192.0.2.1/24 2001:db8:51::1/64
567#
568# VRF red:
569# dummy1 - 192.168.2.1/24 2001:db8:2::1/64
570# veth1 - 192.0.2.2/24 2001:db8:51::2/64
571#
572# [ dummy0 veth0 ]--[ veth1 dummy1 ]
573
574fib_nexthop_test()
575{
576 setup
577
578 set -e
579
580 $IP -4 rule add pref 32765 table local
581 $IP -4 rule del pref 0
582 $IP -6 rule add pref 32765 table local
583 $IP -6 rule del pref 0
584
585 $IP link add red type vrf table 1
586 $IP link set red up
587 $IP -4 route add vrf red unreachable default metric 4278198272
588 $IP -6 route add vrf red unreachable default metric 4278198272
589
590 $IP link add veth0 type veth peer name veth1
591 $IP link set dev veth0 up
592 $IP address add 192.0.2.1/24 dev veth0
593 $IP -6 address add 2001:db8:51::1/64 dev veth0
594
595 $IP link set dev veth1 vrf red up
596 $IP address add 192.0.2.2/24 dev veth1
597 $IP -6 address add 2001:db8:51::2/64 dev veth1
598
599 $IP link add dummy1 type dummy
600 $IP link set dev dummy1 vrf red up
601 $IP address add 192.168.2.1/24 dev dummy1
602 $IP -6 address add 2001:db8:2::1/64 dev dummy1
603 set +e
604
605 sleep 1
606 fib4_nexthop
607 fib6_nexthop
608
609 (
610 $IP link del dev dummy1
611 $IP link del veth0
612 $IP link del red
613 ) 2>/dev/null
614 cleanup
615}
616
617################################################################################
618# Tests on route add and replace
619
620run_cmd()
621{
622 local cmd="$1"
623 local out
624 local stderr="2>/dev/null"
625
626 if [ "$VERBOSE" = "1" ]; then
627 printf " COMMAND: $cmd\n"
628 stderr=
629 fi
630
631 out=$(eval $cmd $stderr)
632 rc=$?
633 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
634 echo " $out"
635 fi
636
637 [ "$VERBOSE" = "1" ] && echo
638
639 return $rc
640}
641
642check_expected()
643{
644 local out="$1"
645 local expected="$2"
646 local rc=0
647
648 [ "${out}" = "${expected}" ] && return 0
649
650 if [ -z "${out}" ]; then
651 if [ "$VERBOSE" = "1" ]; then
652 printf "\nNo route entry found\n"
653 printf "Expected:\n"
654 printf " ${expected}\n"
655 fi
656 return 1
657 fi
658
659 # tricky way to convert output to 1-line without ip's
660 # messy '\'; this drops all extra white space
661 out=$(echo ${out})
662 if [ "${out}" != "${expected}" ]; then
663 rc=1
664 if [ "${VERBOSE}" = "1" ]; then
665 printf " Unexpected route entry. Have:\n"
666 printf " ${out}\n"
667 printf " Expected:\n"
668 printf " ${expected}\n\n"
669 fi
670 fi
671
672 return $rc
673}
674
675# add route for a prefix, flushing any existing routes first
676# expected to be the first step of a test
677add_route6()
678{
679 local pfx="$1"
680 local nh="$2"
681 local out
682
683 if [ "$VERBOSE" = "1" ]; then
684 echo
685 echo " ##################################################"
686 echo
687 fi
688
689 run_cmd "$IP -6 ro flush ${pfx}"
690 [ $? -ne 0 ] && exit 1
691
692 out=$($IP -6 ro ls match ${pfx})
693 if [ -n "$out" ]; then
694 echo "Failed to flush routes for prefix used for tests."
695 exit 1
696 fi
697
698 run_cmd "$IP -6 ro add ${pfx} ${nh}"
699 if [ $? -ne 0 ]; then
700 echo "Failed to add initial route for test."
701 exit 1
702 fi
703}
704
705# add initial route - used in replace route tests
706add_initial_route6()
707{
708 add_route6 "2001:db8:104::/64" "$1"
709}
710
711check_route6()
712{
713 local pfx
714 local expected="$1"
715 local out
716 local rc=0
717
718 set -- $expected
719 pfx=$1
720
721 out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')
722 check_expected "${out}" "${expected}"
723}
724
725route_cleanup()
726{
727 $IP li del red 2>/dev/null
728 $IP li del dummy1 2>/dev/null
729 $IP li del veth1 2>/dev/null
730 $IP li del veth3 2>/dev/null
731
732 cleanup &> /dev/null
733}
734
735route_setup()
736{
737 route_cleanup
738 setup
739
740 [ "${VERBOSE}" = "1" ] && set -x
741 set -e
742
743 ip netns add ns2
744 ip netns set ns2 auto
745 ip -netns ns2 link set dev lo up
746 ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1
747 ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1
748
749 $IP li add veth1 type veth peer name veth2
750 $IP li add veth3 type veth peer name veth4
751
752 $IP li set veth1 up
753 $IP li set veth3 up
754 $IP li set veth2 netns ns2 up
755 $IP li set veth4 netns ns2 up
756 ip -netns ns2 li add dummy1 type dummy
757 ip -netns ns2 li set dummy1 up
758
759 $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad
760 $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad
761 $IP addr add 172.16.101.1/24 dev veth1
762 $IP addr add 172.16.103.1/24 dev veth3
763
764 ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad
765 ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad
766 ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad
767
768 ip -netns ns2 addr add 172.16.101.2/24 dev veth2
769 ip -netns ns2 addr add 172.16.103.2/24 dev veth4
770 ip -netns ns2 addr add 172.16.104.1/24 dev dummy1
771
772 set +e
773}
774
775# assumption is that basic add of a single path route works
776# otherwise just adding an address on an interface is broken
777ipv6_rt_add()
778{
779 local rc
780
781 echo
782 echo "IPv6 route add / append tests"
783
784 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
785 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
786 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"
787 log_test $? 2 "Attempt to add duplicate route - gw"
788
789 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
790 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
791 run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"
792 log_test $? 2 "Attempt to add duplicate route - dev only"
793
794 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
795 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
796 run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"
797 log_test $? 2 "Attempt to add duplicate route - reject route"
798
799 # route append with same prefix adds a new route
800 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
801 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
802 run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"
803 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"
804 log_test $? 0 "Append nexthop to existing route - gw"
805
806 # insert mpath directly
807 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
808 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"
809 log_test $? 0 "Add multipath route"
810
811 add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
812 run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
813 log_test $? 2 "Attempt to add duplicate multipath route"
814
815 # insert of a second route without append but different metric
816 add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
817 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"
818 rc=$?
819 if [ $rc -eq 0 ]; then
820 run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"
821 rc=$?
822 fi
823 log_test $rc 0 "Route add with different metrics"
824
825 run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"
826 rc=$?
827 if [ $rc -eq 0 ]; then
828 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"
829 rc=$?
830 fi
831 log_test $rc 0 "Route delete with metric"
832}
833
834ipv6_rt_replace_single()
835{
836 # single path with single path
837 #
838 add_initial_route6 "via 2001:db8:101::2"
839 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"
840 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
841 log_test $? 0 "Single path with single path"
842
843 # single path with multipath
844 #
845 add_initial_route6 "nexthop via 2001:db8:101::2"
846 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"
847 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"
848 log_test $? 0 "Single path with multipath"
849
850 # single path with single path using MULTIPATH attribute
851 #
852 add_initial_route6 "via 2001:db8:101::2"
853 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"
854 check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
855 log_test $? 0 "Single path with single path via multipath attribute"
856
857 # route replace fails - invalid nexthop
858 add_initial_route6 "via 2001:db8:101::2"
859 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"
860 if [ $? -eq 0 ]; then
861 # previous command is expected to fail so if it returns 0
862 # that means the test failed.
863 log_test 0 1 "Invalid nexthop"
864 else
865 check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
866 log_test $? 0 "Invalid nexthop"
867 fi
868
869 # replace non-existent route
870 # - note use of change versus replace since ip adds NLM_F_CREATE
871 # for replace
872 add_initial_route6 "via 2001:db8:101::2"
873 run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"
874 log_test $? 2 "Single path - replace of non-existent route"
875}
876
877ipv6_rt_replace_mpath()
878{
879 # multipath with multipath
880 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
881 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
882 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"
883 log_test $? 0 "Multipath with multipath"
884
885 # multipath with single
886 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
887 run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"
888 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
889 log_test $? 0 "Multipath with single path"
890
891 # multipath with single
892 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
893 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"
894 check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
895 log_test $? 0 "Multipath with single path via multipath attribute"
896
897 # route replace fails - invalid nexthop 1
898 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
899 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"
900 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"
901 log_test $? 0 "Multipath - invalid first nexthop"
902
903 # route replace fails - invalid nexthop 2
904 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
905 run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"
906 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"
907 log_test $? 0 "Multipath - invalid second nexthop"
908
909 # multipath non-existent route
910 add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
911 run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
912 log_test $? 2 "Multipath - replace of non-existent route"
913}
914
915ipv6_rt_replace()
916{
917 echo
918 echo "IPv6 route replace tests"
919
920 ipv6_rt_replace_single
921 ipv6_rt_replace_mpath
922}
923
924ipv6_route_test()
925{
926 route_setup
927
928 ipv6_rt_add
929 ipv6_rt_replace
930
931 route_cleanup
932}
933
934ip_addr_metric_check()
935{
936 ip addr help 2>&1 | grep -q metric
937 if [ $? -ne 0 ]; then
938 echo "iproute2 command does not support metric for addresses. Skipping test"
939 return 1
940 fi
941
942 return 0
943}
944
945ipv6_addr_metric_test()
946{
947 local rc
948
949 echo
950 echo "IPv6 prefix route tests"
951
952 ip_addr_metric_check || return 1
953
954 setup
955
956 set -e
957 $IP li add dummy1 type dummy
958 $IP li add dummy2 type dummy
959 $IP li set dummy1 up
960 $IP li set dummy2 up
961
962 # default entry is metric 256
963 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"
964 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"
965 set +e
966
967 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"
968 log_test $? 0 "Default metric"
969
970 set -e
971 run_cmd "$IP -6 addr flush dev dummy1"
972 run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"
973 set +e
974
975 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"
976 log_test $? 0 "User specified metric on first device"
977
978 set -e
979 run_cmd "$IP -6 addr flush dev dummy2"
980 run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"
981 set +e
982
983 check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"
984 log_test $? 0 "User specified metric on second device"
985
986 run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"
987 rc=$?
988 if [ $rc -eq 0 ]; then
989 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"
990 rc=$?
991 fi
992 log_test $rc 0 "Delete of address on first device"
993
994 run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"
995 rc=$?
996 if [ $rc -eq 0 ]; then
997 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
998 rc=$?
999 fi
1000 log_test $rc 0 "Modify metric of address"
1001
1002 # verify prefix route removed on down
1003 run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"
1004 run_cmd "$IP li set dev dummy2 down"
1005 rc=$?
1006 if [ $rc -eq 0 ]; then
1007 out=$($IP -6 ro ls match 2001:db8:104::/64)
1008 check_expected "${out}" ""
1009 rc=$?
1010 fi
1011 log_test $rc 0 "Prefix route removed on link down"
1012
1013 # verify prefix route re-inserted with assigned metric
1014 run_cmd "$IP li set dev dummy2 up"
1015 rc=$?
1016 if [ $rc -eq 0 ]; then
1017 check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
1018 rc=$?
1019 fi
1020 log_test $rc 0 "Prefix route with metric on link up"
1021
1022 $IP li del dummy1
1023 $IP li del dummy2
1024 cleanup
1025}
1026
1027ipv6_route_metrics_test()
1028{
1029 local rc
1030
1031 echo
1032 echo "IPv6 routes with metrics"
1033
1034 route_setup
1035
1036 #
1037 # single path with metrics
1038 #
1039 run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"
1040 rc=$?
1041 if [ $rc -eq 0 ]; then
1042 check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"
1043 rc=$?
1044 fi
1045 log_test $rc 0 "Single path route with mtu metric"
1046
1047
1048 #
1049 # multipath via separate routes with metrics
1050 #
1051 run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"
1052 run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"
1053 rc=$?
1054 if [ $rc -eq 0 ]; then
1055 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"
1056 rc=$?
1057 fi
1058 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"
1059
1060 # second route is coalesced to first to make a multipath route.
1061 # MTU of the second path is hidden from display!
1062 run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"
1063 run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"
1064 rc=$?
1065 if [ $rc -eq 0 ]; then
1066 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"
1067 rc=$?
1068 fi
1069 log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"
1070
1071 run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"
1072 if [ $? -eq 0 ]; then
1073 check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"
1074 log_test $? 0 " MTU of second leg"
1075 fi
1076
1077 #
1078 # multipath with metrics
1079 #
1080 run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
1081 rc=$?
1082 if [ $rc -eq 0 ]; then
1083 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"
1084 rc=$?
1085 fi
1086 log_test $rc 0 "Multipath route with mtu metric"
1087
1088 $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300
1089 run_cmd "ip netns exec ns1 ping6 -w1 -c1 -s 1500 2001:db8:104::1"
1090 log_test $? 0 "Using route with mtu metric"
1091
1092 run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"
1093 log_test $? 2 "Invalid metric (fails metric_convert)"
1094
1095 route_cleanup
1096}
1097
1098# add route for a prefix, flushing any existing routes first
1099# expected to be the first step of a test
1100add_route()
1101{
1102 local pfx="$1"
1103 local nh="$2"
1104 local out
1105
1106 if [ "$VERBOSE" = "1" ]; then
1107 echo
1108 echo " ##################################################"
1109 echo
1110 fi
1111
1112 run_cmd "$IP ro flush ${pfx}"
1113 [ $? -ne 0 ] && exit 1
1114
1115 out=$($IP ro ls match ${pfx})
1116 if [ -n "$out" ]; then
1117 echo "Failed to flush routes for prefix used for tests."
1118 exit 1
1119 fi
1120
1121 run_cmd "$IP ro add ${pfx} ${nh}"
1122 if [ $? -ne 0 ]; then
1123 echo "Failed to add initial route for test."
1124 exit 1
1125 fi
1126}
1127
1128# add initial route - used in replace route tests
1129add_initial_route()
1130{
1131 add_route "172.16.104.0/24" "$1"
1132}
1133
1134check_route()
1135{
1136 local pfx
1137 local expected="$1"
1138 local out
1139
1140 set -- $expected
1141 pfx=$1
1142 [ "${pfx}" = "unreachable" ] && pfx=$2
1143
1144 out=$($IP ro ls match ${pfx})
1145 check_expected "${out}" "${expected}"
1146}
1147
1148# assumption is that basic add of a single path route works
1149# otherwise just adding an address on an interface is broken
1150ipv4_rt_add()
1151{
1152 local rc
1153
1154 echo
1155 echo "IPv4 route add / append tests"
1156
1157 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1158 add_route "172.16.104.0/24" "via 172.16.101.2"
1159 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"
1160 log_test $? 2 "Attempt to add duplicate route - gw"
1161
1162 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1163 add_route "172.16.104.0/24" "via 172.16.101.2"
1164 run_cmd "$IP ro add 172.16.104.0/24 dev veth3"
1165 log_test $? 2 "Attempt to add duplicate route - dev only"
1166
1167 # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
1168 add_route "172.16.104.0/24" "via 172.16.101.2"
1169 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1170 log_test $? 2 "Attempt to add duplicate route - reject route"
1171
1172 # iproute2 prepend only sets NLM_F_CREATE
1173 # - adds a new route; does NOT convert existing route to ECMP
1174 add_route "172.16.104.0/24" "via 172.16.101.2"
1175 run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"
1176 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"
1177 log_test $? 0 "Add new nexthop for existing prefix"
1178
1179 # route append with same prefix adds a new route
1180 # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
1181 add_route "172.16.104.0/24" "via 172.16.101.2"
1182 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1183 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"
1184 log_test $? 0 "Append nexthop to existing route - gw"
1185
1186 add_route "172.16.104.0/24" "via 172.16.101.2"
1187 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1188 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"
1189 log_test $? 0 "Append nexthop to existing route - dev only"
1190
1191 add_route "172.16.104.0/24" "via 172.16.101.2"
1192 run_cmd "$IP ro append unreachable 172.16.104.0/24"
1193 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"
1194 log_test $? 0 "Append nexthop to existing route - reject route"
1195
1196 run_cmd "$IP ro flush 172.16.104.0/24"
1197 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1198 run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
1199 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"
1200 log_test $? 0 "Append nexthop to existing reject route - gw"
1201
1202 run_cmd "$IP ro flush 172.16.104.0/24"
1203 run_cmd "$IP ro add unreachable 172.16.104.0/24"
1204 run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
1205 check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"
1206 log_test $? 0 "Append nexthop to existing reject route - dev only"
1207
1208 # insert mpath directly
1209 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1210 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"
1211 log_test $? 0 "add multipath route"
1212
1213 add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1214 run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1215 log_test $? 2 "Attempt to add duplicate multipath route"
1216
1217 # insert of a second route without append but different metric
1218 add_route "172.16.104.0/24" "via 172.16.101.2"
1219 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"
1220 rc=$?
1221 if [ $rc -eq 0 ]; then
1222 run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"
1223 rc=$?
1224 fi
1225 log_test $rc 0 "Route add with different metrics"
1226
1227 run_cmd "$IP ro del 172.16.104.0/24 metric 512"
1228 rc=$?
1229 if [ $rc -eq 0 ]; then
1230 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"
1231 rc=$?
1232 fi
1233 log_test $rc 0 "Route delete with metric"
1234}
1235
1236ipv4_rt_replace_single()
1237{
1238 # single path with single path
1239 #
1240 add_initial_route "via 172.16.101.2"
1241 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"
1242 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1243 log_test $? 0 "Single path with single path"
1244
1245 # single path with multipath
1246 #
1247 add_initial_route "nexthop via 172.16.101.2"
1248 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"
1249 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"
1250 log_test $? 0 "Single path with multipath"
1251
1252 # single path with reject
1253 #
1254 add_initial_route "nexthop via 172.16.101.2"
1255 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1256 check_route "unreachable 172.16.104.0/24"
1257 log_test $? 0 "Single path with reject route"
1258
1259 # single path with single path using MULTIPATH attribute
1260 #
1261 add_initial_route "via 172.16.101.2"
1262 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"
1263 check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
1264 log_test $? 0 "Single path with single path via multipath attribute"
1265
1266 # route replace fails - invalid nexthop
1267 add_initial_route "via 172.16.101.2"
1268 run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"
1269 if [ $? -eq 0 ]; then
1270 # previous command is expected to fail so if it returns 0
1271 # that means the test failed.
1272 log_test 0 1 "Invalid nexthop"
1273 else
1274 check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"
1275 log_test $? 0 "Invalid nexthop"
1276 fi
1277
1278 # replace non-existent route
1279 # - note use of change versus replace since ip adds NLM_F_CREATE
1280 # for replace
1281 add_initial_route "via 172.16.101.2"
1282 run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"
1283 log_test $? 2 "Single path - replace of non-existent route"
1284}
1285
1286ipv4_rt_replace_mpath()
1287{
1288 # multipath with multipath
1289 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1290 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1291 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"
1292 log_test $? 0 "Multipath with multipath"
1293
1294 # multipath with single
1295 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1296 run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"
1297 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1298 log_test $? 0 "Multipath with single path"
1299
1300 # multipath with single
1301 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1302 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"
1303 check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
1304 log_test $? 0 "Multipath with single path via multipath attribute"
1305
1306 # multipath with reject
1307 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1308 run_cmd "$IP ro replace unreachable 172.16.104.0/24"
1309 check_route "unreachable 172.16.104.0/24"
1310 log_test $? 0 "Multipath with reject route"
1311
1312 # route replace fails - invalid nexthop 1
1313 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1314 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"
1315 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"
1316 log_test $? 0 "Multipath - invalid first nexthop"
1317
1318 # route replace fails - invalid nexthop 2
1319 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1320 run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"
1321 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"
1322 log_test $? 0 "Multipath - invalid second nexthop"
1323
1324 # multipath non-existent route
1325 add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1326 run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
1327 log_test $? 2 "Multipath - replace of non-existent route"
1328}
1329
1330ipv4_rt_replace()
1331{
1332 echo
1333 echo "IPv4 route replace tests"
1334
1335 ipv4_rt_replace_single
1336 ipv4_rt_replace_mpath
1337}
1338
1339ipv4_route_test()
1340{
1341 route_setup
1342
1343 ipv4_rt_add
1344 ipv4_rt_replace
1345
1346 route_cleanup
1347}
1348
1349ipv4_addr_metric_test()
1350{
1351 local rc
1352
1353 echo
1354 echo "IPv4 prefix route tests"
1355
1356 ip_addr_metric_check || return 1
1357
1358 setup
1359
1360 set -e
1361 $IP li add dummy1 type dummy
1362 $IP li add dummy2 type dummy
1363 $IP li set dummy1 up
1364 $IP li set dummy2 up
1365
1366 # default entry is metric 256
1367 run_cmd "$IP addr add dev dummy1 172.16.104.1/24"
1368 run_cmd "$IP addr add dev dummy2 172.16.104.2/24"
1369 set +e
1370
1371 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"
1372 log_test $? 0 "Default metric"
1373
1374 set -e
1375 run_cmd "$IP addr flush dev dummy1"
1376 run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"
1377 set +e
1378
1379 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"
1380 log_test $? 0 "User specified metric on first device"
1381
1382 set -e
1383 run_cmd "$IP addr flush dev dummy2"
1384 run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"
1385 set +e
1386
1387 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"
1388 log_test $? 0 "User specified metric on second device"
1389
1390 run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"
1391 rc=$?
1392 if [ $rc -eq 0 ]; then
1393 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
1394 rc=$?
1395 fi
1396 log_test $rc 0 "Delete of address on first device"
1397
1398 run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"
1399 rc=$?
1400 if [ $rc -eq 0 ]; then
1401 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
1402 rc=$?
1403 fi
1404 log_test $rc 0 "Modify metric of address"
1405
1406 # verify prefix route removed on down
1407 run_cmd "$IP li set dev dummy2 down"
1408 rc=$?
1409 if [ $rc -eq 0 ]; then
1410 out=$($IP ro ls match 172.16.104.0/24)
1411 check_expected "${out}" ""
1412 rc=$?
1413 fi
1414 log_test $rc 0 "Prefix route removed on link down"
1415
1416 # verify prefix route re-inserted with assigned metric
1417 run_cmd "$IP li set dev dummy2 up"
1418 rc=$?
1419 if [ $rc -eq 0 ]; then
1420 check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
1421 rc=$?
1422 fi
1423 log_test $rc 0 "Prefix route with metric on link up"
1424
1425 $IP li del dummy1
1426 $IP li del dummy2
1427 cleanup
1428}
1429
1430ipv4_route_metrics_test()
1431{
1432 local rc
1433
1434 echo
1435 echo "IPv4 route add / append tests"
1436
1437 route_setup
1438
1439 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"
1440 rc=$?
1441 if [ $rc -eq 0 ]; then
1442 check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"
1443 rc=$?
1444 fi
1445 log_test $rc 0 "Single path route with mtu metric"
1446
1447
1448 run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
1449 rc=$?
1450 if [ $rc -eq 0 ]; then
1451 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"
1452 rc=$?
1453 fi
1454 log_test $rc 0 "Multipath route with mtu metric"
1455
1456 $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300
1457 run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1"
1458 log_test $? 0 "Using route with mtu metric"
1459
1460 run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"
1461 log_test $? 2 "Invalid metric (fails metric_convert)"
1462
1463 route_cleanup
1464}
1465
1466ipv4_route_v6_gw_test()
1467{
1468 local rc
1469
1470 echo
1471 echo "IPv4 route with IPv6 gateway tests"
1472
1473 route_setup
1474 sleep 2
1475
1476 #
1477 # single path route
1478 #
1479 run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"
1480 rc=$?
1481 log_test $rc 0 "Single path route with IPv6 gateway"
1482 if [ $rc -eq 0 ]; then
1483 check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"
1484 fi
1485
1486 run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1"
1487 log_test $rc 0 "Single path route with IPv6 gateway - ping"
1488
1489 run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"
1490 rc=$?
1491 log_test $rc 0 "Single path route delete"
1492 if [ $rc -eq 0 ]; then
1493 check_route "172.16.112.0/24"
1494 fi
1495
1496 #
1497 # multipath - v6 then v4
1498 #
1499 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"
1500 rc=$?
1501 log_test $rc 0 "Multipath route add - v6 nexthop then v4"
1502 if [ $rc -eq 0 ]; then
1503 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"
1504 fi
1505
1506 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"
1507 log_test $? 2 " Multipath route delete - nexthops in wrong order"
1508
1509 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"
1510 log_test $? 0 " Multipath route delete exact match"
1511
1512 #
1513 # multipath - v4 then v6
1514 #
1515 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"
1516 rc=$?
1517 log_test $rc 0 "Multipath route add - v4 nexthop then v6"
1518 if [ $rc -eq 0 ]; then
1519 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"
1520 fi
1521
1522 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"
1523 log_test $? 2 " Multipath route delete - nexthops in wrong order"
1524
1525 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"
1526 log_test $? 0 " Multipath route delete exact match"
1527
1528 route_cleanup
1529}
1530
1531################################################################################
1532# usage
1533
1534usage()
1535{
1536 cat <<EOF
1537usage: ${0##*/} OPTS
1538
1539 -t <test> Test(s) to run (default: all)
1540 (options: $TESTS)
1541 -p Pause on fail
1542 -P Pause after each test before cleanup
1543 -v verbose mode (show commands and output)
1544EOF
1545}
1546
1547################################################################################
1548# main
1549
1550while getopts :t:pPhv o
1551do
1552 case $o in
1553 t) TESTS=$OPTARG;;
1554 p) PAUSE_ON_FAIL=yes;;
1555 P) PAUSE=yes;;
1556 v) VERBOSE=$(($VERBOSE + 1));;
1557 h) usage; exit 0;;
1558 *) usage; exit 1;;
1559 esac
1560done
1561
1562PEER_CMD="ip netns exec ${PEER_NS}"
1563
1564# make sure we don't pause twice
1565[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
1566
1567if [ "$(id -u)" -ne 0 ];then
1568 echo "SKIP: Need root privileges"
1569 exit $ksft_skip;
1570fi
1571
1572if [ ! -x "$(command -v ip)" ]; then
1573 echo "SKIP: Could not run test without ip tool"
1574 exit $ksft_skip
1575fi
1576
1577ip route help 2>&1 | grep -q fibmatch
1578if [ $? -ne 0 ]; then
1579 echo "SKIP: iproute2 too old, missing fibmatch"
1580 exit $ksft_skip
1581fi
1582
1583# start clean
1584cleanup &> /dev/null
1585
1586for t in $TESTS
1587do
1588 case $t in
1589 fib_unreg_test|unregister) fib_unreg_test;;
1590 fib_down_test|down) fib_down_test;;
1591 fib_carrier_test|carrier) fib_carrier_test;;
1592 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
1593 fib_nexthop_test|nexthop) fib_nexthop_test;;
1594 ipv6_route_test|ipv6_rt) ipv6_route_test;;
1595 ipv4_route_test|ipv4_rt) ipv4_route_test;;
1596 ipv6_addr_metric) ipv6_addr_metric_test;;
1597 ipv4_addr_metric) ipv4_addr_metric_test;;
1598 ipv6_route_metrics) ipv6_route_metrics_test;;
1599 ipv4_route_metrics) ipv4_route_metrics_test;;
1600 ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
1601
1602 help) echo "Test names: $TESTS"; exit 0;;
1603 esac
1604done
1605
1606if [ "$TESTS" != "none" ]; then
1607 printf "\nTests passed: %3d\n" ${nsuccess}
1608 printf "Tests failed: %3d\n" ${nfail}
1609fi
1610
1611exit $ret