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 for i in "$@"; do 31 weights[$i]=$((weight++)) 32 done 33 34 if [[ ${weights[$a]} > ${weights[$b]} ]]; then 35 echo "$a" 36 return 0 37 else 38 echo "$b" 39 return 1 40 fi 41} 42 43ksft_status_merge() 44{ 45 local a=$1; shift 46 local b=$1; shift 47 48 __ksft_status_merge "$a" "$b" \ 49 $ksft_pass $ksft_xfail $ksft_skip $ksft_fail 50} 51 52ksft_exit_status_merge() 53{ 54 local a=$1; shift 55 local b=$1; shift 56 57 __ksft_status_merge "$a" "$b" \ 58 $ksft_xfail $ksft_pass $ksft_skip $ksft_fail 59} 60 61busywait() 62{ 63 local timeout=$1; shift 64 65 local start_time="$(date -u +%s%3N)" 66 while true 67 do 68 local out 69 out=$("$@") 70 local ret=$? 71 if ((!ret)); 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)); then 78 echo -n "$out" 79 return 1 80 fi 81 done 82} 83 84cleanup_ns() 85{ 86 local ns="" 87 local errexit=0 88 local ret=0 89 90 # disable errexit temporary 91 if [[ $- =~ "e" ]]; then 92 errexit=1 93 set +e 94 fi 95 96 for ns in "$@"; do 97 ip netns delete "${ns}" &> /dev/null 98 if ! busywait $BUSYWAIT_TIMEOUT ip netns list \| grep -vq "^$ns$" &> /dev/null; then 99 echo "Warn: Failed to remove namespace $ns" 100 ret=1 101 fi 102 done 103 104 [ $errexit -eq 1 ] && set -e 105 return $ret 106} 107 108cleanup_all_ns() 109{ 110 cleanup_ns $NS_LIST 111} 112 113# setup netns with given names as prefix. e.g 114# setup_ns local remote 115setup_ns() 116{ 117 local ns="" 118 local ns_name="" 119 local ns_list="" 120 for ns_name in "$@"; do 121 # Some test may setup/remove same netns multi times 122 if unset ${ns_name} 2> /dev/null; then 123 ns="${ns_name,,}-$(mktemp -u XXXXXX)" 124 eval readonly ${ns_name}="$ns" 125 else 126 eval ns='$'${ns_name} 127 cleanup_ns "$ns" 128 129 fi 130 131 if ! ip netns add "$ns"; then 132 echo "Failed to create namespace $ns_name" 133 cleanup_ns "$ns_list" 134 return $ksft_skip 135 fi 136 ip -n "$ns" link set lo up 137 ns_list="$ns_list $ns" 138 done 139 NS_LIST="$NS_LIST $ns_list" 140} 141