WIP FPC-III support
[linux/fpc-iii.git] / tools / testing / selftests / net / fib-onlink-tests.sh
blobc287b90b8af80af5fb3d9b426f4aeb6af1ff74b2
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
4 # IPv4 and IPv6 onlink tests
6 PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
7 VERBOSE=0
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
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
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
45 # Test networks:
46 # [1] = default table
47 # [2] = VRF
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
58 # connected gateway
59 CONGW[1]=169.254.1.254
60 CONGW[2]=169.254.3.254
61 CONGW[3]=169.254.5.254
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
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
74 # mcast address
75 MCAST6=ff02::1
78 PEER_NS=bart
79 PEER_CMD="ip netns exec ${PEER_NS}"
80 VRF=lisa
81 VRF_TABLE=1101
82 PBR_TABLE=101
84 ################################################################################
85 # utilities
87 log_test()
89 local rc=$1
90 local expected=$2
91 local msg="$3"
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
108 log_section()
110 echo
111 echo "######################################################################"
112 echo "TEST SECTION: $*"
113 echo "######################################################################"
116 log_subsection()
118 echo
119 echo "#########################################"
120 echo "TEST SUBSECTION: $*"
123 run_cmd()
125 local cmd="$*"
126 local out
127 local rc
129 if [ "$VERBOSE" = "1" ]; then
130 printf " COMMAND: $cmd\n"
133 out=$(eval $cmd 2>&1)
134 rc=$?
135 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
136 echo " $out"
139 [ "$VERBOSE" = "1" ] && echo
141 return $rc
144 get_linklocal()
146 local dev=$1
147 local pfx
148 local addr
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
158 addr=${addr/\/*}
160 [ -z "$addr" ] && return 1
162 echo $addr
164 return 0
167 ################################################################################
170 setup()
172 echo
173 echo "########################################"
174 echo "Configuring interfaces"
176 set -e
178 # create namespace
179 ip netns add ${PEER_NS}
180 ip -netns ${PEER_NS} li set lo up
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
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]}
194 # enslave vrf interfaces
195 for n in 5 7; do
196 ip li set ${NETIFS[p${n}]} vrf ${VRF}
197 done
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
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
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}
216 set +e
219 cleanup()
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}
231 ################################################################################
232 # IPv4 tests
235 run_ip()
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"
244 # dev arg may be empty
245 [ -n "${dev}" ] && dev="dev ${dev}"
247 run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink
248 log_test $? ${exp_rc} "${desc}"
251 run_ip_mpath()
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"
260 # dev arg may be empty
261 [ -n "${dev}" ] && dev="dev ${dev}"
263 run_cmd ip ro add table "${table}" "${prefix}"/32 \
264 nexthop via ${nh1} nexthop via ${nh2}
265 log_test $? ${exp_rc} "${desc}"
268 valid_onlink_ipv4()
270 # - unicast connected, unicast recursive
272 log_subsection "default VRF - main table"
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"
277 log_subsection "VRF ${VRF}"
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"
282 log_subsection "VRF device, PBR table"
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"
287 # multipath version
289 log_subsection "default VRF - main table - multipath"
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"
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"
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"
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"
312 invalid_onlink_ipv4()
314 run_ip 254 ${TEST_NET4[1]}.11 ${V4ADDRS[p1]} ${NETIFS[p1]} 2 \
315 "Invalid gw - local unicast address"
317 run_ip ${VRF_TABLE} ${TEST_NET4[2]}.11 ${V4ADDRS[p5]} ${NETIFS[p5]} 2 \
318 "Invalid gw - local unicast address, VRF"
320 run_ip 254 ${TEST_NET4[1]}.101 ${V4ADDRS[p1]} "" 2 "No nexthop device given"
322 run_ip 254 ${TEST_NET4[1]}.102 ${V4ADDRS[p3]} ${NETIFS[p1]} 2 \
323 "Gateway resolves to wrong nexthop device"
325 run_ip ${VRF_TABLE} ${TEST_NET4[2]}.103 ${V4ADDRS[p7]} ${NETIFS[p5]} 2 \
326 "Gateway resolves to wrong nexthop device - VRF"
329 ################################################################################
330 # IPv6 tests
333 run_ip6()
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"
342 # dev arg may be empty
343 [ -n "${dev}" ] && dev="dev ${dev}"
345 run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink
346 log_test $? ${exp_rc} "${desc}"
349 run_ip6_mpath()
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"
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}"
364 valid_onlink_ipv6()
366 # - unicast connected, unicast recursive, v4-mapped
368 log_subsection "default VRF - main table"
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"
374 log_subsection "VRF ${VRF}"
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"
380 log_subsection "VRF device, PBR table"
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"
386 # multipath version
388 log_subsection "default VRF - main table - multipath"
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"
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"
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"
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"
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"
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"
421 invalid_onlink_ipv6()
423 local lladdr
425 lladdr=$(get_linklocal ${NETIFS[p1]}) || return 1
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"
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"
442 run_ip6 254 ${TEST_NET6[1]}::101 ${V6ADDRS[p1]} "" 2 \
443 "No nexthop device given"
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"
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"
453 run_onlink_tests()
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
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
468 ################################################################################
469 # usage
471 usage()
473 cat <<EOF
474 usage: ${0##*/} OPTS
476 -p Pause on fail
477 -v verbose mode (show commands and output)
481 ################################################################################
482 # main
484 nsuccess=0
485 nfail=0
487 while getopts :t:pPhv o
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
497 cleanup
498 setup
499 run_onlink_tests
500 cleanup
502 if [ "$TESTS" != "none" ]; then
503 printf "\nTests passed: %3d\n" ${nsuccess}
504 printf "Tests failed: %3d\n" ${nfail}