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