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