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