Merge tag 'x86_bugs_retbleed' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-2.6-microblaze.git] / tools / testing / selftests / net / fib-onlink-tests.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 # IPv4 and IPv6 onlink tests
5
6 PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
7 VERBOSE=0
8
9 # Network interfaces
10 # - odd in current namespace; even in peer ns
11 declare -A NETIFS
12 # default VRF
13 NETIFS[p1]=veth1
14 NETIFS[p2]=veth2
15 NETIFS[p3]=veth3
16 NETIFS[p4]=veth4
17 # VRF
18 NETIFS[p5]=veth5
19 NETIFS[p6]=veth6
20 NETIFS[p7]=veth7
21 NETIFS[p8]=veth8
22
23 # /24 network
24 declare -A V4ADDRS
25 V4ADDRS[p1]=169.254.1.1
26 V4ADDRS[p2]=169.254.1.2
27 V4ADDRS[p3]=169.254.3.1
28 V4ADDRS[p4]=169.254.3.2
29 V4ADDRS[p5]=169.254.5.1
30 V4ADDRS[p6]=169.254.5.2
31 V4ADDRS[p7]=169.254.7.1
32 V4ADDRS[p8]=169.254.7.2
33
34 # /64 network
35 declare -A V6ADDRS
36 V6ADDRS[p1]=2001:db8:101::1
37 V6ADDRS[p2]=2001:db8:101::2
38 V6ADDRS[p3]=2001:db8:301::1
39 V6ADDRS[p4]=2001:db8:301::2
40 V6ADDRS[p5]=2001:db8:501::1
41 V6ADDRS[p6]=2001:db8:501::2
42 V6ADDRS[p7]=2001:db8:701::1
43 V6ADDRS[p8]=2001:db8:701::2
44
45 # Test networks:
46 # [1] = default table
47 # [2] = VRF
48 #
49 # /32 host routes
50 declare -A TEST_NET4
51 TEST_NET4[1]=169.254.101
52 TEST_NET4[2]=169.254.102
53 # /128 host routes
54 declare -A TEST_NET6
55 TEST_NET6[1]=2001:db8:101
56 TEST_NET6[2]=2001:db8:102
57
58 # connected gateway
59 CONGW[1]=169.254.1.254
60 CONGW[2]=169.254.3.254
61 CONGW[3]=169.254.5.254
62
63 # recursive gateway
64 RECGW4[1]=169.254.11.254
65 RECGW4[2]=169.254.12.254
66 RECGW6[1]=2001:db8:11::64
67 RECGW6[2]=2001:db8:12::64
68
69 # for v4 mapped to v6
70 declare -A TEST_NET4IN6IN6
71 TEST_NET4IN6[1]=10.1.1.254
72 TEST_NET4IN6[2]=10.2.1.254
73
74 # mcast address
75 MCAST6=ff02::1
76
77
78 PEER_NS=bart
79 PEER_CMD="ip netns exec ${PEER_NS}"
80 VRF=lisa
81 VRF_TABLE=1101
82 PBR_TABLE=101
83
84 ################################################################################
85 # utilities
86
87 log_test()
88 {
89         local rc=$1
90         local expected=$2
91         local msg="$3"
92
93         if [ ${rc} -eq ${expected} ]; then
94                 nsuccess=$((nsuccess+1))
95                 printf "    TEST: %-50s  [ OK ]\n" "${msg}"
96         else
97                 nfail=$((nfail+1))
98                 printf "    TEST: %-50s  [FAIL]\n" "${msg}"
99                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
100                         echo
101                         echo "hit enter to continue, 'q' to quit"
102                         read a
103                         [ "$a" = "q" ] && exit 1
104                 fi
105         fi
106 }
107
108 log_section()
109 {
110         echo
111         echo "######################################################################"
112         echo "TEST SECTION: $*"
113         echo "######################################################################"
114 }
115
116 log_subsection()
117 {
118         echo
119         echo "#########################################"
120         echo "TEST SUBSECTION: $*"
121 }
122
123 run_cmd()
124 {
125         local cmd="$*"
126         local out
127         local rc
128
129         if [ "$VERBOSE" = "1" ]; then
130                 printf "    COMMAND: $cmd\n"
131         fi
132
133         out=$(eval $cmd 2>&1)
134         rc=$?
135         if [ "$VERBOSE" = "1" -a -n "$out" ]; then
136                 echo "    $out"
137         fi
138
139         [ "$VERBOSE" = "1" ] && echo
140
141         return $rc
142 }
143
144 get_linklocal()
145 {
146         local dev=$1
147         local pfx
148         local addr
149
150         addr=$(${pfx} ip -6 -br addr show dev ${dev} | \
151         awk '{
152                 for (i = 3; i <= NF; ++i) {
153                         if ($i ~ /^fe80/)
154                                 print $i
155                 }
156         }'
157         )
158         addr=${addr/\/*}
159
160         [ -z "$addr" ] && return 1
161
162         echo $addr
163
164         return 0
165 }
166
167 ################################################################################
168 #
169
170 setup()
171 {
172         echo
173         echo "########################################"
174         echo "Configuring interfaces"
175
176         set -e
177
178         # create namespace
179         ip netns add ${PEER_NS}
180         ip -netns ${PEER_NS} li set lo up
181
182         # add vrf table
183         ip li add ${VRF} type vrf table ${VRF_TABLE}
184         ip li set ${VRF} up
185         ip ro add table ${VRF_TABLE} unreachable default metric 8192
186         ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192
187
188         # create test interfaces
189         ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
190         ip li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]}
191         ip li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]}
192         ip li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]}
193
194         # enslave vrf interfaces
195         for n in 5 7; do
196                 ip li set ${NETIFS[p${n}]} vrf ${VRF}
197         done
198
199         # add addresses
200         for n in 1 3 5 7; do
201                 ip li set ${NETIFS[p${n}]} up
202                 ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
203                 ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
204         done
205
206         # move peer interfaces to namespace and add addresses
207         for n in 2 4 6 8; do
208                 ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up
209                 ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
210                 ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
211         done
212
213         ip -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64}
214         ip -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64}
215
216         set +e
217 }
218
219 cleanup()
220 {
221         # make sure we start from a clean slate
222         ip netns del ${PEER_NS} 2>/dev/null
223         for n in 1 3 5 7; do
224                 ip link del ${NETIFS[p${n}]} 2>/dev/null
225         done
226         ip link del ${VRF} 2>/dev/null
227         ip ro flush table ${VRF_TABLE}
228         ip -6 ro flush table ${VRF_TABLE}
229 }
230
231 ################################################################################
232 # IPv4 tests
233 #
234
235 run_ip()
236 {
237         local table="$1"
238         local prefix="$2"
239         local gw="$3"
240         local dev="$4"
241         local exp_rc="$5"
242         local desc="$6"
243
244         # dev arg may be empty
245         [ -n "${dev}" ] && dev="dev ${dev}"
246
247         run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink
248         log_test $? ${exp_rc} "${desc}"
249 }
250
251 run_ip_mpath()
252 {
253         local table="$1"
254         local prefix="$2"
255         local nh1="$3"
256         local nh2="$4"
257         local exp_rc="$5"
258         local desc="$6"
259
260         # dev arg may be empty
261         [ -n "${dev}" ] && dev="dev ${dev}"
262
263         run_cmd ip ro add table "${table}" "${prefix}"/32 \
264                 nexthop via ${nh1} nexthop via ${nh2}
265         log_test $? ${exp_rc} "${desc}"
266 }
267
268 valid_onlink_ipv4()
269 {
270         # - unicast connected, unicast recursive
271         #
272         log_subsection "default VRF - main table"
273
274         run_ip 254 ${TEST_NET4[1]}.1 ${CONGW[1]} ${NETIFS[p1]} 0 "unicast connected"
275         run_ip 254 ${TEST_NET4[1]}.2 ${RECGW4[1]} ${NETIFS[p1]} 0 "unicast recursive"
276
277         log_subsection "VRF ${VRF}"
278
279         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.1 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
280         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.2 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
281
282         log_subsection "VRF device, PBR table"
283
284         run_ip ${PBR_TABLE} ${TEST_NET4[2]}.3 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
285         run_ip ${PBR_TABLE} ${TEST_NET4[2]}.4 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
286
287         # multipath version
288         #
289         log_subsection "default VRF - main table - multipath"
290
291         run_ip_mpath 254 ${TEST_NET4[1]}.5 \
292                 "${CONGW[1]} dev ${NETIFS[p1]} onlink" \
293                 "${CONGW[2]} dev ${NETIFS[p3]} onlink" \
294                 0 "unicast connected - multipath"
295
296         run_ip_mpath 254 ${TEST_NET4[1]}.6 \
297                 "${RECGW4[1]} dev ${NETIFS[p1]} onlink" \
298                 "${RECGW4[2]} dev ${NETIFS[p3]} onlink" \
299                 0 "unicast recursive - multipath"
300
301         run_ip_mpath 254 ${TEST_NET4[1]}.7 \
302                 "${CONGW[1]} dev ${NETIFS[p1]}"        \
303                 "${CONGW[2]} dev ${NETIFS[p3]} onlink" \
304                 0 "unicast connected - multipath onlink first only"
305
306         run_ip_mpath 254 ${TEST_NET4[1]}.8 \
307                 "${CONGW[1]} dev ${NETIFS[p1]} onlink" \
308                 "${CONGW[2]} dev ${NETIFS[p3]}"        \
309                 0 "unicast connected - multipath onlink second only"
310 }
311
312 invalid_onlink_ipv4()
313 {
314         run_ip 254 ${TEST_NET4[1]}.11 ${V4ADDRS[p1]} ${NETIFS[p1]} 2 \
315                 "Invalid gw - local unicast address"
316
317         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.11 ${V4ADDRS[p5]} ${NETIFS[p5]} 2 \
318                 "Invalid gw - local unicast address, VRF"
319
320         run_ip 254 ${TEST_NET4[1]}.101 ${V4ADDRS[p1]} "" 2 "No nexthop device given"
321
322         run_ip 254 ${TEST_NET4[1]}.102 ${V4ADDRS[p3]} ${NETIFS[p1]} 2 \
323                 "Gateway resolves to wrong nexthop device"
324
325         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.103 ${V4ADDRS[p7]} ${NETIFS[p5]} 2 \
326                 "Gateway resolves to wrong nexthop device - VRF"
327 }
328
329 ################################################################################
330 # IPv6 tests
331 #
332
333 run_ip6()
334 {
335         local table="$1"
336         local prefix="$2"
337         local gw="$3"
338         local dev="$4"
339         local exp_rc="$5"
340         local desc="$6"
341
342         # dev arg may be empty
343         [ -n "${dev}" ] && dev="dev ${dev}"
344
345         run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink
346         log_test $? ${exp_rc} "${desc}"
347 }
348
349 run_ip6_mpath()
350 {
351         local table="$1"
352         local prefix="$2"
353         local opts="$3"
354         local nh1="$4"
355         local nh2="$5"
356         local exp_rc="$6"
357         local desc="$7"
358
359         run_cmd ip -6 ro add table "${table}" "${prefix}"/128 "${opts}" \
360                 nexthop via ${nh1} nexthop via ${nh2}
361         log_test $? ${exp_rc} "${desc}"
362 }
363
364 valid_onlink_ipv6()
365 {
366         # - unicast connected, unicast recursive, v4-mapped
367         #
368         log_subsection "default VRF - main table"
369
370         run_ip6 254 ${TEST_NET6[1]}::1 ${V6ADDRS[p1]/::*}::64 ${NETIFS[p1]} 0 "unicast connected"
371         run_ip6 254 ${TEST_NET6[1]}::2 ${RECGW6[1]} ${NETIFS[p1]} 0 "unicast recursive"
372         run_ip6 254 ${TEST_NET6[1]}::3 ::ffff:${TEST_NET4IN6[1]} ${NETIFS[p1]} 0 "v4-mapped"
373
374         log_subsection "VRF ${VRF}"
375
376         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::1 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
377         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::2 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
378         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::3 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
379
380         log_subsection "VRF device, PBR table"
381
382         run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::4 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
383         run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::5 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
384         run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::6 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
385
386         # multipath version
387         #
388         log_subsection "default VRF - main table - multipath"
389
390         run_ip6_mpath 254 ${TEST_NET6[1]}::4 "onlink" \
391                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}" \
392                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
393                 0 "unicast connected - multipath onlink"
394
395         run_ip6_mpath 254 ${TEST_NET6[1]}::5 "onlink" \
396                 "${RECGW6[1]} dev ${NETIFS[p1]}" \
397                 "${RECGW6[2]} dev ${NETIFS[p3]}" \
398                 0 "unicast recursive - multipath onlink"
399
400         run_ip6_mpath 254 ${TEST_NET6[1]}::6 "onlink" \
401                 "::ffff:${TEST_NET4IN6[1]} dev ${NETIFS[p1]}" \
402                 "::ffff:${TEST_NET4IN6[2]} dev ${NETIFS[p3]}" \
403                 0 "v4-mapped - multipath onlink"
404
405         run_ip6_mpath 254 ${TEST_NET6[1]}::7 "" \
406                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
407                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
408                 0 "unicast connected - multipath onlink both nexthops"
409
410         run_ip6_mpath 254 ${TEST_NET6[1]}::8 "" \
411                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
412                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
413                 0 "unicast connected - multipath onlink first only"
414
415         run_ip6_mpath 254 ${TEST_NET6[1]}::9 "" \
416                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}"        \
417                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
418                 0 "unicast connected - multipath onlink second only"
419 }
420
421 invalid_onlink_ipv6()
422 {
423         local lladdr
424
425         lladdr=$(get_linklocal ${NETIFS[p1]}) || return 1
426
427         run_ip6 254 ${TEST_NET6[1]}::11 ${V6ADDRS[p1]} ${NETIFS[p1]} 2 \
428                 "Invalid gw - local unicast address"
429         run_ip6 254 ${TEST_NET6[1]}::12 ${lladdr} ${NETIFS[p1]} 2 \
430                 "Invalid gw - local linklocal address"
431         run_ip6 254 ${TEST_NET6[1]}::12 ${MCAST6} ${NETIFS[p1]} 2 \
432                 "Invalid gw - multicast address"
433
434         lladdr=$(get_linklocal ${NETIFS[p5]}) || return 1
435         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::11 ${V6ADDRS[p5]} ${NETIFS[p5]} 2 \
436                 "Invalid gw - local unicast address, VRF"
437         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${lladdr} ${NETIFS[p5]} 2 \
438                 "Invalid gw - local linklocal address, VRF"
439         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${MCAST6} ${NETIFS[p5]} 2 \
440                 "Invalid gw - multicast address, VRF"
441
442         run_ip6 254 ${TEST_NET6[1]}::101 ${V6ADDRS[p1]} "" 2 \
443                 "No nexthop device given"
444
445         # default VRF validation is done against LOCAL table
446         # run_ip6 254 ${TEST_NET6[1]}::102 ${V6ADDRS[p3]/::[0-9]/::64} ${NETIFS[p1]} 2 \
447         #       "Gateway resolves to wrong nexthop device"
448
449         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::103 ${V6ADDRS[p7]/::[0-9]/::64} ${NETIFS[p5]} 2 \
450                 "Gateway resolves to wrong nexthop device - VRF"
451 }
452
453 run_onlink_tests()
454 {
455         log_section "IPv4 onlink"
456         log_subsection "Valid onlink commands"
457         valid_onlink_ipv4
458         log_subsection "Invalid onlink commands"
459         invalid_onlink_ipv4
460
461         log_section "IPv6 onlink"
462         log_subsection "Valid onlink commands"
463         valid_onlink_ipv6
464         log_subsection "Invalid onlink commands"
465         invalid_onlink_ipv6
466 }
467
468 ################################################################################
469 # usage
470
471 usage()
472 {
473         cat <<EOF
474 usage: ${0##*/} OPTS
475
476         -p          Pause on fail
477         -v          verbose mode (show commands and output)
478 EOF
479 }
480
481 ################################################################################
482 # main
483
484 nsuccess=0
485 nfail=0
486
487 while getopts :t:pPhv o
488 do
489         case $o in
490                 p) PAUSE_ON_FAIL=yes;;
491                 v) VERBOSE=$(($VERBOSE + 1));;
492                 h) usage; exit 0;;
493                 *) usage; exit 1;;
494         esac
495 done
496
497 cleanup
498 setup
499 run_onlink_tests
500 cleanup
501
502 if [ "$TESTS" != "none" ]; then
503         printf "\nTests passed: %3d\n" ${nsuccess}
504         printf "Tests failed: %3d\n"   ${nfail}
505 fi