1#! /bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4readonly KSFT_PASS=0 5readonly KSFT_FAIL=1 6readonly KSFT_SKIP=4 7 8# shellcheck disable=SC2155 # declare and assign separately 9readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}" 10 11# These variables are used in some selftests, read-only 12declare -rx MPTCP_LIB_EVENT_CREATED=1 # MPTCP_EVENT_CREATED 13declare -rx MPTCP_LIB_EVENT_ESTABLISHED=2 # MPTCP_EVENT_ESTABLISHED 14declare -rx MPTCP_LIB_EVENT_CLOSED=3 # MPTCP_EVENT_CLOSED 15declare -rx MPTCP_LIB_EVENT_ANNOUNCED=6 # MPTCP_EVENT_ANNOUNCED 16declare -rx MPTCP_LIB_EVENT_REMOVED=7 # MPTCP_EVENT_REMOVED 17declare -rx MPTCP_LIB_EVENT_SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED 18declare -rx MPTCP_LIB_EVENT_SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED 19declare -rx MPTCP_LIB_EVENT_SUB_PRIORITY=13 # MPTCP_EVENT_SUB_PRIORITY 20declare -rx MPTCP_LIB_EVENT_LISTENER_CREATED=15 # MPTCP_EVENT_LISTENER_CREATED 21declare -rx MPTCP_LIB_EVENT_LISTENER_CLOSED=16 # MPTCP_EVENT_LISTENER_CLOSED 22 23declare -rx MPTCP_LIB_AF_INET=2 24declare -rx MPTCP_LIB_AF_INET6=10 25 26MPTCP_LIB_SUBTESTS=() 27 28# only if supported (or forced) and not disabled, see no-color.org 29if { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } && 30 [ "${NO_COLOR:-}" != "1" ]; then 31 readonly MPTCP_LIB_COLOR_RED="\E[1;31m" 32 readonly MPTCP_LIB_COLOR_GREEN="\E[1;32m" 33 readonly MPTCP_LIB_COLOR_YELLOW="\E[1;33m" 34 readonly MPTCP_LIB_COLOR_BLUE="\E[1;34m" 35 readonly MPTCP_LIB_COLOR_RESET="\E[0m" 36else 37 readonly MPTCP_LIB_COLOR_RED= 38 readonly MPTCP_LIB_COLOR_GREEN= 39 readonly MPTCP_LIB_COLOR_YELLOW= 40 readonly MPTCP_LIB_COLOR_BLUE= 41 readonly MPTCP_LIB_COLOR_RESET= 42fi 43 44# $1: color, $2: text 45mptcp_lib_print_color() { 46 echo -e "${MPTCP_LIB_START_PRINT:-}${*}${MPTCP_LIB_COLOR_RESET}" 47} 48 49mptcp_lib_print_ok() { 50 mptcp_lib_print_color "${MPTCP_LIB_COLOR_GREEN}${*}" 51} 52 53mptcp_lib_print_warn() { 54 mptcp_lib_print_color "${MPTCP_LIB_COLOR_YELLOW}${*}" 55} 56 57mptcp_lib_print_info() { 58 mptcp_lib_print_color "${MPTCP_LIB_COLOR_BLUE}${*}" 59} 60 61mptcp_lib_print_err() { 62 mptcp_lib_print_color "${MPTCP_LIB_COLOR_RED}${*}" 63} 64 65# SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all 66# features using the last version of the kernel and the selftests to make sure 67# a test is not being skipped by mistake. 68mptcp_lib_expect_all_features() { 69 [ "${SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES:-}" = "1" ] 70} 71 72# $1: msg 73mptcp_lib_fail_if_expected_feature() { 74 if mptcp_lib_expect_all_features; then 75 echo "ERROR: missing feature: ${*}" 76 exit ${KSFT_FAIL} 77 fi 78 79 return 1 80} 81 82# $1: file 83mptcp_lib_has_file() { 84 local f="${1}" 85 86 if [ -f "${f}" ]; then 87 return 0 88 fi 89 90 mptcp_lib_fail_if_expected_feature "${f} file not found" 91} 92 93mptcp_lib_check_mptcp() { 94 if ! mptcp_lib_has_file "/proc/sys/net/mptcp/enabled"; then 95 echo "SKIP: MPTCP support is not available" 96 exit ${KSFT_SKIP} 97 fi 98} 99 100mptcp_lib_check_kallsyms() { 101 if ! mptcp_lib_has_file "/proc/kallsyms"; then 102 echo "SKIP: CONFIG_KALLSYMS is missing" 103 exit ${KSFT_SKIP} 104 fi 105} 106 107# Internal: use mptcp_lib_kallsyms_has() instead 108__mptcp_lib_kallsyms_has() { 109 local sym="${1}" 110 111 mptcp_lib_check_kallsyms 112 113 grep -q " ${sym}" /proc/kallsyms 114} 115 116# $1: part of a symbol to look at, add '$' at the end for full name 117mptcp_lib_kallsyms_has() { 118 local sym="${1}" 119 120 if __mptcp_lib_kallsyms_has "${sym}"; then 121 return 0 122 fi 123 124 mptcp_lib_fail_if_expected_feature "${sym} symbol not found" 125} 126 127# $1: part of a symbol to look at, add '$' at the end for full name 128mptcp_lib_kallsyms_doesnt_have() { 129 local sym="${1}" 130 131 if ! __mptcp_lib_kallsyms_has "${sym}"; then 132 return 0 133 fi 134 135 mptcp_lib_fail_if_expected_feature "${sym} symbol has been found" 136} 137 138# !!!AVOID USING THIS!!! 139# Features might not land in the expected version and features can be backported 140# 141# $1: kernel version, e.g. 6.3 142mptcp_lib_kversion_ge() { 143 local exp_maj="${1%.*}" 144 local exp_min="${1#*.}" 145 local v maj min 146 147 # If the kernel has backported features, set this env var to 1: 148 if [ "${SELFTESTS_MPTCP_LIB_NO_KVERSION_CHECK:-}" = "1" ]; then 149 return 0 150 fi 151 152 v=$(uname -r | cut -d'.' -f1,2) 153 maj=${v%.*} 154 min=${v#*.} 155 156 if [ "${maj}" -gt "${exp_maj}" ] || 157 { [ "${maj}" -eq "${exp_maj}" ] && [ "${min}" -ge "${exp_min}" ]; }; then 158 return 0 159 fi 160 161 mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}" 162} 163 164__mptcp_lib_result_add() { 165 local result="${1}" 166 shift 167 168 local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1)) 169 170 MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*}") 171} 172 173# $1: test name 174mptcp_lib_result_pass() { 175 __mptcp_lib_result_add "ok" "${1}" 176} 177 178# $1: test name 179mptcp_lib_result_fail() { 180 __mptcp_lib_result_add "not ok" "${1}" 181} 182 183# $1: test name 184mptcp_lib_result_skip() { 185 __mptcp_lib_result_add "ok" "${1} # SKIP" 186} 187 188# $1: result code ; $2: test name 189mptcp_lib_result_code() { 190 local ret="${1}" 191 local name="${2}" 192 193 case "${ret}" in 194 "${KSFT_PASS}") 195 mptcp_lib_result_pass "${name}" 196 ;; 197 "${KSFT_FAIL}") 198 mptcp_lib_result_fail "${name}" 199 ;; 200 "${KSFT_SKIP}") 201 mptcp_lib_result_skip "${name}" 202 ;; 203 *) 204 echo "ERROR: wrong result code: ${ret}" 205 exit ${KSFT_FAIL} 206 ;; 207 esac 208} 209 210mptcp_lib_result_print_all_tap() { 211 local subtest 212 213 if [ ${#MPTCP_LIB_SUBTESTS[@]} -eq 0 ] || 214 [ "${SELFTESTS_MPTCP_LIB_NO_TAP:-}" = "1" ]; then 215 return 216 fi 217 218 printf "\nTAP version 13\n" 219 printf "1..%d\n" "${#MPTCP_LIB_SUBTESTS[@]}" 220 221 for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do 222 printf "%s\n" "${subtest}" 223 done 224} 225 226# get the value of keyword $1 in the line marked by keyword $2 227mptcp_lib_get_info_value() { 228 grep "${2}" | sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q' 229} 230 231# $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]] 232mptcp_lib_evts_get_info() { 233 grep "${4:-}" "${2}" | mptcp_lib_get_info_value "${1}" "^type:${3:-1}," 234} 235 236# $1: PID 237mptcp_lib_kill_wait() { 238 [ "${1}" -eq 0 ] && return 0 239 240 kill -SIGUSR1 "${1}" > /dev/null 2>&1 241 kill "${1}" > /dev/null 2>&1 242 wait "${1}" 2>/dev/null 243} 244 245# $1: IP address 246mptcp_lib_is_v6() { 247 [ -z "${1##*:*}" ] 248} 249 250# $1: ns, $2: MIB counter 251mptcp_lib_get_counter() { 252 local ns="${1}" 253 local counter="${2}" 254 local count 255 256 count=$(ip netns exec "${ns}" nstat -asz "${counter}" | 257 awk 'NR==1 {next} {print $2}') 258 if [ -z "${count}" ]; then 259 mptcp_lib_fail_if_expected_feature "${counter} counter" 260 return 1 261 fi 262 263 echo "${count}" 264} 265 266mptcp_lib_events() { 267 local ns="${1}" 268 local evts="${2}" 269 declare -n pid="${3}" 270 271 :>"${evts}" 272 273 mptcp_lib_kill_wait "${pid:-0}" 274 ip netns exec "${ns}" ./pm_nl_ctl events >> "${evts}" 2>&1 & 275 pid=$! 276} 277