| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- #! /bin/bash
- # SPDX-License-Identifier: GPL-2.0
- . "$(dirname "${0}")/../lib.sh"
- readonly KSFT_PASS=0
- readonly KSFT_FAIL=1
- readonly KSFT_SKIP=4
- # shellcheck disable=SC2155 # declare and assign separately
- readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}"
- # These variables are used in some selftests, read-only
- declare -rx MPTCP_LIB_EVENT_CREATED=1 # MPTCP_EVENT_CREATED
- declare -rx MPTCP_LIB_EVENT_ESTABLISHED=2 # MPTCP_EVENT_ESTABLISHED
- declare -rx MPTCP_LIB_EVENT_CLOSED=3 # MPTCP_EVENT_CLOSED
- declare -rx MPTCP_LIB_EVENT_ANNOUNCED=6 # MPTCP_EVENT_ANNOUNCED
- declare -rx MPTCP_LIB_EVENT_REMOVED=7 # MPTCP_EVENT_REMOVED
- declare -rx MPTCP_LIB_EVENT_SUB_ESTABLISHED=10 # MPTCP_EVENT_SUB_ESTABLISHED
- declare -rx MPTCP_LIB_EVENT_SUB_CLOSED=11 # MPTCP_EVENT_SUB_CLOSED
- declare -rx MPTCP_LIB_EVENT_SUB_PRIORITY=13 # MPTCP_EVENT_SUB_PRIORITY
- declare -rx MPTCP_LIB_EVENT_LISTENER_CREATED=15 # MPTCP_EVENT_LISTENER_CREATED
- declare -rx MPTCP_LIB_EVENT_LISTENER_CLOSED=16 # MPTCP_EVENT_LISTENER_CLOSED
- declare -rx MPTCP_LIB_AF_INET=2
- declare -rx MPTCP_LIB_AF_INET6=10
- MPTCP_LIB_SUBTESTS=()
- MPTCP_LIB_SUBTESTS_DUPLICATED=0
- MPTCP_LIB_SUBTEST_FLAKY=0
- MPTCP_LIB_SUBTESTS_LAST_TS_MS=
- MPTCP_LIB_TEST_COUNTER=0
- MPTCP_LIB_TEST_FORMAT="%02u %-50s"
- MPTCP_LIB_IP_MPTCP=0
- # only if supported (or forced) and not disabled, see no-color.org
- if { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } &&
- [ "${NO_COLOR:-}" != "1" ]; then
- readonly MPTCP_LIB_COLOR_RED="\E[1;31m"
- readonly MPTCP_LIB_COLOR_GREEN="\E[1;32m"
- readonly MPTCP_LIB_COLOR_YELLOW="\E[1;33m"
- readonly MPTCP_LIB_COLOR_BLUE="\E[1;34m"
- readonly MPTCP_LIB_COLOR_RESET="\E[0m"
- else
- readonly MPTCP_LIB_COLOR_RED=
- readonly MPTCP_LIB_COLOR_GREEN=
- readonly MPTCP_LIB_COLOR_YELLOW=
- readonly MPTCP_LIB_COLOR_BLUE=
- readonly MPTCP_LIB_COLOR_RESET=
- fi
- # SELFTESTS_MPTCP_LIB_OVERRIDE_FLAKY env var can be set not to ignore errors
- # from subtests marked as flaky
- mptcp_lib_override_flaky() {
- [ "${SELFTESTS_MPTCP_LIB_OVERRIDE_FLAKY:-}" = 1 ]
- }
- mptcp_lib_subtest_is_flaky() {
- [ "${MPTCP_LIB_SUBTEST_FLAKY}" = 1 ] && ! mptcp_lib_override_flaky
- }
- # $1: color, $2: text
- mptcp_lib_print_color() {
- echo -e "${MPTCP_LIB_START_PRINT:-}${*}${MPTCP_LIB_COLOR_RESET}"
- }
- mptcp_lib_print_ok() {
- mptcp_lib_print_color "${MPTCP_LIB_COLOR_GREEN}${*}"
- }
- mptcp_lib_print_warn() {
- mptcp_lib_print_color "${MPTCP_LIB_COLOR_YELLOW}${*}"
- }
- mptcp_lib_print_info() {
- mptcp_lib_print_color "${MPTCP_LIB_COLOR_BLUE}${*}"
- }
- mptcp_lib_print_err() {
- mptcp_lib_print_color "${MPTCP_LIB_COLOR_RED}${*}"
- }
- # shellcheck disable=SC2120 # parameters are optional
- mptcp_lib_pr_ok() {
- mptcp_lib_print_ok "[ OK ]${1:+ ${*}}"
- }
- mptcp_lib_pr_skip() {
- mptcp_lib_print_warn "[SKIP]${1:+ ${*}}"
- }
- mptcp_lib_pr_fail() {
- local title cmt
- if mptcp_lib_subtest_is_flaky; then
- title="IGNO"
- cmt=" (flaky)"
- else
- title="FAIL"
- fi
- mptcp_lib_print_err "[${title}]${cmt}${1:+ ${*}}"
- }
- mptcp_lib_pr_info() {
- mptcp_lib_print_info "INFO: ${*}"
- }
- mptcp_lib_pr_nstat() {
- local ns="${1}"
- local hist="/tmp/${ns}.out"
- if [ -f "${hist}" ]; then
- awk '$2 != 0 { print " "$0 }' "${hist}"
- else
- ip netns exec "${ns}" nstat -as | grep Tcp
- fi
- }
- # $1-2: listener/connector ns ; $3 port
- mptcp_lib_pr_err_stats() {
- local lns="${1}"
- local cns="${2}"
- local port="${3}"
- echo -en "${MPTCP_LIB_COLOR_RED}"
- {
- printf "\nnetns %s (listener) socket stat for %d:\n" "${lns}" "${port}"
- ip netns exec "${lns}" ss -Menitam -o "sport = :${port}"
- mptcp_lib_pr_nstat "${lns}"
- printf "\nnetns %s (connector) socket stat for %d:\n" "${cns}" "${port}"
- ip netns exec "${cns}" ss -Menitam -o "dport = :${port}"
- [ "${lns}" != "${cns}" ] && mptcp_lib_pr_nstat "${cns}"
- } 1>&2
- echo -en "${MPTCP_LIB_COLOR_RESET}"
- }
- # SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all
- # features using the last version of the kernel and the selftests to make sure
- # a test is not being skipped by mistake.
- mptcp_lib_expect_all_features() {
- [ "${SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES:-}" = "1" ]
- }
- # $1: msg
- mptcp_lib_fail_if_expected_feature() {
- if mptcp_lib_expect_all_features; then
- echo "ERROR: missing feature: ${*}"
- exit ${KSFT_FAIL}
- fi
- return 1
- }
- # $1: file
- mptcp_lib_has_file() {
- local f="${1}"
- if [ -f "${f}" ]; then
- return 0
- fi
- mptcp_lib_fail_if_expected_feature "${f} file not found"
- }
- mptcp_lib_check_mptcp() {
- if ! mptcp_lib_has_file "/proc/sys/net/mptcp/enabled"; then
- mptcp_lib_pr_skip "MPTCP support is not available"
- exit ${KSFT_SKIP}
- fi
- }
- mptcp_lib_check_kallsyms() {
- if ! mptcp_lib_has_file "/proc/kallsyms"; then
- mptcp_lib_pr_skip "CONFIG_KALLSYMS is missing"
- exit ${KSFT_SKIP}
- fi
- }
- # Internal: use mptcp_lib_kallsyms_has() instead
- __mptcp_lib_kallsyms_has() {
- local sym="${1}"
- mptcp_lib_check_kallsyms
- grep -q " ${sym}" /proc/kallsyms
- }
- # $1: part of a symbol to look at, add '$' at the end for full name
- mptcp_lib_kallsyms_has() {
- local sym="${1}"
- if __mptcp_lib_kallsyms_has "${sym}"; then
- return 0
- fi
- mptcp_lib_fail_if_expected_feature "${sym} symbol not found"
- }
- # $1: part of a symbol to look at, add '$' at the end for full name
- mptcp_lib_kallsyms_doesnt_have() {
- local sym="${1}"
- if ! __mptcp_lib_kallsyms_has "${sym}"; then
- return 0
- fi
- mptcp_lib_fail_if_expected_feature "${sym} symbol has been found"
- }
- # !!!AVOID USING THIS!!!
- # Features might not land in the expected version and features can be backported
- #
- # $1: kernel version, e.g. 6.3
- mptcp_lib_kversion_ge() {
- local exp_maj="${1%.*}"
- local exp_min="${1#*.}"
- local v maj min
- # If the kernel has backported features, set this env var to 1:
- if [ "${SELFTESTS_MPTCP_LIB_NO_KVERSION_CHECK:-}" = "1" ]; then
- return 0
- fi
- v=$(uname -r | cut -d'.' -f1,2)
- maj=${v%.*}
- min=${v#*.}
- if [ "${maj}" -gt "${exp_maj}" ] ||
- { [ "${maj}" -eq "${exp_maj}" ] && [ "${min}" -ge "${exp_min}" ]; }; then
- return 0
- fi
- mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}"
- }
- mptcp_lib_subtests_last_ts_reset() {
- MPTCP_LIB_SUBTESTS_LAST_TS_MS="$(date +%s%3N)"
- }
- mptcp_lib_subtests_last_ts_reset
- __mptcp_lib_result_check_duplicated() {
- local subtest
- for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do
- if [[ "${subtest}" == *" - ${KSFT_TEST}: ${*%% #*}" ]]; then
- MPTCP_LIB_SUBTESTS_DUPLICATED=1
- mptcp_lib_print_err "Duplicated entry: ${*}"
- break
- fi
- done
- }
- __mptcp_lib_result_add() {
- local result="${1}"
- local time="time="
- local ts_prev_ms
- shift
- local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1))
- __mptcp_lib_result_check_duplicated "${*}"
- # not to add two '#'
- [[ "${*}" != *"#"* ]] && time="# ${time}"
- ts_prev_ms="${MPTCP_LIB_SUBTESTS_LAST_TS_MS}"
- mptcp_lib_subtests_last_ts_reset
- time+="$((MPTCP_LIB_SUBTESTS_LAST_TS_MS - ts_prev_ms))ms"
- MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*} ${time}")
- }
- # $1: test name
- mptcp_lib_result_pass() {
- __mptcp_lib_result_add "ok" "${1}"
- }
- # $1: test name
- mptcp_lib_result_fail() {
- if mptcp_lib_subtest_is_flaky; then
- # It might sound better to use 'not ok # TODO' or 'ok # SKIP',
- # but some CIs don't understand 'TODO' and treat SKIP as errors.
- __mptcp_lib_result_add "ok" "${1} # IGNORE Flaky"
- else
- __mptcp_lib_result_add "not ok" "${1}"
- fi
- }
- # $1: test name
- mptcp_lib_result_skip() {
- __mptcp_lib_result_add "ok" "${1} # SKIP"
- }
- # $1: result code ; $2: test name
- mptcp_lib_result_code() {
- local ret="${1}"
- local name="${2}"
- case "${ret}" in
- "${KSFT_PASS}")
- mptcp_lib_result_pass "${name}"
- ;;
- "${KSFT_FAIL}")
- mptcp_lib_result_fail "${name}"
- ;;
- "${KSFT_SKIP}")
- mptcp_lib_result_skip "${name}"
- ;;
- *)
- echo "ERROR: wrong result code: ${ret}"
- exit ${KSFT_FAIL}
- ;;
- esac
- }
- mptcp_lib_result_print_all_tap() {
- local subtest
- if [ ${#MPTCP_LIB_SUBTESTS[@]} -eq 0 ] ||
- [ "${SELFTESTS_MPTCP_LIB_NO_TAP:-}" = "1" ]; then
- return
- fi
- printf "\nTAP version 13\n"
- printf "1..%d\n" "${#MPTCP_LIB_SUBTESTS[@]}"
- for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do
- printf "%s\n" "${subtest}"
- done
- if [ "${MPTCP_LIB_SUBTESTS_DUPLICATED}" = 1 ] &&
- mptcp_lib_expect_all_features; then
- mptcp_lib_print_err "Duplicated test entries"
- exit ${KSFT_FAIL}
- fi
- }
- # get the value of keyword $1 in the line marked by keyword $2
- mptcp_lib_get_info_value() {
- grep "${2}" 2>/dev/null |
- sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q'
- # the ';q' at the end limits to the first matched entry.
- }
- # $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]]
- mptcp_lib_evts_get_info() {
- grep "${4:-}" "${2}" 2>/dev/null |
- mptcp_lib_get_info_value "${1}" "^type:${3:-1},"
- }
- mptcp_lib_wait_timeout() {
- local timeout_test="${1}"
- local listener_ns="${2}"
- local connector_ns="${3}"
- local port="${4}"
- shift 4 # rest are PIDs
- sleep "${timeout_test}"
- mptcp_lib_print_err "timeout"
- mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
- kill "${@}" 2>/dev/null
- }
- # $1: PID
- mptcp_lib_kill_wait() {
- [ "${1}" -eq 0 ] && return 0
- kill -SIGUSR1 "${1}" > /dev/null 2>&1
- kill "${1}" > /dev/null 2>&1
- wait "${1}" 2>/dev/null
- }
- # $1: PID
- mptcp_lib_pid_list_children() {
- local curr="${1}"
- # evoke 'ps' only once
- local pids="${2:-"$(ps o pid,ppid)"}"
- echo "${curr}"
- local pid
- for pid in $(echo "${pids}" | awk "\$2 == ${curr} { print \$1 }"); do
- mptcp_lib_pid_list_children "${pid}" "${pids}"
- done
- }
- # $1: PID
- mptcp_lib_kill_group_wait() {
- # Some users might not have procps-ng: cannot use "kill -- -PID"
- mptcp_lib_pid_list_children "${1}" | xargs -r kill &>/dev/null
- wait "${1}" 2>/dev/null
- }
- # $1: IP address
- mptcp_lib_is_v6() {
- [ -z "${1##*:*}" ]
- }
- mptcp_lib_nstat_init() {
- local ns="${1}"
- rm -f "/tmp/${ns}."{nstat,out}
- NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -n
- }
- mptcp_lib_nstat_get() {
- local ns="${1}"
- # filter out non-*TCP stats, and the rate (last column)
- NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -sz |
- grep -o ".*Tcp\S\+\s\+[0-9]\+" > "/tmp/${ns}.out"
- }
- # $1: ns, $2: MIB counter
- # Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available.
- # If not, get the counter from nstat ignoring any history.
- mptcp_lib_get_counter() {
- local ns="${1}"
- local counter="${2}"
- local hist="/tmp/${ns}.out"
- local count
- if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then
- count=$(awk "/^${counter} / {print \$2; exit}" "${hist}")
- else
- count=$(ip netns exec "${ns}" nstat -asz "${counter}" |
- awk 'NR==1 {next} {print $2}')
- fi
- if [ -z "${count}" ]; then
- mptcp_lib_fail_if_expected_feature "${counter} counter"
- return 1
- fi
- echo "${count}"
- }
- mptcp_lib_make_file() {
- local name="${1}"
- local bs="${2}"
- local size="${3}"
- dd if=/dev/urandom of="${name}" bs="${bs}" count="${size}" 2> /dev/null
- echo -e "\nMPTCP_TEST_FILE_END_MARKER" >> "${name}"
- }
- # $1: file
- mptcp_lib_print_file_err() {
- ls -l "${1}" 1>&2
- echo "Trailing bytes are: "
- tail -c 32 "${1}" | od -x | head -n2
- }
- # $1: input file ; $2: output file ; $3: what kind of file
- mptcp_lib_check_transfer() {
- local in="${1}"
- local out="${2}"
- local what="${3}"
- if ! cmp "$in" "$out" > /dev/null 2>&1; then
- mptcp_lib_pr_fail "$what does not match (in, out):"
- mptcp_lib_print_file_err "$in"
- mptcp_lib_print_file_err "$out"
- return 1
- fi
- return 0
- }
- # $1: ns, $2: port
- mptcp_lib_wait_local_port_listen() {
- wait_local_port_listen "${@}" "tcp"
- }
- mptcp_lib_check_output() {
- local err="${1}"
- local cmd="${2}"
- local expected="${3}"
- local cmd_ret=0
- local out
- if ! out=$(${cmd} 2>"${err}"); then
- cmd_ret=${?}
- fi
- if [ ${cmd_ret} -ne 0 ]; then
- mptcp_lib_pr_fail "command execution '${cmd}' stderr"
- cat "${err}"
- return 2
- elif [ "${out}" = "${expected}" ]; then
- return 0
- else
- mptcp_lib_pr_fail "expected '${expected}' got '${out}'"
- return 1
- fi
- }
- mptcp_lib_check_tools() {
- local tool
- for tool in "${@}"; do
- case "${tool}" in
- "ip")
- if ! ip -Version &> /dev/null; then
- mptcp_lib_pr_skip "Could not run test without ip tool"
- exit ${KSFT_SKIP}
- fi
- ;;
- "tc")
- if ! tc -help &> /dev/null; then
- mptcp_lib_pr_skip "Could not run test without tc tool"
- exit ${KSFT_SKIP}
- fi
- ;;
- "ss")
- if ! ss -h | grep -q MPTCP; then
- mptcp_lib_pr_skip "ss tool does not support MPTCP"
- exit ${KSFT_SKIP}
- fi
- ;;
- "iptables"* | "ip6tables"*)
- if ! "${tool}" -V &> /dev/null; then
- mptcp_lib_pr_skip "Could not run all tests without ${tool}"
- exit ${KSFT_SKIP}
- fi
- ;;
- *)
- mptcp_lib_pr_fail "Internal error: unsupported tool: ${tool}"
- exit ${KSFT_FAIL}
- ;;
- esac
- done
- }
- mptcp_lib_ns_init() {
- if ! setup_ns "${@}"; then
- mptcp_lib_pr_fail "Failed to setup namespaces ${*}"
- exit ${KSFT_FAIL}
- fi
- local netns
- for netns in "${@}"; do
- ip netns exec "${!netns}" sysctl -q net.mptcp.enabled=1
- done
- }
- mptcp_lib_ns_exit() {
- cleanup_ns "${@}"
- local netns
- for netns in "${@}"; do
- rm -f /tmp/"${netns}".{nstat,out}
- done
- }
- mptcp_lib_events() {
- local ns="${1}"
- local evts="${2}"
- declare -n pid="${3}"
- :>"${evts}"
- mptcp_lib_kill_wait "${pid:-0}"
- ip netns exec "${ns}" ./pm_nl_ctl events >> "${evts}" 2>&1 &
- pid=$!
- }
- mptcp_lib_print_title() {
- : "${MPTCP_LIB_TEST_COUNTER:?}"
- : "${MPTCP_LIB_TEST_FORMAT:?}"
- # shellcheck disable=SC2059 # the format is in a variable
- printf "${MPTCP_LIB_TEST_FORMAT}" "$((++MPTCP_LIB_TEST_COUNTER))" "${*}"
- }
- # $1: var name ; $2: prev ret
- mptcp_lib_check_expected_one() {
- local var="${1}"
- local exp="e_${var}"
- local prev_ret="${2}"
- if [ "${!var}" = "${!exp}" ]; then
- return 0
- fi
- if [ "${prev_ret}" = "0" ]; then
- mptcp_lib_pr_fail
- fi
- mptcp_lib_print_err "Expected value for '${var}': '${!exp}', got '${!var}'."
- return 1
- }
- # $@: all var names to check
- mptcp_lib_check_expected() {
- local rc=0
- local var
- for var in "${@}"; do
- mptcp_lib_check_expected_one "${var}" "${rc}" || rc=1
- done
- return "${rc}"
- }
- # shellcheck disable=SC2034 # Some variables are used below but indirectly
- mptcp_lib_verify_listener_events() {
- local evt=${1}
- local e_type=${2}
- local e_family=${3}
- local e_saddr=${4}
- local e_sport=${5}
- local type
- local family
- local saddr
- local sport
- local rc=0
- type=$(mptcp_lib_evts_get_info type "${evt}" "${e_type}")
- family=$(mptcp_lib_evts_get_info family "${evt}" "${e_type}")
- if [ "${family}" ] && [ "${family}" = "${AF_INET6}" ]; then
- saddr=$(mptcp_lib_evts_get_info saddr6 "${evt}" "${e_type}")
- else
- saddr=$(mptcp_lib_evts_get_info saddr4 "${evt}" "${e_type}")
- fi
- sport=$(mptcp_lib_evts_get_info sport "${evt}" "${e_type}")
- mptcp_lib_check_expected "type" "family" "saddr" "sport" || rc="${?}"
- return "${rc}"
- }
- mptcp_lib_set_ip_mptcp() {
- MPTCP_LIB_IP_MPTCP=1
- }
- mptcp_lib_is_ip_mptcp() {
- [ "${MPTCP_LIB_IP_MPTCP}" = "1" ]
- }
- # format: <id>,<ip>,<flags>,<dev>
- mptcp_lib_pm_nl_format_endpoints() {
- local entry id ip flags dev port
- for entry in "${@}"; do
- IFS=, read -r id ip flags dev port <<< "${entry}"
- if mptcp_lib_is_ip_mptcp; then
- echo -n "${ip}"
- [ -n "${port}" ] && echo -n " port ${port}"
- echo -n " id ${id}"
- [ -n "${flags}" ] && echo -n " ${flags}"
- [ -n "${dev}" ] && echo -n " dev ${dev}"
- echo " " # always a space at the end
- else
- echo -n "id ${id}"
- echo -n " flags ${flags//" "/","}"
- [ -n "${dev}" ] && echo -n " dev ${dev}"
- echo -n " ${ip}"
- [ -n "${port}" ] && echo -n " ${port}"
- echo ""
- fi
- done
- }
- mptcp_lib_pm_nl_get_endpoint() {
- local ns=${1}
- local id=${2}
- if mptcp_lib_is_ip_mptcp; then
- ip -n "${ns}" mptcp endpoint show id "${id}"
- else
- ip netns exec "${ns}" ./pm_nl_ctl get "${id}"
- fi
- }
- mptcp_lib_pm_nl_set_limits() {
- local ns=${1}
- local addrs=${2}
- local subflows=${3}
- if mptcp_lib_is_ip_mptcp; then
- ip -n "${ns}" mptcp limits set add_addr_accepted "${addrs}" subflows "${subflows}"
- else
- ip netns exec "${ns}" ./pm_nl_ctl limits "${addrs}" "${subflows}"
- fi
- }
- mptcp_lib_pm_nl_add_endpoint() {
- local ns=${1}
- local addr=${2}
- local flags dev id port
- local nr=2
- local p
- for p in "${@}"; do
- case "${p}" in
- "flags" | "dev" | "id" | "port")
- eval "${p}"=\$"${nr}"
- ;;
- esac
- nr=$((nr + 1))
- done
- if mptcp_lib_is_ip_mptcp; then
- # shellcheck disable=SC2086 # blanks in flags, no double quote
- ip -n "${ns}" mptcp endpoint add "${addr}" ${flags//","/" "} \
- ${dev:+dev "${dev}"} ${id:+id "${id}"} ${port:+port "${port}"}
- else
- ip netns exec "${ns}" ./pm_nl_ctl add "${addr}" ${flags:+flags "${flags}"} \
- ${dev:+dev "${dev}"} ${id:+id "${id}"} ${port:+port "${port}"}
- fi
- }
- mptcp_lib_pm_nl_del_endpoint() {
- local ns=${1}
- local id=${2}
- local addr=${3}
- if mptcp_lib_is_ip_mptcp; then
- [ "${id}" -ne 0 ] && addr=''
- ip -n "${ns}" mptcp endpoint delete id "${id}" ${addr:+"${addr}"}
- else
- ip netns exec "${ns}" ./pm_nl_ctl del "${id}" "${addr}"
- fi
- }
- mptcp_lib_pm_nl_flush_endpoint() {
- local ns=${1}
- if mptcp_lib_is_ip_mptcp; then
- ip -n "${ns}" mptcp endpoint flush
- else
- ip netns exec "${ns}" ./pm_nl_ctl flush
- fi
- }
- mptcp_lib_pm_nl_show_endpoints() {
- local ns=${1}
- if mptcp_lib_is_ip_mptcp; then
- ip -n "${ns}" mptcp endpoint show
- else
- ip netns exec "${ns}" ./pm_nl_ctl dump
- fi
- }
- mptcp_lib_pm_nl_change_endpoint() {
- local ns=${1}
- local id=${2}
- local flags=${3}
- if mptcp_lib_is_ip_mptcp; then
- # shellcheck disable=SC2086 # blanks in flags, no double quote
- ip -n "${ns}" mptcp endpoint change id "${id}" ${flags//","/" "}
- else
- ip netns exec "${ns}" ./pm_nl_ctl set id "${id}" flags "${flags}"
- fi
- }
|