selftests: Add ipv6 ping tests to fcnal-test
[linux-2.6-microblaze.git] / tools / testing / selftests / net / fcnal-test.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # Copyright (c) 2019 David Ahern <dsahern@gmail.com>. All rights reserved.
5 #
6 # IPv4 and IPv6 functional tests focusing on VRF and routing lookups
7 # for various permutations:
8 #   1. icmp, tcp, udp and netfilter
9 #   2. client, server, no-server
10 #   3. global address on interface
11 #   4. global address on 'lo'
12 #   5. remote and local traffic
13 #   6. VRF and non-VRF permutations
14 #
15 # Setup:
16 #                     ns-A     |     ns-B
17 # No VRF case:
18 #    [ lo ]         [ eth1 ]---|---[ eth1 ]      [ lo ]
19 #                                                remote address
20 # VRF case:
21 #         [ red ]---[ eth1 ]---|---[ eth1 ]      [ lo ]
22 #
23 # ns-A:
24 #     eth1: 172.16.1.1/24, 2001:db8:1::1/64
25 #       lo: 127.0.0.1/8, ::1/128
26 #           172.16.2.1/32, 2001:db8:2::1/128
27 #      red: 127.0.0.1/8, ::1/128
28 #           172.16.3.1/32, 2001:db8:3::1/128
29 #
30 # ns-B:
31 #     eth1: 172.16.1.2/24, 2001:db8:1::2/64
32 #      lo2: 127.0.0.1/8, ::1/128
33 #           172.16.2.2/32, 2001:db8:2::2/128
34 #
35 # server / client nomenclature relative to ns-A
36
37 VERBOSE=0
38
39 NSA_DEV=eth1
40 NSB_DEV=eth1
41 VRF=red
42 VRF_TABLE=1101
43
44 # IPv4 config
45 NSA_IP=172.16.1.1
46 NSB_IP=172.16.1.2
47 VRF_IP=172.16.3.1
48
49 # IPv6 config
50 NSA_IP6=2001:db8:1::1
51 NSB_IP6=2001:db8:1::2
52 VRF_IP6=2001:db8:3::1
53
54 NSA_LO_IP=172.16.2.1
55 NSB_LO_IP=172.16.2.2
56 NSA_LO_IP6=2001:db8:2::1
57 NSB_LO_IP6=2001:db8:2::2
58
59 MCAST=ff02::1
60 # set after namespace create
61 NSA_LINKIP6=
62 NSB_LINKIP6=
63
64 NSA=ns-A
65 NSB=ns-B
66
67 NSA_CMD="ip netns exec ${NSA}"
68 NSB_CMD="ip netns exec ${NSB}"
69
70 which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
71
72 ################################################################################
73 # utilities
74
75 log_test()
76 {
77         local rc=$1
78         local expected=$2
79         local msg="$3"
80
81         [ "${VERBOSE}" = "1" ] && echo
82
83         if [ ${rc} -eq ${expected} ]; then
84                 nsuccess=$((nsuccess+1))
85                 printf "TEST: %-70s  [ OK ]\n" "${msg}"
86         else
87                 nfail=$((nfail+1))
88                 printf "TEST: %-70s  [FAIL]\n" "${msg}"
89                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
90                         echo
91                         echo "hit enter to continue, 'q' to quit"
92                         read a
93                         [ "$a" = "q" ] && exit 1
94                 fi
95         fi
96
97         if [ "${PAUSE}" = "yes" ]; then
98                 echo
99                 echo "hit enter to continue, 'q' to quit"
100                 read a
101                 [ "$a" = "q" ] && exit 1
102         fi
103
104         kill_procs
105 }
106
107 log_test_addr()
108 {
109         local addr=$1
110         local rc=$2
111         local expected=$3
112         local msg="$4"
113         local astr
114
115         astr=$(addr2str ${addr})
116         log_test $rc $expected "$msg - ${astr}"
117 }
118
119 log_section()
120 {
121         echo
122         echo "###########################################################################"
123         echo "$*"
124         echo "###########################################################################"
125         echo
126 }
127
128 log_subsection()
129 {
130         echo
131         echo "#################################################################"
132         echo "$*"
133         echo
134 }
135
136 log_start()
137 {
138         # make sure we have no test instances running
139         kill_procs
140
141         if [ "${VERBOSE}" = "1" ]; then
142                 echo
143                 echo "#######################################################"
144         fi
145 }
146
147 log_debug()
148 {
149         if [ "${VERBOSE}" = "1" ]; then
150                 echo
151                 echo "$*"
152                 echo
153         fi
154 }
155
156 show_hint()
157 {
158         if [ "${VERBOSE}" = "1" ]; then
159                 echo "HINT: $*"
160                 echo
161         fi
162 }
163
164 kill_procs()
165 {
166         killall nettest ping ping6 >/dev/null 2>&1
167         sleep 1
168 }
169
170 do_run_cmd()
171 {
172         local cmd="$*"
173         local out
174
175         if [ "$VERBOSE" = "1" ]; then
176                 echo "COMMAND: ${cmd}"
177         fi
178
179         out=$($cmd 2>&1)
180         rc=$?
181         if [ "$VERBOSE" = "1" -a -n "$out" ]; then
182                 echo "$out"
183         fi
184
185         return $rc
186 }
187
188 run_cmd()
189 {
190         do_run_cmd ${NSA_CMD} $*
191 }
192
193 run_cmd_nsb()
194 {
195         do_run_cmd ${NSB_CMD} $*
196 }
197
198 setup_cmd()
199 {
200         local cmd="$*"
201         local rc
202
203         run_cmd ${cmd}
204         rc=$?
205         if [ $rc -ne 0 ]; then
206                 # show user the command if not done so already
207                 if [ "$VERBOSE" = "0" ]; then
208                         echo "setup command: $cmd"
209                 fi
210                 echo "failed. stopping tests"
211                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
212                         echo
213                         echo "hit enter to continue"
214                         read a
215                 fi
216                 exit $rc
217         fi
218 }
219
220 setup_cmd_nsb()
221 {
222         local cmd="$*"
223         local rc
224
225         run_cmd_nsb ${cmd}
226         rc=$?
227         if [ $rc -ne 0 ]; then
228                 # show user the command if not done so already
229                 if [ "$VERBOSE" = "0" ]; then
230                         echo "setup command: $cmd"
231                 fi
232                 echo "failed. stopping tests"
233                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
234                         echo
235                         echo "hit enter to continue"
236                         read a
237                 fi
238                 exit $rc
239         fi
240 }
241
242 # set sysctl values in NS-A
243 set_sysctl()
244 {
245         echo "SYSCTL: $*"
246         echo
247         run_cmd sysctl -q -w $*
248 }
249
250 ################################################################################
251 # Setup for tests
252
253 addr2str()
254 {
255         case "$1" in
256         127.0.0.1) echo "loopback";;
257         ::1) echo "IPv6 loopback";;
258
259         ${NSA_IP})      echo "ns-A IP";;
260         ${NSA_IP6})     echo "ns-A IPv6";;
261         ${NSA_LO_IP})   echo "ns-A loopback IP";;
262         ${NSA_LO_IP6})  echo "ns-A loopback IPv6";;
263         ${NSA_LINKIP6}|${NSA_LINKIP6}%*) echo "ns-A IPv6 LLA";;
264
265         ${NSB_IP})      echo "ns-B IP";;
266         ${NSB_IP6})     echo "ns-B IPv6";;
267         ${NSB_LO_IP})   echo "ns-B loopback IP";;
268         ${NSB_LO_IP6})  echo "ns-B loopback IPv6";;
269         ${NSB_LINKIP6}|${NSB_LINKIP6}%*) echo "ns-B IPv6 LLA";;
270
271         ${VRF_IP})      echo "VRF IP";;
272         ${VRF_IP6})     echo "VRF IPv6";;
273
274         ${MCAST}%*)     echo "multicast IP";;
275
276         *) echo "unknown";;
277         esac
278 }
279
280 get_linklocal()
281 {
282         local ns=$1
283         local dev=$2
284         local addr
285
286         addr=$(ip -netns ${ns} -6 -br addr show dev ${dev} | \
287         awk '{
288                 for (i = 3; i <= NF; ++i) {
289                         if ($i ~ /^fe80/)
290                                 print $i
291                 }
292         }'
293         )
294         addr=${addr/\/*}
295
296         [ -z "$addr" ] && return 1
297
298         echo $addr
299
300         return 0
301 }
302
303 ################################################################################
304 # create namespaces and vrf
305
306 create_vrf()
307 {
308         local ns=$1
309         local vrf=$2
310         local table=$3
311         local addr=$4
312         local addr6=$5
313
314         ip -netns ${ns} link add ${vrf} type vrf table ${table}
315         ip -netns ${ns} link set ${vrf} up
316         ip -netns ${ns} route add vrf ${vrf} unreachable default metric 8192
317         ip -netns ${ns} -6 route add vrf ${vrf} unreachable default metric 8192
318
319         ip -netns ${ns} addr add 127.0.0.1/8 dev ${vrf}
320         ip -netns ${ns} -6 addr add ::1 dev ${vrf} nodad
321         if [ "${addr}" != "-" ]; then
322                 ip -netns ${ns} addr add dev ${vrf} ${addr}
323         fi
324         if [ "${addr6}" != "-" ]; then
325                 ip -netns ${ns} -6 addr add dev ${vrf} ${addr6}
326         fi
327
328         ip -netns ${ns} ru del pref 0
329         ip -netns ${ns} ru add pref 32765 from all lookup local
330         ip -netns ${ns} -6 ru del pref 0
331         ip -netns ${ns} -6 ru add pref 32765 from all lookup local
332 }
333
334 create_ns()
335 {
336         local ns=$1
337         local addr=$2
338         local addr6=$3
339
340         ip netns add ${ns}
341
342         ip -netns ${ns} link set lo up
343         if [ "${addr}" != "-" ]; then
344                 ip -netns ${ns} addr add dev lo ${addr}
345         fi
346         if [ "${addr6}" != "-" ]; then
347                 ip -netns ${ns} -6 addr add dev lo ${addr6}
348         fi
349
350         ip -netns ${ns} ro add unreachable default metric 8192
351         ip -netns ${ns} -6 ro add unreachable default metric 8192
352
353         ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1
354         ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
355         ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1
356         ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1
357 }
358
359 # create veth pair to connect namespaces and apply addresses.
360 connect_ns()
361 {
362         local ns1=$1
363         local ns1_dev=$2
364         local ns1_addr=$3
365         local ns1_addr6=$4
366         local ns2=$5
367         local ns2_dev=$6
368         local ns2_addr=$7
369         local ns2_addr6=$8
370
371         ip -netns ${ns1} li add ${ns1_dev} type veth peer name tmp
372         ip -netns ${ns1} li set ${ns1_dev} up
373         ip -netns ${ns1} li set tmp netns ${ns2} name ${ns2_dev}
374         ip -netns ${ns2} li set ${ns2_dev} up
375
376         if [ "${ns1_addr}" != "-" ]; then
377                 ip -netns ${ns1} addr add dev ${ns1_dev} ${ns1_addr}
378                 ip -netns ${ns2} addr add dev ${ns2_dev} ${ns2_addr}
379         fi
380
381         if [ "${ns1_addr6}" != "-" ]; then
382                 ip -netns ${ns1} addr add dev ${ns1_dev} ${ns1_addr6}
383                 ip -netns ${ns2} addr add dev ${ns2_dev} ${ns2_addr6}
384         fi
385 }
386
387 cleanup()
388 {
389         # explicit cleanups to check those code paths
390         ip netns | grep -q ${NSA}
391         if [ $? -eq 0 ]; then
392                 ip -netns ${NSA} link delete ${VRF}
393                 ip -netns ${NSA} ro flush table ${VRF_TABLE}
394
395                 ip -netns ${NSA} addr flush dev ${NSA_DEV}
396                 ip -netns ${NSA} -6 addr flush dev ${NSA_DEV}
397                 ip -netns ${NSA} link set dev ${NSA_DEV} down
398                 ip -netns ${NSA} link del dev ${NSA_DEV}
399
400                 ip netns del ${NSA}
401         fi
402
403         ip netns del ${NSB}
404 }
405
406 setup()
407 {
408         local with_vrf=${1}
409
410         # make sure we are starting with a clean slate
411         kill_procs
412         cleanup 2>/dev/null
413
414         log_debug "Configuring network namespaces"
415         set -e
416
417         create_ns ${NSA} ${NSA_LO_IP}/32 ${NSA_LO_IP6}/128
418         create_ns ${NSB} ${NSB_LO_IP}/32 ${NSB_LO_IP6}/128
419         connect_ns ${NSA} ${NSA_DEV} ${NSA_IP}/24 ${NSA_IP6}/64 \
420                    ${NSB} ${NSB_DEV} ${NSB_IP}/24 ${NSB_IP6}/64
421
422         NSA_LINKIP6=$(get_linklocal ${NSA} ${NSA_DEV})
423         NSB_LINKIP6=$(get_linklocal ${NSB} ${NSB_DEV})
424
425         # tell ns-A how to get to remote addresses of ns-B
426         if [ "${with_vrf}" = "yes" ]; then
427                 create_vrf ${NSA} ${VRF} ${VRF_TABLE} ${VRF_IP} ${VRF_IP6}
428
429                 ip -netns ${NSA} link set dev ${NSA_DEV} vrf ${VRF}
430                 ip -netns ${NSA} ro add vrf ${VRF} ${NSB_LO_IP}/32 via ${NSB_IP} dev ${NSA_DEV}
431                 ip -netns ${NSA} -6 ro add vrf ${VRF} ${NSB_LO_IP6}/128 via ${NSB_IP6} dev ${NSA_DEV}
432
433                 ip -netns ${NSB} ro add ${VRF_IP}/32 via ${NSA_IP} dev ${NSB_DEV}
434                 ip -netns ${NSB} -6 ro add ${VRF_IP6}/128 via ${NSA_IP6} dev ${NSB_DEV}
435         else
436                 ip -netns ${NSA} ro add ${NSB_LO_IP}/32 via ${NSB_IP} dev ${NSA_DEV}
437                 ip -netns ${NSA} ro add ${NSB_LO_IP6}/128 via ${NSB_IP6} dev ${NSA_DEV}
438         fi
439
440
441         # tell ns-B how to get to remote addresses of ns-A
442         ip -netns ${NSB} ro add ${NSA_LO_IP}/32 via ${NSA_IP} dev ${NSB_DEV}
443         ip -netns ${NSB} ro add ${NSA_LO_IP6}/128 via ${NSA_IP6} dev ${NSB_DEV}
444
445         set +e
446
447         sleep 1
448 }
449
450 ################################################################################
451 # IPv4
452
453 ipv4_ping_novrf()
454 {
455         local a
456
457         #
458         # out
459         #
460         for a in ${NSB_IP} ${NSB_LO_IP}
461         do
462                 log_start
463                 run_cmd ping -c1 -w1 ${a}
464                 log_test_addr ${a} $? 0 "ping out"
465
466                 log_start
467                 run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
468                 log_test_addr ${a} $? 0 "ping out, device bind"
469
470                 log_start
471                 run_cmd ping -c1 -w1 -I ${NSA_LO_IP} ${a}
472                 log_test_addr ${a} $? 0 "ping out, address bind"
473         done
474
475         #
476         # in
477         #
478         for a in ${NSA_IP} ${NSA_LO_IP}
479         do
480                 log_start
481                 run_cmd_nsb ping -c1 -w1 ${a}
482                 log_test_addr ${a} $? 0 "ping in"
483         done
484
485         #
486         # local traffic
487         #
488         for a in ${NSA_IP} ${NSA_LO_IP} 127.0.0.1
489         do
490                 log_start
491                 run_cmd ping -c1 -w1 ${a}
492                 log_test_addr ${a} $? 0 "ping local"
493         done
494
495         #
496         # local traffic, socket bound to device
497         #
498         # address on device
499         a=${NSA_IP}
500         log_start
501         run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
502         log_test_addr ${a} $? 0 "ping local, device bind"
503
504         # loopback addresses not reachable from device bind
505         # fails in a really weird way though because ipv4 special cases
506         # route lookups with oif set.
507         for a in ${NSA_LO_IP} 127.0.0.1
508         do
509                 log_start
510                 show_hint "Fails since address on loopback device is out of device scope"
511                 run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
512                 log_test_addr ${a} $? 1 "ping local, device bind"
513         done
514
515         #
516         # ip rule blocks reachability to remote address
517         #
518         log_start
519         setup_cmd ip rule add pref 32765 from all lookup local
520         setup_cmd ip rule del pref 0 from all lookup local
521         setup_cmd ip rule add pref 50 to ${NSB_LO_IP} prohibit
522         setup_cmd ip rule add pref 51 from ${NSB_IP} prohibit
523
524         a=${NSB_LO_IP}
525         run_cmd ping -c1 -w1 ${a}
526         log_test_addr ${a} $? 2 "ping out, blocked by rule"
527
528         # NOTE: ipv4 actually allows the lookup to fail and yet still create
529         # a viable rtable if the oif (e.g., bind to device) is set, so this
530         # case succeeds despite the rule
531         # run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
532
533         a=${NSA_LO_IP}
534         log_start
535         show_hint "Response generates ICMP (or arp request is ignored) due to ip rule"
536         run_cmd_nsb ping -c1 -w1 ${a}
537         log_test_addr ${a} $? 1 "ping in, blocked by rule"
538
539         [ "$VERBOSE" = "1" ] && echo
540         setup_cmd ip rule del pref 32765 from all lookup local
541         setup_cmd ip rule add pref 0 from all lookup local
542         setup_cmd ip rule del pref 50 to ${NSB_LO_IP} prohibit
543         setup_cmd ip rule del pref 51 from ${NSB_IP} prohibit
544
545         #
546         # route blocks reachability to remote address
547         #
548         log_start
549         setup_cmd ip route replace unreachable ${NSB_LO_IP}
550         setup_cmd ip route replace unreachable ${NSB_IP}
551
552         a=${NSB_LO_IP}
553         run_cmd ping -c1 -w1 ${a}
554         log_test_addr ${a} $? 2 "ping out, blocked by route"
555
556         # NOTE: ipv4 actually allows the lookup to fail and yet still create
557         # a viable rtable if the oif (e.g., bind to device) is set, so this
558         # case succeeds despite not having a route for the address
559         # run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
560
561         a=${NSA_LO_IP}
562         log_start
563         show_hint "Response is dropped (or arp request is ignored) due to ip route"
564         run_cmd_nsb ping -c1 -w1 ${a}
565         log_test_addr ${a} $? 1 "ping in, blocked by route"
566
567         #
568         # remove 'remote' routes; fallback to default
569         #
570         log_start
571         setup_cmd ip ro del ${NSB_LO_IP}
572
573         a=${NSB_LO_IP}
574         run_cmd ping -c1 -w1 ${a}
575         log_test_addr ${a} $? 2 "ping out, unreachable default route"
576
577         # NOTE: ipv4 actually allows the lookup to fail and yet still create
578         # a viable rtable if the oif (e.g., bind to device) is set, so this
579         # case succeeds despite not having a route for the address
580         # run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
581 }
582
583 ipv4_ping_vrf()
584 {
585         local a
586
587         # should default on; does not exist on older kernels
588         set_sysctl net.ipv4.raw_l3mdev_accept=1 2>/dev/null
589
590         #
591         # out
592         #
593         for a in ${NSB_IP} ${NSB_LO_IP}
594         do
595                 log_start
596                 run_cmd ping -c1 -w1 -I ${VRF} ${a}
597                 log_test_addr ${a} $? 0 "ping out, VRF bind"
598
599                 log_start
600                 run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
601                 log_test_addr ${a} $? 0 "ping out, device bind"
602
603                 log_start
604                 run_cmd ip vrf exec ${VRF} ping -c1 -w1 -I ${NSA_IP} ${a}
605                 log_test_addr ${a} $? 0 "ping out, vrf device + dev address bind"
606
607                 log_start
608                 run_cmd ip vrf exec ${VRF} ping -c1 -w1 -I ${VRF_IP} ${a}
609                 log_test_addr ${a} $? 0 "ping out, vrf device + vrf address bind"
610         done
611
612         #
613         # in
614         #
615         for a in ${NSA_IP} ${VRF_IP}
616         do
617                 log_start
618                 run_cmd_nsb ping -c1 -w1 ${a}
619                 log_test_addr ${a} $? 0 "ping in"
620         done
621
622         #
623         # local traffic, local address
624         #
625         for a in ${NSA_IP} ${VRF_IP} 127.0.0.1
626         do
627                 log_start
628                 show_hint "Source address should be ${a}"
629                 run_cmd ping -c1 -w1 -I ${VRF} ${a}
630                 log_test_addr ${a} $? 0 "ping local, VRF bind"
631         done
632
633         #
634         # local traffic, socket bound to device
635         #
636         # address on device
637         a=${NSA_IP}
638         log_start
639         run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
640         log_test_addr ${a} $? 0 "ping local, device bind"
641
642         # vrf device is out of scope
643         for a in ${VRF_IP} 127.0.0.1
644         do
645                 log_start
646                 show_hint "Fails since address on vrf device is out of device scope"
647                 run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
648                 log_test_addr ${a} $? 1 "ping local, device bind"
649         done
650
651         #
652         # ip rule blocks address
653         #
654         log_start
655         setup_cmd ip rule add pref 50 to ${NSB_LO_IP} prohibit
656         setup_cmd ip rule add pref 51 from ${NSB_IP} prohibit
657
658         a=${NSB_LO_IP}
659         run_cmd ping -c1 -w1 -I ${VRF} ${a}
660         log_test_addr ${a} $? 2 "ping out, vrf bind, blocked by rule"
661
662         log_start
663         run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
664         log_test_addr ${a} $? 2 "ping out, device bind, blocked by rule"
665
666         a=${NSA_LO_IP}
667         log_start
668         show_hint "Response lost due to ip rule"
669         run_cmd_nsb ping -c1 -w1 ${a}
670         log_test_addr ${a} $? 1 "ping in, blocked by rule"
671
672         [ "$VERBOSE" = "1" ] && echo
673         setup_cmd ip rule del pref 50 to ${NSB_LO_IP} prohibit
674         setup_cmd ip rule del pref 51 from ${NSB_IP} prohibit
675
676         #
677         # remove 'remote' routes; fallback to default
678         #
679         log_start
680         setup_cmd ip ro del vrf ${VRF} ${NSB_LO_IP}
681
682         a=${NSB_LO_IP}
683         run_cmd ping -c1 -w1 -I ${VRF} ${a}
684         log_test_addr ${a} $? 2 "ping out, vrf bind, unreachable route"
685
686         log_start
687         run_cmd ping -c1 -w1 -I ${NSA_DEV} ${a}
688         log_test_addr ${a} $? 2 "ping out, device bind, unreachable route"
689
690         a=${NSA_LO_IP}
691         log_start
692         show_hint "Response lost by unreachable route"
693         run_cmd_nsb ping -c1 -w1 ${a}
694         log_test_addr ${a} $? 1 "ping in, unreachable route"
695 }
696
697 ipv4_ping()
698 {
699         log_section "IPv4 ping"
700
701         log_subsection "No VRF"
702         setup
703         set_sysctl net.ipv4.raw_l3mdev_accept=0 2>/dev/null
704         ipv4_ping_novrf
705         setup
706         set_sysctl net.ipv4.raw_l3mdev_accept=1 2>/dev/null
707         ipv4_ping_novrf
708
709         log_subsection "With VRF"
710         setup "yes"
711         ipv4_ping_vrf
712 }
713
714 ################################################################################
715 # IPv6
716
717 ipv6_ping_novrf()
718 {
719         local a
720
721         # should not have an impact, but make a known state
722         set_sysctl net.ipv4.raw_l3mdev_accept=0 2>/dev/null
723
724         #
725         # out
726         #
727         for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
728         do
729                 log_start
730                 run_cmd ${ping6} -c1 -w1 ${a}
731                 log_test_addr ${a} $? 0 "ping out"
732         done
733
734         for a in ${NSB_IP6} ${NSB_LO_IP6}
735         do
736                 log_start
737                 run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
738                 log_test_addr ${a} $? 0 "ping out, device bind"
739
740                 log_start
741                 run_cmd ${ping6} -c1 -w1 -I ${NSA_LO_IP6} ${a}
742                 log_test_addr ${a} $? 0 "ping out, loopback address bind"
743         done
744
745         #
746         # in
747         #
748         for a in ${NSA_IP6} ${NSA_LO_IP6} ${NSA_LINKIP6}%${NSB_DEV} ${MCAST}%${NSB_DEV}
749         do
750                 log_start
751                 run_cmd_nsb ${ping6} -c1 -w1 ${a}
752                 log_test_addr ${a} $? 0 "ping in"
753         done
754
755         #
756         # local traffic, local address
757         #
758         for a in ${NSA_IP6} ${NSA_LO_IP6} ::1 ${NSA_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
759         do
760                 log_start
761                 run_cmd ${ping6} -c1 -w1 ${a}
762                 log_test_addr ${a} $? 0 "ping local, no bind"
763         done
764
765         for a in ${NSA_IP6} ${NSA_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
766         do
767                 log_start
768                 run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
769                 log_test_addr ${a} $? 0 "ping local, device bind"
770         done
771
772         for a in ${NSA_LO_IP6} ::1
773         do
774                 log_start
775                 show_hint "Fails since address on loopback is out of device scope"
776                 run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
777                 log_test_addr ${a} $? 2 "ping local, device bind"
778         done
779
780         #
781         # ip rule blocks address
782         #
783         log_start
784         setup_cmd ip -6 rule add pref 32765 from all lookup local
785         setup_cmd ip -6 rule del pref 0 from all lookup local
786         setup_cmd ip -6 rule add pref 50 to ${NSB_LO_IP6} prohibit
787         setup_cmd ip -6 rule add pref 51 from ${NSB_IP6} prohibit
788
789         a=${NSB_LO_IP6}
790         run_cmd ${ping6} -c1 -w1 ${a}
791         log_test_addr ${a} $? 2 "ping out, blocked by rule"
792
793         log_start
794         run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
795         log_test_addr ${a} $? 2 "ping out, device bind, blocked by rule"
796
797         a=${NSA_LO_IP6}
798         log_start
799         show_hint "Response lost due to ip rule"
800         run_cmd_nsb ${ping6} -c1 -w1 ${a}
801         log_test_addr ${a} $? 1 "ping in, blocked by rule"
802
803         setup_cmd ip -6 rule add pref 0 from all lookup local
804         setup_cmd ip -6 rule del pref 32765 from all lookup local
805         setup_cmd ip -6 rule del pref 50 to ${NSB_LO_IP6} prohibit
806         setup_cmd ip -6 rule del pref 51 from ${NSB_IP6} prohibit
807
808         #
809         # route blocks reachability to remote address
810         #
811         log_start
812         setup_cmd ip -6 route del ${NSB_LO_IP6}
813         setup_cmd ip -6 route add unreachable ${NSB_LO_IP6} metric 10
814         setup_cmd ip -6 route add unreachable ${NSB_IP6} metric 10
815
816         a=${NSB_LO_IP6}
817         run_cmd ${ping6} -c1 -w1 ${a}
818         log_test_addr ${a} $? 2 "ping out, blocked by route"
819
820         log_start
821         run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
822         log_test_addr ${a} $? 2 "ping out, device bind, blocked by route"
823
824         a=${NSA_LO_IP6}
825         log_start
826         show_hint "Response lost due to ip route"
827         run_cmd_nsb ${ping6} -c1 -w1 ${a}
828         log_test_addr ${a} $? 1 "ping in, blocked by route"
829
830
831         #
832         # remove 'remote' routes; fallback to default
833         #
834         log_start
835         setup_cmd ip -6 ro del unreachable ${NSB_LO_IP6}
836         setup_cmd ip -6 ro del unreachable ${NSB_IP6}
837
838         a=${NSB_LO_IP6}
839         run_cmd ${ping6} -c1 -w1 ${a}
840         log_test_addr ${a} $? 2 "ping out, unreachable route"
841
842         log_start
843         run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
844         log_test_addr ${a} $? 2 "ping out, device bind, unreachable route"
845 }
846
847 ipv6_ping_vrf()
848 {
849         local a
850
851         # should default on; does not exist on older kernels
852         set_sysctl net.ipv4.raw_l3mdev_accept=1 2>/dev/null
853
854         #
855         # out
856         #
857         for a in ${NSB_IP6} ${NSB_LO_IP6}
858         do
859                 log_start
860                 run_cmd ${ping6} -c1 -w1 -I ${VRF} ${a}
861                 log_test_addr ${a} $? 0 "ping out, VRF bind"
862         done
863
864         for a in ${NSB_LINKIP6}%${VRF} ${MCAST}%${VRF}
865         do
866                 log_start
867                 show_hint "Fails since VRF device does not support linklocal or multicast"
868                 run_cmd ${ping6} -c1 -w1 ${a}
869                 log_test_addr ${a} $? 2 "ping out, VRF bind"
870         done
871
872         for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
873         do
874                 log_start
875                 run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
876                 log_test_addr ${a} $? 0 "ping out, device bind"
877         done
878
879         for a in ${NSB_IP6} ${NSB_LO_IP6} ${NSB_LINKIP6}%${NSA_DEV}
880         do
881                 log_start
882                 run_cmd ip vrf exec ${VRF} ${ping6} -c1 -w1 -I ${VRF_IP6} ${a}
883                 log_test_addr ${a} $? 0 "ping out, vrf device+address bind"
884         done
885
886         #
887         # in
888         #
889         for a in ${NSA_IP6} ${VRF_IP6} ${NSA_LINKIP6}%${NSB_DEV} ${MCAST}%${NSB_DEV}
890         do
891                 log_start
892                 run_cmd_nsb ${ping6} -c1 -w1 ${a}
893                 log_test_addr ${a} $? 0 "ping in"
894         done
895
896         a=${NSA_LO_IP6}
897         log_start
898         show_hint "Fails since loopback address is out of VRF scope"
899         run_cmd_nsb ${ping6} -c1 -w1 ${a}
900         log_test_addr ${a} $? 1 "ping in"
901
902         #
903         # local traffic, local address
904         #
905         for a in ${NSA_IP6} ${VRF_IP6} ::1
906         do
907                 log_start
908                 show_hint "Source address should be ${a}"
909                 run_cmd ${ping6} -c1 -w1 -I ${VRF} ${a}
910                 log_test_addr ${a} $? 0 "ping local, VRF bind"
911         done
912
913         for a in ${NSA_IP6} ${NSA_LINKIP6}%${NSA_DEV} ${MCAST}%${NSA_DEV}
914         do
915                 log_start
916                 run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
917                 log_test_addr ${a} $? 0 "ping local, device bind"
918         done
919
920         # LLA to GUA - remove ipv6 global addresses from ns-B
921         setup_cmd_nsb ip -6 addr del ${NSB_IP6}/64 dev ${NSB_DEV}
922         setup_cmd_nsb ip -6 addr del ${NSB_LO_IP6}/128 dev lo
923         setup_cmd_nsb ip -6 ro add ${NSA_IP6}/128 via ${NSA_LINKIP6} dev ${NSB_DEV}
924
925         for a in ${NSA_IP6} ${VRF_IP6}
926         do
927                 log_start
928                 run_cmd_nsb ${ping6} -c1 -w1 ${NSA_IP6}
929                 log_test_addr ${a} $? 0 "ping in, LLA to GUA"
930         done
931
932         setup_cmd_nsb ip -6 ro del ${NSA_IP6}/128 via ${NSA_LINKIP6} dev ${NSB_DEV}
933         setup_cmd_nsb ip -6 addr add ${NSB_IP6}/64 dev ${NSB_DEV}
934         setup_cmd_nsb ip -6 addr add ${NSB_LO_IP6}/128 dev lo
935
936         #
937         # ip rule blocks address
938         #
939         log_start
940         setup_cmd ip -6 rule add pref 50 to ${NSB_LO_IP6} prohibit
941         setup_cmd ip -6 rule add pref 51 from ${NSB_IP6} prohibit
942
943         a=${NSB_LO_IP6}
944         run_cmd ${ping6} -c1 -w1 ${a}
945         log_test_addr ${a} $? 2 "ping out, blocked by rule"
946
947         log_start
948         run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
949         log_test_addr ${a} $? 2 "ping out, device bind, blocked by rule"
950
951         a=${NSA_LO_IP6}
952         log_start
953         show_hint "Response lost due to ip rule"
954         run_cmd_nsb ${ping6} -c1 -w1 ${a}
955         log_test_addr ${a} $? 1 "ping in, blocked by rule"
956
957         log_start
958         setup_cmd ip -6 rule del pref 50 to ${NSB_LO_IP6} prohibit
959         setup_cmd ip -6 rule del pref 51 from ${NSB_IP6} prohibit
960
961         #
962         # remove 'remote' routes; fallback to default
963         #
964         log_start
965         setup_cmd ip -6 ro del ${NSB_LO_IP6} vrf ${VRF}
966
967         a=${NSB_LO_IP6}
968         run_cmd ${ping6} -c1 -w1 ${a}
969         log_test_addr ${a} $? 2 "ping out, unreachable route"
970
971         log_start
972         run_cmd ${ping6} -c1 -w1 -I ${NSA_DEV} ${a}
973         log_test_addr ${a} $? 2 "ping out, device bind, unreachable route"
974
975         ip -netns ${NSB} -6 ro del ${NSA_LO_IP6}
976         a=${NSA_LO_IP6}
977         log_start
978         run_cmd_nsb ${ping6} -c1 -w1 ${a}
979         log_test_addr ${a} $? 2 "ping in, unreachable route"
980 }
981
982 ipv6_ping()
983 {
984         log_section "IPv6 ping"
985
986         log_subsection "No VRF"
987         setup
988         ipv6_ping_novrf
989
990         log_subsection "With VRF"
991         setup "yes"
992         ipv6_ping_vrf
993 }
994
995 ################################################################################
996 # usage
997
998 usage()
999 {
1000         cat <<EOF
1001 usage: ${0##*/} OPTS
1002
1003         -4          IPv4 tests only
1004         -6          IPv6 tests only
1005         -t <test>   Test name/set to run
1006         -p          Pause on fail
1007         -P          Pause after each test
1008         -v          Be verbose
1009 EOF
1010 }
1011
1012 ################################################################################
1013 # main
1014
1015 TESTS_IPV4="ipv4_ping"
1016 TESTS_IPV6="ipv6_ping"
1017 PAUSE_ON_FAIL=no
1018 PAUSE=no
1019
1020 while getopts :46t:pPvh o
1021 do
1022         case $o in
1023                 4) TESTS=ipv4;;
1024                 6) TESTS=ipv6;;
1025                 t) TESTS=$OPTARG;;
1026                 p) PAUSE_ON_FAIL=yes;;
1027                 P) PAUSE=yes;;
1028                 v) VERBOSE=1;;
1029                 h) usage; exit 0;;
1030                 *) usage; exit 1;;
1031         esac
1032 done
1033
1034 # make sure we don't pause twice
1035 [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
1036
1037 #
1038 # show user test config
1039 #
1040 if [ -z "$TESTS" ]; then
1041         TESTS="$TESTS_IPV4 $TESTS_IPV6 $TESTS_OTHER"
1042 elif [ "$TESTS" = "ipv4" ]; then
1043         TESTS="$TESTS_IPV4"
1044 elif [ "$TESTS" = "ipv6" ]; then
1045         TESTS="$TESTS_IPV6"
1046 fi
1047
1048 declare -i nfail=0
1049 declare -i nsuccess=0
1050
1051 for t in $TESTS
1052 do
1053         case $t in
1054         ipv4_ping|ping)  ipv4_ping;;
1055         ipv6_ping|ping6) ipv6_ping;;
1056
1057         # setup namespaces and config, but do not run any tests
1058         setup)           setup; exit 0;;
1059         vrf_setup)       setup "yes"; exit 0;;
1060
1061         help)            echo "Test names: $TESTS"; exit 0;;
1062         esac
1063 done
1064
1065 cleanup 2>/dev/null
1066
1067 printf "\nTests passed: %3d\n" ${nsuccess}
1068 printf "Tests failed: %3d\n"   ${nfail}