Commit | Line | Data |
---|---|---|
153e1b84 DA |
1 | #!/bin/bash |
2 | # SPDX-License-Identifier: GPL-2.0 | |
3 | ||
4 | # IPv4 and IPv6 onlink tests | |
5 | ||
3a06833b | 6 | source lib.sh |
153e1b84 | 7 | PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} |
9b7e94e6 | 8 | VERBOSE=0 |
153e1b84 DA |
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 | |
8ae797aa DA |
61 | CONGW[2]=169.254.3.254 |
62 | CONGW[3]=169.254.5.254 | |
153e1b84 DA |
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 | ||
153e1b84 DA |
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)) | |
9b7e94e6 | 93 | printf " TEST: %-50s [ OK ]\n" "${msg}" |
153e1b84 DA |
94 | else |
95 | nfail=$((nfail+1)) | |
9b7e94e6 | 96 | printf " TEST: %-50s [FAIL]\n" "${msg}" |
153e1b84 DA |
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 | { | |
9b7e94e6 DA |
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 | |
153e1b84 DA |
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 | |
3a06833b | 177 | setup_ns PEER_NS |
153e1b84 DA |
178 | |
179 | # add vrf table | |
180 | ip li add ${VRF} type vrf table ${VRF_TABLE} | |
181 | ip li set ${VRF} up | |
4ed591c8 DA |
182 | ip ro add table ${VRF_TABLE} unreachable default metric 8192 |
183 | ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192 | |
153e1b84 DA |
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}]} | |
4ed591c8 | 200 | ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad |
153e1b84 DA |
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}]} | |
4ed591c8 | 207 | ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad |
153e1b84 DA |
208 | done |
209 | ||
4ed591c8 DA |
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} | |
153e1b84 | 212 | |
4ed591c8 | 213 | set +e |
153e1b84 DA |
214 | } |
215 | ||
216 | cleanup() | |
217 | { | |
218 | # make sure we start from a clean slate | |
3a06833b | 219 | cleanup_ns ${PEER_NS} 2>/dev/null |
153e1b84 DA |
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 | ||
8ae797aa DA |
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 | ||
153e1b84 DA |
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 | ||
8ae797aa | 276 | run_ip ${VRF_TABLE} ${TEST_NET4[2]}.1 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected" |
153e1b84 DA |
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 | ||
8ae797aa | 281 | run_ip ${PBR_TABLE} ${TEST_NET4[2]}.3 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected" |
153e1b84 | 282 | run_ip ${PBR_TABLE} ${TEST_NET4[2]}.4 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive" |
8ae797aa DA |
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" | |
153e1b84 DA |
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 | ||
8ae797aa DA |
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 | ||
153e1b84 DA |
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" | |
8ae797aa DA |
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" | |
153e1b84 DA |
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 | |
8ae797aa | 461 | log_subsection "Invalid onlink commands" |
153e1b84 DA |
462 | invalid_onlink_ipv6 |
463 | } | |
464 | ||
9b7e94e6 DA |
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 | ||
153e1b84 DA |
478 | ################################################################################ |
479 | # main | |
480 | ||
481 | nsuccess=0 | |
482 | nfail=0 | |
483 | ||
9b7e94e6 DA |
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 | ||
153e1b84 DA |
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 |