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##############################################################################
5# Defines
6
7: "${WAIT_TIMEOUT:=20}"
8
9BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms
10
11# Kselftest framework constants.
12ksft_pass=0
13ksft_fail=1
14ksft_xfail=2
15ksft_skip=4
16
17# namespace list created by setup_ns
18NS_LIST=()
19
20##############################################################################
21# Helpers
22
23__ksft_status_merge()
24{
25 local a=$1; shift
26 local b=$1; shift
27 local -A weights
28 local weight=0
29
30 local i
31 for i in "$@"; do
32 weights[$i]=$((weight++))
33 done
34
35 if [[ ${weights[$a]} > ${weights[$b]} ]]; then
36 echo "$a"
37 return 0
38 else
39 echo "$b"
40 return 1
41 fi
42}
43
44ksft_status_merge()
45{
46 local a=$1; shift
47 local b=$1; shift
48
49 __ksft_status_merge "$a" "$b" \
50 $ksft_pass $ksft_xfail $ksft_skip $ksft_fail
51}
52
53ksft_exit_status_merge()
54{
55 local a=$1; shift
56 local b=$1; shift
57
58 __ksft_status_merge "$a" "$b" \
59 $ksft_xfail $ksft_pass $ksft_skip $ksft_fail
60}
61
62loopy_wait()
63{
64 local sleep_cmd=$1; shift
65 local timeout_ms=$1; shift
66
67 local start_time="$(date -u +%s%3N)"
68 while true
69 do
70 local out
71 if out=$("$@"); then
72 echo -n "$out"
73 return 0
74 fi
75
76 local current_time="$(date -u +%s%3N)"
77 if ((current_time - start_time > timeout_ms)); then
78 echo -n "$out"
79 return 1
80 fi
81
82 $sleep_cmd
83 done
84}
85
86busywait()
87{
88 local timeout_ms=$1; shift
89
90 loopy_wait : "$timeout_ms" "$@"
91}
92
93# timeout in seconds
94slowwait()
95{
96 local timeout_sec=$1; shift
97
98 loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@"
99}
100
101until_counter_is()
102{
103 local expr=$1; shift
104 local current=$("$@")
105
106 echo $((current))
107 ((current $expr))
108}
109
110busywait_for_counter()
111{
112 local timeout=$1; shift
113 local delta=$1; shift
114
115 local base=$("$@")
116 busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"
117}
118
119slowwait_for_counter()
120{
121 local timeout=$1; shift
122 local delta=$1; shift
123
124 local base=$("$@")
125 slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@"
126}
127
128# Check for existence of tools which are built as part of selftests
129# but may also already exist in $PATH
130check_gen_prog()
131{
132 local prog_name=$1; shift
133
134 if ! which $prog_name >/dev/null 2>/dev/null; then
135 PATH=$PWD:$PATH
136 if ! which $prog_name >/dev/null; then
137 echo "'$prog_name' command not found; skipping tests"
138 exit $ksft_skip
139 fi
140 fi
141}
142
143remove_ns_list()
144{
145 local item=$1
146 local ns
147 local ns_list=("${NS_LIST[@]}")
148 NS_LIST=()
149
150 for ns in "${ns_list[@]}"; do
151 if [ "${ns}" != "${item}" ]; then
152 NS_LIST+=("${ns}")
153 fi
154 done
155}
156
157cleanup_ns()
158{
159 local ns=""
160 local ret=0
161
162 for ns in "$@"; do
163 [ -z "${ns}" ] && continue
164 ip netns pids "${ns}" 2> /dev/null | xargs -r kill || true
165 ip netns delete "${ns}" &> /dev/null || true
166 if ! busywait $BUSYWAIT_TIMEOUT ip netns list \| grep -vq "^$ns$" &> /dev/null; then
167 echo "Warn: Failed to remove namespace $ns"
168 ret=1
169 else
170 remove_ns_list "${ns}"
171 fi
172 done
173
174 return $ret
175}
176
177cleanup_all_ns()
178{
179 cleanup_ns "${NS_LIST[@]}"
180}
181
182# setup netns with given names as prefix. e.g
183# setup_ns local remote
184setup_ns()
185{
186 local ns_name=""
187 local ns_list=()
188 for ns_name in "$@"; do
189 # avoid conflicts with local var: internal error
190 if [ "${ns_name}" = "ns_name" ]; then
191 echo "Failed to setup namespace '${ns_name}': invalid name"
192 cleanup_ns "${ns_list[@]}"
193 exit $ksft_fail
194 fi
195
196 # Some test may setup/remove same netns multi times
197 if [ -z "${!ns_name}" ]; then
198 eval "${ns_name}=${ns_name,,}-$(mktemp -u XXXXXX)"
199 else
200 cleanup_ns "${!ns_name}"
201 fi
202
203 if ! ip netns add "${!ns_name}"; then
204 echo "Failed to create namespace $ns_name"
205 cleanup_ns "${ns_list[@]}"
206 return $ksft_skip
207 fi
208 ip -n "${!ns_name}" link set lo up
209 ns_list+=("${!ns_name}")
210 done
211 NS_LIST+=("${ns_list[@]}")
212}
213
214tc_rule_stats_get()
215{
216 local dev=$1; shift
217 local pref=$1; shift
218 local dir=${1:-ingress}; shift
219 local selector=${1:-.packets}; shift
220
221 tc -j -s filter show dev $dev $dir pref $pref \
222 | jq ".[1].options.actions[].stats$selector"
223}
224
225tc_rule_handle_stats_get()
226{
227 local id=$1; shift
228 local handle=$1; shift
229 local selector=${1:-.packets}; shift
230 local netns=${1:-""}; shift
231
232 tc $netns -j -s filter show $id \
233 | jq ".[] | select(.options.handle == $handle) | \
234 .options.actions[0].stats$selector"
235}