2 # SPDX-License-Identifier: GPL-2.0
4 net_dir
=$
(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
5 source "$net_dir/lib/sh/defer.sh"
7 ##############################################################################
10 : "${WAIT_TIMEOUT:=20}"
12 # Whether to pause on after a failure.
13 : "${PAUSE_ON_FAIL:=no}"
15 BUSYWAIT_TIMEOUT
=$
((WAIT_TIMEOUT
* 1000)) # ms
17 # Kselftest framework constants.
23 # namespace list created by setup_ns
26 # Exit status to return at the end. Set in case one of the tests fails.
28 # Per-test return value. Clear at the beginning of each test.
31 ##############################################################################
43 weights
[$i]=$
((weight
++))
46 if [[ ${weights[$a]} > ${weights[$b]} ]]; then
60 __ksft_status_merge
"$a" "$b" \
61 $ksft_pass $ksft_xfail $ksft_skip $ksft_fail
64 ksft_exit_status_merge
()
69 __ksft_status_merge
"$a" "$b" \
70 $ksft_xfail $ksft_pass $ksft_skip $ksft_fail
75 local sleep_cmd
=$1; shift
76 local timeout_ms
=$1; shift
78 local start_time
="$(date -u +%s%3N)"
87 local current_time
="$(date -u +%s%3N)"
88 if ((current_time
- start_time
> timeout_ms
)); then
99 local timeout_ms
=$1; shift
101 loopy_wait
: "$timeout_ms" "$@"
107 local timeout_sec
=$1; shift
109 loopy_wait
"sleep 0.1" "$((timeout_sec * 1000))" "$@"
115 local current
=$
("$@")
121 busywait_for_counter
()
123 local timeout
=$1; shift
124 local delta
=$1; shift
127 busywait
"$timeout" until_counter_is
">= $((base + delta))" "$@"
130 slowwait_for_counter
()
132 local timeout
=$1; shift
133 local delta
=$1; shift
136 slowwait
"$timeout" until_counter_is
">= $((base + delta))" "$@"
139 # Check for existence of tools which are built as part of selftests
140 # but may also already exist in $PATH
143 local prog_name
=$1; shift
145 if ! which $prog_name >/dev
/null
2>/dev
/null
; then
147 if ! which $prog_name >/dev
/null
; then
148 echo "'$prog_name' command not found; skipping tests"
158 local ns_list
=("${NS_LIST[@]}")
161 for ns
in "${ns_list[@]}"; do
162 if [ "${ns}" != "${item}" ]; then
174 [ -z "${ns}" ] && continue
175 ip netns pids
"${ns}" 2> /dev
/null |
xargs -r kill || true
176 ip netns delete
"${ns}" &> /dev
/null || true
177 if ! busywait
$BUSYWAIT_TIMEOUT ip netns list \|
grep -vq "^$ns$" &> /dev
/null
; then
178 echo "Warn: Failed to remove namespace $ns"
181 remove_ns_list
"${ns}"
190 cleanup_ns
"${NS_LIST[@]}"
193 # setup netns with given names as prefix. e.g
194 # setup_ns local remote
199 for ns_name
in "$@"; do
200 # avoid conflicts with local var: internal error
201 if [ "${ns_name}" = "ns_name" ]; then
202 echo "Failed to setup namespace '${ns_name}': invalid name"
203 cleanup_ns
"${ns_list[@]}"
207 # Some test may setup/remove same netns multi times
208 if [ -z "${!ns_name}" ]; then
209 eval "${ns_name}=${ns_name,,}-$(mktemp -u XXXXXX)"
211 cleanup_ns
"${!ns_name}"
214 if ! ip netns add
"${!ns_name}"; then
215 echo "Failed to create namespace $ns_name"
216 cleanup_ns
"${ns_list[@]}"
219 ip
-n "${!ns_name}" link
set lo up
220 ns_list
+=("${!ns_name}")
222 NS_LIST
+=("${ns_list[@]}")
229 local dir
=${1:-ingress}; shift
230 local selector
=${1:-.packets}; shift
232 tc
-j -s filter show dev
$dev $dir pref
$pref \
233 | jq
".[1].options.actions[].stats$selector"
236 tc_rule_handle_stats_get
()
239 local handle
=$1; shift
240 local selector
=${1:-.packets}; shift
241 local netns
=${1:-""}; shift
243 tc
$netns -j -s filter show
$id \
244 | jq
".[] | select(.options.handle == $handle) | \
245 .options.actions[0].stats$selector"
248 ret_set_ksft_status
()
250 local ksft_status
=$1; shift
253 RET
=$
(ksft_status_merge
$RET $ksft_status)
261 local test_name
=$1; shift
262 local opt_str
=$1; shift
263 local result
=$1; shift
264 local retmsg
=$1; shift
266 printf "TEST: %-60s [%s]\n" "$test_name $opt_str" "$result"
267 if [[ $retmsg ]]; then
268 printf "\t%s\n" "$retmsg"
274 if [[ $PAUSE_ON_FAIL == yes ]]; then
275 echo "Hit enter to continue, 'q' to quit"
277 [[ $a == q
]] && exit 1
281 handle_test_result_pass
()
283 local test_name
=$1; shift
284 local opt_str
=$1; shift
286 log_test_result
"$test_name" "$opt_str" " OK "
289 handle_test_result_fail
()
291 local test_name
=$1; shift
292 local opt_str
=$1; shift
294 log_test_result
"$test_name" "$opt_str" FAIL
"$retmsg"
298 handle_test_result_xfail
()
300 local test_name
=$1; shift
301 local opt_str
=$1; shift
303 log_test_result
"$test_name" "$opt_str" XFAIL
"$retmsg"
307 handle_test_result_skip
()
309 local test_name
=$1; shift
310 local opt_str
=$1; shift
312 log_test_result
"$test_name" "$opt_str" SKIP
"$retmsg"
320 if [[ $# -eq 2 ]]; then
324 if ((RET
== ksft_pass
)); then
325 handle_test_result_pass
"$test_name" "$opt_str"
326 elif ((RET
== ksft_xfail
)); then
327 handle_test_result_xfail
"$test_name" "$opt_str"
328 elif ((RET
== ksft_skip
)); then
329 handle_test_result_skip
"$test_name" "$opt_str"
331 handle_test_result_fail
"$test_name" "$opt_str"
334 EXIT_STATUS
=$
(ksft_exit_status_merge
$EXIT_STATUS $RET)
340 RET
=$ksft_skip retmsg
= log_test
"$@"
345 RET
=$ksft_xfail retmsg
= log_test
"$@"
359 for current_test
in ${TESTS:-$ALL_TESTS}; do
365 # Whether FAILs should be interpreted as XFAILs. Internal.
374 if [[ $FAIL_TO_XFAIL = yes ]]; then
375 ret_set_ksft_status
$ksft_xfail "$msg"
377 ret_set_ksft_status
$ksft_fail "$msg"
387 check_err $
((!err
)) "$msg"
392 local should_fail
=$1; shift
396 if ((should_fail
)); then
397 check_fail
$err "$what succeeded, but should have failed"
399 check_err
$err "$what failed"
405 FAIL_TO_XFAIL
=yes "$@"
410 if [[ $KSFT_MACHINE_SLOW = yes ]]; then
411 FAIL_TO_XFAIL
=yes "$@"
419 if [[ $KSFT_MACHINE_SLOW != yes ]]; then
429 kind
=$
(ip
-j -d link show dev
$dev |
430 jq
-r '.[].linkinfo.info_kind')
431 if [[ $kind = veth
]]; then
432 FAIL_TO_XFAIL
=yes "$@"
442 # Suppress noise from killing the process.
443 { kill $pid && wait $pid; } 2>/dev
/null
450 ip link add name
"$name" "$@"
451 defer ip link del dev
"$name"
456 local member
=$1; shift
457 local master
=$1; shift
459 ip link
set dev
"$member" master
"$master"
460 defer ip link
set dev
"$member" nomaster