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