2 # SPDX-License-Identifier: GPL-2.0
4 # IPv4 and IPv6 onlink tests
6 PAUSE_ON_FAIL
=${PAUSE_ON_FAIL:=no}
10 # - odd in current namespace; even in peer ns
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
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
51 TEST_NET4
[1]=169.254.101
52 TEST_NET4
[2]=169.254.102
55 TEST_NET6
[1]=2001:db8
:101
56 TEST_NET6
[2]=2001:db8
:102
59 CONGW
[1]=169.254.1.254
60 CONGW
[2]=169.254.3.254
61 CONGW
[3]=169.254.5.254
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
70 declare -A TEST_NET4IN6IN6
71 TEST_NET4IN6
[1]=10.1.1.254
72 TEST_NET4IN6
[2]=10.2.1.254
79 PEER_CMD
="ip netns exec ${PEER_NS}"
84 ################################################################################
93 if [ ${rc} -eq ${expected} ]; then
94 nsuccess
=$
((nsuccess
+1))
95 printf " TEST: %-50s [ OK ]\n" "${msg}"
98 printf " TEST: %-50s [FAIL]\n" "${msg}"
99 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
101 echo "hit enter to continue, 'q' to quit"
103 [ "$a" = "q" ] && exit 1
111 echo "######################################################################"
112 echo "TEST SECTION: $*"
113 echo "######################################################################"
119 echo "#########################################"
120 echo "TEST SUBSECTION: $*"
129 if [ "$VERBOSE" = "1" ]; then
130 printf " COMMAND: $cmd\n"
133 out
=$
(eval $cmd 2>&1)
135 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
139 [ "$VERBOSE" = "1" ] && echo
150 addr
=$
(${pfx} ip
-6 -br addr show dev
${dev} | \
152 for (i = 3; i <= NF; ++i) {
160 [ -z "$addr" ] && return 1
167 ################################################################################
173 echo "########################################"
174 echo "Configuring interfaces"
179 ip netns add
${PEER_NS}
180 ip
-netns ${PEER_NS} li
set lo up
183 ip li add
${VRF} type vrf table
${VRF_TABLE}
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
196 ip li
set ${NETIFS[p${n}]} vrf
${VRF}
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
206 # move peer interfaces to namespace and add addresses
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
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}
221 # make sure we start from a clean slate
222 ip netns del
${PEER_NS} 2>/dev
/null
224 ip link del
${NETIFS[p${n}]} 2>/dev
/null
226 ip link del
${VRF} 2>/dev
/null
227 ip ro flush table
${VRF_TABLE}
228 ip
-6 ro flush table
${VRF_TABLE}
231 ################################################################################
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}"
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}"
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"
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 ################################################################################
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}"
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}"
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"
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
()
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"
455 log_section
"IPv4 onlink"
456 log_subsection
"Valid onlink commands"
458 log_subsection
"Invalid onlink commands"
461 log_section
"IPv6 onlink"
462 log_subsection
"Valid onlink commands"
464 log_subsection
"Invalid onlink commands"
468 ################################################################################
477 -v verbose mode (show commands and output)
481 ################################################################################
487 while getopts :t
:pPhv o
490 p
) PAUSE_ON_FAIL
=yes;;
491 v
) VERBOSE
=$
(($VERBOSE + 1));;
502 if [ "$TESTS" != "none" ]; then
503 printf "\nTests passed: %3d\n" ${nsuccess}
504 printf "Tests failed: %3d\n" ${nfail}