1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/tools/testing/selftests/net/lib.sh
Hangbin Liu ea63ac1429 selftests/net: use tc rule to filter the na packet
Test arp_ndisc_untracked_subnets use tcpdump to filter the unsolicited
and untracked na messages. It set -e before calling tcpdump. But if
tcpdump filters 0 packet, it will return none zero, and cause the script
to exit.

Instead of using slow tcpdump to capture packets, let's using tc rule
to filter out the na message.

At the same time, fix function setup_v6 which only needs one parameter.
Move all the related helpers from forwarding lib.sh to net lib.sh.

Fixes: 0ea7b0a454 ("selftests: net: arp_ndisc_untracked_subnets: test for arp_accept and accept_untracked_na")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240517010327.2631319-1-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2024-05-21 13:25:11 +02:00

210 lines
3.5 KiB
Bash

#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
##############################################################################
# Defines
: "${WAIT_TIMEOUT:=20}"
BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms
# Kselftest framework constants.
ksft_pass=0
ksft_fail=1
ksft_xfail=2
ksft_skip=4
# namespace list created by setup_ns
NS_LIST=""
##############################################################################
# Helpers
__ksft_status_merge()
{
local a=$1; shift
local b=$1; shift
local -A weights
local weight=0
for i in "$@"; do
weights[$i]=$((weight++))
done
if [[ ${weights[$a]} > ${weights[$b]} ]]; then
echo "$a"
return 0
else
echo "$b"
return 1
fi
}
ksft_status_merge()
{
local a=$1; shift
local b=$1; shift
__ksft_status_merge "$a" "$b" \
$ksft_pass $ksft_xfail $ksft_skip $ksft_fail
}
ksft_exit_status_merge()
{
local a=$1; shift
local b=$1; shift
__ksft_status_merge "$a" "$b" \
$ksft_xfail $ksft_pass $ksft_skip $ksft_fail
}
loopy_wait()
{
local sleep_cmd=$1; shift
local timeout_ms=$1; shift
local start_time="$(date -u +%s%3N)"
while true
do
local out
out=$("$@")
local ret=$?
if ((!ret)); then
echo -n "$out"
return 0
fi
local current_time="$(date -u +%s%3N)"
if ((current_time - start_time > timeout_ms)); then
echo -n "$out"
return 1
fi
$sleep_cmd
done
}
busywait()
{
local timeout_ms=$1; shift
loopy_wait : "$timeout_ms" "$@"
}
# timeout in seconds
slowwait()
{
local timeout_sec=$1; shift
loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@"
}
until_counter_is()
{
local expr=$1; shift
local current=$("$@")
echo $((current))
((current $expr))
}
busywait_for_counter()
{
local timeout=$1; shift
local delta=$1; shift
local base=$("$@")
busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"
}
slowwait_for_counter()
{
local timeout=$1; shift
local delta=$1; shift
local base=$("$@")
slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@"
}
cleanup_ns()
{
local ns=""
local errexit=0
local ret=0
# disable errexit temporary
if [[ $- =~ "e" ]]; then
errexit=1
set +e
fi
for ns in "$@"; do
ip netns delete "${ns}" &> /dev/null
if ! busywait $BUSYWAIT_TIMEOUT ip netns list \| grep -vq "^$ns$" &> /dev/null; then
echo "Warn: Failed to remove namespace $ns"
ret=1
fi
done
[ $errexit -eq 1 ] && set -e
return $ret
}
cleanup_all_ns()
{
cleanup_ns $NS_LIST
}
# setup netns with given names as prefix. e.g
# setup_ns local remote
setup_ns()
{
local ns=""
local ns_name=""
local ns_list=""
local ns_exist=
for ns_name in "$@"; do
# Some test may setup/remove same netns multi times
if unset ${ns_name} 2> /dev/null; then
ns="${ns_name,,}-$(mktemp -u XXXXXX)"
eval readonly ${ns_name}="$ns"
ns_exist=false
else
eval ns='$'${ns_name}
cleanup_ns "$ns"
ns_exist=true
fi
if ! ip netns add "$ns"; then
echo "Failed to create namespace $ns_name"
cleanup_ns "$ns_list"
return $ksft_skip
fi
ip -n "$ns" link set lo up
! $ns_exist && ns_list="$ns_list $ns"
done
NS_LIST="$NS_LIST $ns_list"
}
tc_rule_stats_get()
{
local dev=$1; shift
local pref=$1; shift
local dir=$1; shift
local selector=${1:-.packets}; shift
tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \
| jq ".[1].options.actions[].stats$selector"
}
tc_rule_handle_stats_get()
{
local id=$1; shift
local handle=$1; shift
local selector=${1:-.packets}; shift
local netns=${1:-""}; shift
tc $netns -j -s filter show $id \
| jq ".[] | select(.options.handle == $handle) | \
.options.actions[0].stats$selector"
}