1d83013bdSMatthieu Baerts#! /bin/bash 2d83013bdSMatthieu Baerts# SPDX-License-Identifier: GPL-2.0 3d83013bdSMatthieu Baerts 4c4192967SMatthieu Baertsreadonly KSFT_PASS=0 5d83013bdSMatthieu Baertsreadonly KSFT_FAIL=1 6d83013bdSMatthieu Baertsreadonly KSFT_SKIP=4 79466df1aSMatthieu Baerts 89466df1aSMatthieu Baerts# shellcheck disable=SC2155 # declare and assign separately 92decb7d9SMatthieu Baerts (NGI0)readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}" 10c4192967SMatthieu Baerts 11a17d1419SGeliang Tang# These variables are used in some selftests, read-only 12*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_CREATED=1 # MPTCP_EVENT_CREATED 13*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_ESTABLISHED=2 # MPTCP_EVENT_ESTABLISHED 14*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_CLOSED=3 # MPTCP_EVENT_CLOSED 15*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_ANNOUNCED=6 # MPTCP_EVENT_ANNOUNCED 16*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_REMOVED=7 # MPTCP_EVENT_REMOVED 17*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED 18*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED 19*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_SUB_PRIORITY=13 # MPTCP_EVENT_SUB_PRIORITY 20*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_LISTENER_CREATED=15 # MPTCP_EVENT_LISTENER_CREATED 21*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_EVENT_LISTENER_CLOSED=16 # MPTCP_EVENT_LISTENER_CLOSED 22*a417ef47SMatthieu Baerts (NGI0) 23*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_AF_INET=2 24*a417ef47SMatthieu Baerts (NGI0)declare -rx MPTCP_LIB_AF_INET6=10 25*a417ef47SMatthieu Baerts (NGI0) 26c4192967SMatthieu BaertsMPTCP_LIB_SUBTESTS=() 27d83013bdSMatthieu Baerts 289466df1aSMatthieu Baerts# only if supported (or forced) and not disabled, see no-color.org 299466df1aSMatthieu Baertsif { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } && 309466df1aSMatthieu Baerts [ "${NO_COLOR:-}" != "1" ]; then 319466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_RED="\E[1;31m" 329466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_GREEN="\E[1;32m" 339466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_YELLOW="\E[1;33m" 349466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_BLUE="\E[1;34m" 359466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_RESET="\E[0m" 369466df1aSMatthieu Baertselse 379466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_RED= 389466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_GREEN= 399466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_YELLOW= 409466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_BLUE= 419466df1aSMatthieu Baerts readonly MPTCP_LIB_COLOR_RESET= 429466df1aSMatthieu Baertsfi 439466df1aSMatthieu Baerts 449466df1aSMatthieu Baerts# $1: color, $2: text 459466df1aSMatthieu Baertsmptcp_lib_print_color() { 469466df1aSMatthieu Baerts echo -e "${MPTCP_LIB_START_PRINT:-}${*}${MPTCP_LIB_COLOR_RESET}" 479466df1aSMatthieu Baerts} 489466df1aSMatthieu Baerts 499466df1aSMatthieu Baertsmptcp_lib_print_ok() { 509466df1aSMatthieu Baerts mptcp_lib_print_color "${MPTCP_LIB_COLOR_GREEN}${*}" 519466df1aSMatthieu Baerts} 529466df1aSMatthieu Baerts 539466df1aSMatthieu Baertsmptcp_lib_print_warn() { 549466df1aSMatthieu Baerts mptcp_lib_print_color "${MPTCP_LIB_COLOR_YELLOW}${*}" 559466df1aSMatthieu Baerts} 569466df1aSMatthieu Baerts 579466df1aSMatthieu Baertsmptcp_lib_print_info() { 589466df1aSMatthieu Baerts mptcp_lib_print_color "${MPTCP_LIB_COLOR_BLUE}${*}" 599466df1aSMatthieu Baerts} 609466df1aSMatthieu Baerts 619466df1aSMatthieu Baertsmptcp_lib_print_err() { 629466df1aSMatthieu Baerts mptcp_lib_print_color "${MPTCP_LIB_COLOR_RED}${*}" 639466df1aSMatthieu Baerts} 649466df1aSMatthieu Baerts 65d83013bdSMatthieu Baerts# SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all 66d83013bdSMatthieu Baerts# features using the last version of the kernel and the selftests to make sure 67d83013bdSMatthieu Baerts# a test is not being skipped by mistake. 68d83013bdSMatthieu Baertsmptcp_lib_expect_all_features() { 69d83013bdSMatthieu Baerts [ "${SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES:-}" = "1" ] 70d83013bdSMatthieu Baerts} 71d83013bdSMatthieu Baerts 72d83013bdSMatthieu Baerts# $1: msg 73d83013bdSMatthieu Baertsmptcp_lib_fail_if_expected_feature() { 74d83013bdSMatthieu Baerts if mptcp_lib_expect_all_features; then 75d83013bdSMatthieu Baerts echo "ERROR: missing feature: ${*}" 76d83013bdSMatthieu Baerts exit ${KSFT_FAIL} 77d83013bdSMatthieu Baerts fi 78d83013bdSMatthieu Baerts 79d83013bdSMatthieu Baerts return 1 80d83013bdSMatthieu Baerts} 81d83013bdSMatthieu Baerts 82d83013bdSMatthieu Baerts# $1: file 83d83013bdSMatthieu Baertsmptcp_lib_has_file() { 84d83013bdSMatthieu Baerts local f="${1}" 85d83013bdSMatthieu Baerts 86d83013bdSMatthieu Baerts if [ -f "${f}" ]; then 87d83013bdSMatthieu Baerts return 0 88d83013bdSMatthieu Baerts fi 89d83013bdSMatthieu Baerts 90d83013bdSMatthieu Baerts mptcp_lib_fail_if_expected_feature "${f} file not found" 91d83013bdSMatthieu Baerts} 92d83013bdSMatthieu Baerts 93d83013bdSMatthieu Baertsmptcp_lib_check_mptcp() { 94d83013bdSMatthieu Baerts if ! mptcp_lib_has_file "/proc/sys/net/mptcp/enabled"; then 95d83013bdSMatthieu Baerts echo "SKIP: MPTCP support is not available" 96d83013bdSMatthieu Baerts exit ${KSFT_SKIP} 97d83013bdSMatthieu Baerts fi 98d83013bdSMatthieu Baerts} 9967300482SMatthieu Baerts 10067300482SMatthieu Baertsmptcp_lib_check_kallsyms() { 10167300482SMatthieu Baerts if ! mptcp_lib_has_file "/proc/kallsyms"; then 10267300482SMatthieu Baerts echo "SKIP: CONFIG_KALLSYMS is missing" 10367300482SMatthieu Baerts exit ${KSFT_SKIP} 10467300482SMatthieu Baerts fi 10567300482SMatthieu Baerts} 10667300482SMatthieu Baerts 10767300482SMatthieu Baerts# Internal: use mptcp_lib_kallsyms_has() instead 10867300482SMatthieu Baerts__mptcp_lib_kallsyms_has() { 10967300482SMatthieu Baerts local sym="${1}" 11067300482SMatthieu Baerts 11167300482SMatthieu Baerts mptcp_lib_check_kallsyms 11267300482SMatthieu Baerts 11367300482SMatthieu Baerts grep -q " ${sym}" /proc/kallsyms 11467300482SMatthieu Baerts} 11567300482SMatthieu Baerts 11667300482SMatthieu Baerts# $1: part of a symbol to look at, add '$' at the end for full name 11767300482SMatthieu Baertsmptcp_lib_kallsyms_has() { 11867300482SMatthieu Baerts local sym="${1}" 11967300482SMatthieu Baerts 12067300482SMatthieu Baerts if __mptcp_lib_kallsyms_has "${sym}"; then 12167300482SMatthieu Baerts return 0 12267300482SMatthieu Baerts fi 12367300482SMatthieu Baerts 12467300482SMatthieu Baerts mptcp_lib_fail_if_expected_feature "${sym} symbol not found" 12567300482SMatthieu Baerts} 12667300482SMatthieu Baerts 12767300482SMatthieu Baerts# $1: part of a symbol to look at, add '$' at the end for full name 12867300482SMatthieu Baertsmptcp_lib_kallsyms_doesnt_have() { 12967300482SMatthieu Baerts local sym="${1}" 13067300482SMatthieu Baerts 13167300482SMatthieu Baerts if ! __mptcp_lib_kallsyms_has "${sym}"; then 13267300482SMatthieu Baerts return 0 13367300482SMatthieu Baerts fi 13467300482SMatthieu Baerts 13567300482SMatthieu Baerts mptcp_lib_fail_if_expected_feature "${sym} symbol has been found" 13667300482SMatthieu Baerts} 137b1a6a38aSMatthieu Baerts 138b1a6a38aSMatthieu Baerts# !!!AVOID USING THIS!!! 139b1a6a38aSMatthieu Baerts# Features might not land in the expected version and features can be backported 140b1a6a38aSMatthieu Baerts# 141b1a6a38aSMatthieu Baerts# $1: kernel version, e.g. 6.3 142b1a6a38aSMatthieu Baertsmptcp_lib_kversion_ge() { 143b1a6a38aSMatthieu Baerts local exp_maj="${1%.*}" 144b1a6a38aSMatthieu Baerts local exp_min="${1#*.}" 145b1a6a38aSMatthieu Baerts local v maj min 146b1a6a38aSMatthieu Baerts 147b1a6a38aSMatthieu Baerts # If the kernel has backported features, set this env var to 1: 148b1a6a38aSMatthieu Baerts if [ "${SELFTESTS_MPTCP_LIB_NO_KVERSION_CHECK:-}" = "1" ]; then 149b1a6a38aSMatthieu Baerts return 0 150b1a6a38aSMatthieu Baerts fi 151b1a6a38aSMatthieu Baerts 152b1a6a38aSMatthieu Baerts v=$(uname -r | cut -d'.' -f1,2) 153b1a6a38aSMatthieu Baerts maj=${v%.*} 154b1a6a38aSMatthieu Baerts min=${v#*.} 155b1a6a38aSMatthieu Baerts 156b1a6a38aSMatthieu Baerts if [ "${maj}" -gt "${exp_maj}" ] || 157b1a6a38aSMatthieu Baerts { [ "${maj}" -eq "${exp_maj}" ] && [ "${min}" -ge "${exp_min}" ]; }; then 158b1a6a38aSMatthieu Baerts return 0 159b1a6a38aSMatthieu Baerts fi 160b1a6a38aSMatthieu Baerts 161b1a6a38aSMatthieu Baerts mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}" 162b1a6a38aSMatthieu Baerts} 163c4192967SMatthieu Baerts 164c4192967SMatthieu Baerts__mptcp_lib_result_add() { 165c4192967SMatthieu Baerts local result="${1}" 166c4192967SMatthieu Baerts shift 167c4192967SMatthieu Baerts 168c4192967SMatthieu Baerts local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1)) 169c4192967SMatthieu Baerts 170c4192967SMatthieu Baerts MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*}") 171c4192967SMatthieu Baerts} 172c4192967SMatthieu Baerts 173c4192967SMatthieu Baerts# $1: test name 174c4192967SMatthieu Baertsmptcp_lib_result_pass() { 175c4192967SMatthieu Baerts __mptcp_lib_result_add "ok" "${1}" 176c4192967SMatthieu Baerts} 177c4192967SMatthieu Baerts 178c4192967SMatthieu Baerts# $1: test name 179c4192967SMatthieu Baertsmptcp_lib_result_fail() { 180c4192967SMatthieu Baerts __mptcp_lib_result_add "not ok" "${1}" 181c4192967SMatthieu Baerts} 182c4192967SMatthieu Baerts 183c4192967SMatthieu Baerts# $1: test name 184c4192967SMatthieu Baertsmptcp_lib_result_skip() { 185c4192967SMatthieu Baerts __mptcp_lib_result_add "ok" "${1} # SKIP" 186c4192967SMatthieu Baerts} 187c4192967SMatthieu Baerts 188c4192967SMatthieu Baerts# $1: result code ; $2: test name 189c4192967SMatthieu Baertsmptcp_lib_result_code() { 190c4192967SMatthieu Baerts local ret="${1}" 191c4192967SMatthieu Baerts local name="${2}" 192c4192967SMatthieu Baerts 193c4192967SMatthieu Baerts case "${ret}" in 194c4192967SMatthieu Baerts "${KSFT_PASS}") 195c4192967SMatthieu Baerts mptcp_lib_result_pass "${name}" 196c4192967SMatthieu Baerts ;; 197c4192967SMatthieu Baerts "${KSFT_FAIL}") 198c4192967SMatthieu Baerts mptcp_lib_result_fail "${name}" 199c4192967SMatthieu Baerts ;; 200c4192967SMatthieu Baerts "${KSFT_SKIP}") 201c4192967SMatthieu Baerts mptcp_lib_result_skip "${name}" 202c4192967SMatthieu Baerts ;; 203c4192967SMatthieu Baerts *) 204c4192967SMatthieu Baerts echo "ERROR: wrong result code: ${ret}" 205c4192967SMatthieu Baerts exit ${KSFT_FAIL} 206c4192967SMatthieu Baerts ;; 207c4192967SMatthieu Baerts esac 208c4192967SMatthieu Baerts} 209c4192967SMatthieu Baerts 210c4192967SMatthieu Baertsmptcp_lib_result_print_all_tap() { 211c4192967SMatthieu Baerts local subtest 212c4192967SMatthieu Baerts 213c4192967SMatthieu Baerts if [ ${#MPTCP_LIB_SUBTESTS[@]} -eq 0 ] || 214c4192967SMatthieu Baerts [ "${SELFTESTS_MPTCP_LIB_NO_TAP:-}" = "1" ]; then 215c4192967SMatthieu Baerts return 216c4192967SMatthieu Baerts fi 217c4192967SMatthieu Baerts 218c4192967SMatthieu Baerts printf "\nTAP version 13\n" 219c4192967SMatthieu Baerts printf "1..%d\n" "${#MPTCP_LIB_SUBTESTS[@]}" 220c4192967SMatthieu Baerts 221c4192967SMatthieu Baerts for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do 222c4192967SMatthieu Baerts printf "%s\n" "${subtest}" 223c4192967SMatthieu Baerts done 224c4192967SMatthieu Baerts} 2251fdb37a6SGeliang Tang 226ae1fa39dSGeliang Tang# get the value of keyword $1 in the line marked by keyword $2 227ae1fa39dSGeliang Tangmptcp_lib_get_info_value() { 228ae1fa39dSGeliang Tang grep "${2}" | sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q' 229ae1fa39dSGeliang Tang} 230ae1fa39dSGeliang Tang 231ece1aaecSGeliang Tang# $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]] 232ae1fa39dSGeliang Tangmptcp_lib_evts_get_info() { 233ece1aaecSGeliang Tang grep "${4:-}" "${2}" | mptcp_lib_get_info_value "${1}" "^type:${3:-1}," 234ae1fa39dSGeliang Tang} 235ae1fa39dSGeliang Tang 2361fdb37a6SGeliang Tang# $1: PID 2371fdb37a6SGeliang Tangmptcp_lib_kill_wait() { 2381fdb37a6SGeliang Tang [ "${1}" -eq 0 ] && return 0 2391fdb37a6SGeliang Tang 2401fdb37a6SGeliang Tang kill -SIGUSR1 "${1}" > /dev/null 2>&1 2411fdb37a6SGeliang Tang kill "${1}" > /dev/null 2>&1 2421fdb37a6SGeliang Tang wait "${1}" 2>/dev/null 2431fdb37a6SGeliang Tang} 244697128a3SGeliang Tang 2458e7f31bfSGeliang Tang# $1: IP address 2468e7f31bfSGeliang Tangmptcp_lib_is_v6() { 2478e7f31bfSGeliang Tang [ -z "${1##*:*}" ] 2488e7f31bfSGeliang Tang} 2498e7f31bfSGeliang Tang 250697128a3SGeliang Tang# $1: ns, $2: MIB counter 251697128a3SGeliang Tangmptcp_lib_get_counter() { 252697128a3SGeliang Tang local ns="${1}" 253697128a3SGeliang Tang local counter="${2}" 254697128a3SGeliang Tang local count 255697128a3SGeliang Tang 256697128a3SGeliang Tang count=$(ip netns exec "${ns}" nstat -asz "${counter}" | 257697128a3SGeliang Tang awk 'NR==1 {next} {print $2}') 258697128a3SGeliang Tang if [ -z "${count}" ]; then 259697128a3SGeliang Tang mptcp_lib_fail_if_expected_feature "${counter} counter" 260697128a3SGeliang Tang return 1 261697128a3SGeliang Tang fi 262697128a3SGeliang Tang 263697128a3SGeliang Tang echo "${count}" 264697128a3SGeliang Tang} 265b66609e9SGeliang Tang 266b66609e9SGeliang Tangmptcp_lib_events() { 267b66609e9SGeliang Tang local ns="${1}" 268b66609e9SGeliang Tang local evts="${2}" 269b66609e9SGeliang Tang declare -n pid="${3}" 270b66609e9SGeliang Tang 271b66609e9SGeliang Tang :>"${evts}" 272b66609e9SGeliang Tang 273b66609e9SGeliang Tang mptcp_lib_kill_wait "${pid:-0}" 274b66609e9SGeliang Tang ip netns exec "${ns}" ./pm_nl_ctl events >> "${evts}" 2>&1 & 275b66609e9SGeliang Tang pid=$! 276b66609e9SGeliang Tang} 277