162306a36Sopenharmony_ci#! /bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci 462306a36Sopenharmony_cireadonly KSFT_PASS=0 562306a36Sopenharmony_cireadonly KSFT_FAIL=1 662306a36Sopenharmony_cireadonly KSFT_SKIP=4 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci# shellcheck disable=SC2155 # declare and assign separately 962306a36Sopenharmony_cireadonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciMPTCP_LIB_SUBTESTS=() 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci# only if supported (or forced) and not disabled, see no-color.org 1462306a36Sopenharmony_ciif { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } && 1562306a36Sopenharmony_ci [ "${NO_COLOR:-}" != "1" ]; then 1662306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_RED="\E[1;31m" 1762306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_GREEN="\E[1;32m" 1862306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_YELLOW="\E[1;33m" 1962306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_BLUE="\E[1;34m" 2062306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_RESET="\E[0m" 2162306a36Sopenharmony_cielse 2262306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_RED= 2362306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_GREEN= 2462306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_YELLOW= 2562306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_BLUE= 2662306a36Sopenharmony_ci readonly MPTCP_LIB_COLOR_RESET= 2762306a36Sopenharmony_cifi 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci# $1: color, $2: text 3062306a36Sopenharmony_cimptcp_lib_print_color() { 3162306a36Sopenharmony_ci echo -e "${MPTCP_LIB_START_PRINT:-}${*}${MPTCP_LIB_COLOR_RESET}" 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cimptcp_lib_print_ok() { 3562306a36Sopenharmony_ci mptcp_lib_print_color "${MPTCP_LIB_COLOR_GREEN}${*}" 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cimptcp_lib_print_warn() { 3962306a36Sopenharmony_ci mptcp_lib_print_color "${MPTCP_LIB_COLOR_YELLOW}${*}" 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cimptcp_lib_print_info() { 4362306a36Sopenharmony_ci mptcp_lib_print_color "${MPTCP_LIB_COLOR_BLUE}${*}" 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cimptcp_lib_print_err() { 4762306a36Sopenharmony_ci mptcp_lib_print_color "${MPTCP_LIB_COLOR_RED}${*}" 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci# SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all 5162306a36Sopenharmony_ci# features using the last version of the kernel and the selftests to make sure 5262306a36Sopenharmony_ci# a test is not being skipped by mistake. 5362306a36Sopenharmony_cimptcp_lib_expect_all_features() { 5462306a36Sopenharmony_ci [ "${SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES:-}" = "1" ] 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci# $1: msg 5862306a36Sopenharmony_cimptcp_lib_fail_if_expected_feature() { 5962306a36Sopenharmony_ci if mptcp_lib_expect_all_features; then 6062306a36Sopenharmony_ci echo "ERROR: missing feature: ${*}" 6162306a36Sopenharmony_ci exit ${KSFT_FAIL} 6262306a36Sopenharmony_ci fi 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci return 1 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci# $1: file 6862306a36Sopenharmony_cimptcp_lib_has_file() { 6962306a36Sopenharmony_ci local f="${1}" 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci if [ -f "${f}" ]; then 7262306a36Sopenharmony_ci return 0 7362306a36Sopenharmony_ci fi 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci mptcp_lib_fail_if_expected_feature "${f} file not found" 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cimptcp_lib_check_mptcp() { 7962306a36Sopenharmony_ci if ! mptcp_lib_has_file "/proc/sys/net/mptcp/enabled"; then 8062306a36Sopenharmony_ci echo "SKIP: MPTCP support is not available" 8162306a36Sopenharmony_ci exit ${KSFT_SKIP} 8262306a36Sopenharmony_ci fi 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cimptcp_lib_check_kallsyms() { 8662306a36Sopenharmony_ci if ! mptcp_lib_has_file "/proc/kallsyms"; then 8762306a36Sopenharmony_ci echo "SKIP: CONFIG_KALLSYMS is missing" 8862306a36Sopenharmony_ci exit ${KSFT_SKIP} 8962306a36Sopenharmony_ci fi 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci# Internal: use mptcp_lib_kallsyms_has() instead 9362306a36Sopenharmony_ci__mptcp_lib_kallsyms_has() { 9462306a36Sopenharmony_ci local sym="${1}" 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci mptcp_lib_check_kallsyms 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci grep -q " ${sym}" /proc/kallsyms 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci# $1: part of a symbol to look at, add '$' at the end for full name 10262306a36Sopenharmony_cimptcp_lib_kallsyms_has() { 10362306a36Sopenharmony_ci local sym="${1}" 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if __mptcp_lib_kallsyms_has "${sym}"; then 10662306a36Sopenharmony_ci return 0 10762306a36Sopenharmony_ci fi 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci mptcp_lib_fail_if_expected_feature "${sym} symbol not found" 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci# $1: part of a symbol to look at, add '$' at the end for full name 11362306a36Sopenharmony_cimptcp_lib_kallsyms_doesnt_have() { 11462306a36Sopenharmony_ci local sym="${1}" 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if ! __mptcp_lib_kallsyms_has "${sym}"; then 11762306a36Sopenharmony_ci return 0 11862306a36Sopenharmony_ci fi 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci mptcp_lib_fail_if_expected_feature "${sym} symbol has been found" 12162306a36Sopenharmony_ci} 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci# !!!AVOID USING THIS!!! 12462306a36Sopenharmony_ci# Features might not land in the expected version and features can be backported 12562306a36Sopenharmony_ci# 12662306a36Sopenharmony_ci# $1: kernel version, e.g. 6.3 12762306a36Sopenharmony_cimptcp_lib_kversion_ge() { 12862306a36Sopenharmony_ci local exp_maj="${1%.*}" 12962306a36Sopenharmony_ci local exp_min="${1#*.}" 13062306a36Sopenharmony_ci local v maj min 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci # If the kernel has backported features, set this env var to 1: 13362306a36Sopenharmony_ci if [ "${SELFTESTS_MPTCP_LIB_NO_KVERSION_CHECK:-}" = "1" ]; then 13462306a36Sopenharmony_ci return 0 13562306a36Sopenharmony_ci fi 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci v=$(uname -r | cut -d'.' -f1,2) 13862306a36Sopenharmony_ci maj=${v%.*} 13962306a36Sopenharmony_ci min=${v#*.} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci if [ "${maj}" -gt "${exp_maj}" ] || 14262306a36Sopenharmony_ci { [ "${maj}" -eq "${exp_maj}" ] && [ "${min}" -ge "${exp_min}" ]; }; then 14362306a36Sopenharmony_ci return 0 14462306a36Sopenharmony_ci fi 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}" 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci__mptcp_lib_result_add() { 15062306a36Sopenharmony_ci local result="${1}" 15162306a36Sopenharmony_ci shift 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1)) 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*}") 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci# $1: test name 15962306a36Sopenharmony_cimptcp_lib_result_pass() { 16062306a36Sopenharmony_ci __mptcp_lib_result_add "ok" "${1}" 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci# $1: test name 16462306a36Sopenharmony_cimptcp_lib_result_fail() { 16562306a36Sopenharmony_ci __mptcp_lib_result_add "not ok" "${1}" 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci# $1: test name 16962306a36Sopenharmony_cimptcp_lib_result_skip() { 17062306a36Sopenharmony_ci __mptcp_lib_result_add "ok" "${1} # SKIP" 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci# $1: result code ; $2: test name 17462306a36Sopenharmony_cimptcp_lib_result_code() { 17562306a36Sopenharmony_ci local ret="${1}" 17662306a36Sopenharmony_ci local name="${2}" 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci case "${ret}" in 17962306a36Sopenharmony_ci "${KSFT_PASS}") 18062306a36Sopenharmony_ci mptcp_lib_result_pass "${name}" 18162306a36Sopenharmony_ci ;; 18262306a36Sopenharmony_ci "${KSFT_FAIL}") 18362306a36Sopenharmony_ci mptcp_lib_result_fail "${name}" 18462306a36Sopenharmony_ci ;; 18562306a36Sopenharmony_ci "${KSFT_SKIP}") 18662306a36Sopenharmony_ci mptcp_lib_result_skip "${name}" 18762306a36Sopenharmony_ci ;; 18862306a36Sopenharmony_ci *) 18962306a36Sopenharmony_ci echo "ERROR: wrong result code: ${ret}" 19062306a36Sopenharmony_ci exit ${KSFT_FAIL} 19162306a36Sopenharmony_ci ;; 19262306a36Sopenharmony_ci esac 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cimptcp_lib_result_print_all_tap() { 19662306a36Sopenharmony_ci local subtest 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci if [ ${#MPTCP_LIB_SUBTESTS[@]} -eq 0 ] || 19962306a36Sopenharmony_ci [ "${SELFTESTS_MPTCP_LIB_NO_TAP:-}" = "1" ]; then 20062306a36Sopenharmony_ci return 20162306a36Sopenharmony_ci fi 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci printf "\nTAP version 13\n" 20462306a36Sopenharmony_ci printf "1..%d\n" "${#MPTCP_LIB_SUBTESTS[@]}" 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do 20762306a36Sopenharmony_ci printf "%s\n" "${subtest}" 20862306a36Sopenharmony_ci done 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci# get the value of keyword $1 in the line marked by keyword $2 21262306a36Sopenharmony_cimptcp_lib_get_info_value() { 21362306a36Sopenharmony_ci grep "${2}" | sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q' 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci# $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]] 21762306a36Sopenharmony_cimptcp_lib_evts_get_info() { 21862306a36Sopenharmony_ci grep "${4:-}" "${2}" | mptcp_lib_get_info_value "${1}" "^type:${3:-1}," 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci# $1: PID 22262306a36Sopenharmony_cimptcp_lib_kill_wait() { 22362306a36Sopenharmony_ci [ "${1}" -eq 0 ] && return 0 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci kill -SIGUSR1 "${1}" > /dev/null 2>&1 22662306a36Sopenharmony_ci kill "${1}" > /dev/null 2>&1 22762306a36Sopenharmony_ci wait "${1}" 2>/dev/null 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci# $1: IP address 23162306a36Sopenharmony_cimptcp_lib_is_v6() { 23262306a36Sopenharmony_ci [ -z "${1##*:*}" ] 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci# $1: ns, $2: MIB counter 23662306a36Sopenharmony_cimptcp_lib_get_counter() { 23762306a36Sopenharmony_ci local ns="${1}" 23862306a36Sopenharmony_ci local counter="${2}" 23962306a36Sopenharmony_ci local count 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci count=$(ip netns exec "${ns}" nstat -asz "${counter}" | 24262306a36Sopenharmony_ci awk 'NR==1 {next} {print $2}') 24362306a36Sopenharmony_ci if [ -z "${count}" ]; then 24462306a36Sopenharmony_ci mptcp_lib_fail_if_expected_feature "${counter} counter" 24562306a36Sopenharmony_ci return 1 24662306a36Sopenharmony_ci fi 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci echo "${count}" 24962306a36Sopenharmony_ci} 250