mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-14 06:22:34 +02:00
Use ping and tcpdump to verify that independent rx and tx enablement of team driver member interfaces works as intended. Signed-off-by: Marc Harvey <marcharvey@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260409-teaming-driver-internal-v7-10-f47e7589685d@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
250 lines
6.3 KiB
Bash
Executable File
250 lines
6.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
# These tests verify the decoupled RX and TX enablement of team driver member
|
|
# interfaces.
|
|
#
|
|
# Topology
|
|
#
|
|
# +---------------------+ NS1
|
|
# | test_team1 |
|
|
# | | |
|
|
# | eth0 |
|
|
# | | |
|
|
# | | |
|
|
# +---------------------+
|
|
# |
|
|
# +---------------------+ NS2
|
|
# | | |
|
|
# | | |
|
|
# | eth0 |
|
|
# | | |
|
|
# | test_team2 |
|
|
# +---------------------+
|
|
|
|
export ALL_TESTS="
|
|
team_test_tx_enablement
|
|
team_test_rx_enablement
|
|
"
|
|
|
|
test_dir="$(dirname "$0")"
|
|
# shellcheck disable=SC1091
|
|
source "${test_dir}/../../../net/lib.sh"
|
|
# shellcheck disable=SC1091
|
|
source "${test_dir}/team_lib.sh"
|
|
|
|
NS1=""
|
|
NS2=""
|
|
export NODAD="nodad"
|
|
PREFIX_LENGTH="64"
|
|
NS1_IP="fd00::1"
|
|
NS2_IP="fd00::2"
|
|
NS1_IP4="192.168.0.1"
|
|
NS2_IP4="192.168.0.2"
|
|
MEMBERS=("eth0")
|
|
PING_COUNT=5
|
|
PING_TIMEOUT_S=1
|
|
PING_INTERVAL=0.1
|
|
|
|
while getopts "4" opt; do
|
|
case $opt in
|
|
4)
|
|
echo "IPv4 mode selected."
|
|
export NODAD=
|
|
PREFIX_LENGTH="24"
|
|
NS1_IP="${NS1_IP4}"
|
|
NS2_IP="${NS2_IP4}"
|
|
;;
|
|
\?)
|
|
echo "Invalid option: -$OPTARG" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# This has to be sourced after opts are gathered...
|
|
export REQUIRE_MZ=no
|
|
export NUM_NETIFS=0
|
|
# shellcheck disable=SC1091
|
|
source "${test_dir}/../../../net/forwarding/lib.sh"
|
|
|
|
# Create the network namespaces, veth pair, and team devices in the specified
|
|
# mode.
|
|
# Globals:
|
|
# RET - Used by test infra, set by `check_err` functions.
|
|
# Arguments:
|
|
# mode - The team driver mode to use for the team devices.
|
|
environment_create()
|
|
{
|
|
trap cleanup_all_ns EXIT
|
|
setup_ns ns1 ns2
|
|
NS1="${NS_LIST[0]}"
|
|
NS2="${NS_LIST[1]}"
|
|
|
|
# Create the interfaces.
|
|
ip -n "${NS1}" link add eth0 type veth peer name eth0 netns "${NS2}"
|
|
ip -n "${NS1}" link add test_team1 type team
|
|
ip -n "${NS2}" link add test_team2 type team
|
|
|
|
# Set up the receiving network namespace's team interface.
|
|
setup_team "${NS2}" test_team2 roundrobin "${NS2_IP}" \
|
|
"${PREFIX_LENGTH}" "${MEMBERS[@]}"
|
|
}
|
|
|
|
# Set a particular option value for team or team port.
|
|
# Arguments:
|
|
# namespace - The namespace name that has the team.
|
|
# option_name - The option name to set.
|
|
# option_value - The value to set the option to.
|
|
# team_name - The name of team to set the option for.
|
|
# member_name - The (optional) optional name of the member port.
|
|
set_option_value()
|
|
{
|
|
local namespace="$1"
|
|
local option_name="$2"
|
|
local option_value="$3"
|
|
local team_name="$4"
|
|
local member_name="$5"
|
|
local port_flag="--port=${member_name}"
|
|
|
|
ip netns exec "${namespace}" teamnl "${team_name}" setoption \
|
|
"${option_name}" "${option_value}" "${port_flag}"
|
|
return $?
|
|
}
|
|
|
|
# Send some pings and return the ping command return value.
|
|
try_ping()
|
|
{
|
|
ip netns exec "${NS1}" ping -i "${PING_INTERVAL}" -c "${PING_COUNT}" \
|
|
"${NS2_IP}" -W "${PING_TIMEOUT_S}"
|
|
}
|
|
|
|
# Checks tcpdump output from net/forwarding lib, and checks if there are any
|
|
# ICMP(4 or 6) packets.
|
|
# Arguments:
|
|
# interface - The interface name to search for.
|
|
# ip_address - The destination IP address (4 or 6) to search for.
|
|
did_interface_receive_icmp()
|
|
{
|
|
local interface="$1"
|
|
local ip_address="$2"
|
|
local packet_count
|
|
|
|
packet_count=$(tcpdump_show "$interface" | grep -c \
|
|
"> ${ip_address}: ICMP")
|
|
echo "Packet count for ${interface} was ${packet_count}"
|
|
|
|
if [[ "$packet_count" -gt 0 ]]; then
|
|
true
|
|
else
|
|
false
|
|
fi
|
|
}
|
|
|
|
# Test JUST tx enablement with a given mode.
|
|
# Globals:
|
|
# RET - Used by test infra, set by `check_err` functions.
|
|
# Arguments:
|
|
# mode - The mode to set the team interfaces to.
|
|
team_test_mode_tx_enablement()
|
|
{
|
|
local mode="$1"
|
|
export RET=0
|
|
|
|
# Set up the sender team with the correct mode.
|
|
setup_team "${NS1}" test_team1 "${mode}" "${NS1_IP}" \
|
|
"${PREFIX_LENGTH}" "${MEMBERS[@]}"
|
|
check_err $? "Failed to set up sender team"
|
|
|
|
### Scenario 1: Member interface initially enabled.
|
|
# Expect ping to pass
|
|
try_ping
|
|
check_err $? "Ping failed when TX enabled"
|
|
|
|
### Scenario 2: One tx-side interface disabled.
|
|
# Expect ping to fail.
|
|
set_option_value "${NS1}" tx_enabled false test_team1 eth0
|
|
check_err $? "Failed to disable TX"
|
|
tcpdump_start eth0 "${NS2}"
|
|
try_ping
|
|
check_fail $? "Ping succeeded when TX disabled"
|
|
tcpdump_stop eth0
|
|
# Expect no packets to be transmitted, since TX is disabled.
|
|
did_interface_receive_icmp eth0 "${NS2_IP}"
|
|
check_fail $? "eth0 IS transmitting when TX disabled"
|
|
tcpdump_cleanup eth0
|
|
|
|
### Scenario 3: The interface has tx re-enabled.
|
|
# Expect ping to pass.
|
|
set_option_value "${NS1}" tx_enabled true test_team1 eth0
|
|
check_err $? "Failed to reenable TX"
|
|
try_ping
|
|
check_err $? "Ping failed when TX reenabled"
|
|
|
|
log_test "TX failover of '${mode}' test"
|
|
}
|
|
|
|
# Test JUST rx enablement with a given mode.
|
|
# Globals:
|
|
# RET - Used by test infra, set by `check_err` functions.
|
|
# Arguments:
|
|
# mode - The mode to set the team interfaces to.
|
|
team_test_mode_rx_enablement()
|
|
{
|
|
local mode="$1"
|
|
export RET=0
|
|
|
|
# Set up the sender team with the correct mode.
|
|
setup_team "${NS1}" test_team1 "${mode}" "${NS1_IP}" \
|
|
"${PREFIX_LENGTH}" "${MEMBERS[@]}"
|
|
check_err $? "Failed to set up sender team"
|
|
|
|
### Scenario 1: Member interface initially enabled.
|
|
# Expect ping to pass
|
|
try_ping
|
|
check_err $? "Ping failed when RX enabled"
|
|
|
|
### Scenario 2: One rx-side interface disabled.
|
|
# Expect ping to fail.
|
|
set_option_value "${NS1}" rx_enabled false test_team1 eth0
|
|
check_err $? "Failed to disable RX"
|
|
tcpdump_start eth0 "${NS2}"
|
|
try_ping
|
|
check_fail $? "Ping succeeded when RX disabled"
|
|
tcpdump_stop eth0
|
|
# Expect packets to be transmitted, since only RX is disabled.
|
|
did_interface_receive_icmp eth0 "${NS2_IP}"
|
|
check_err $? "eth0 not transmitting when RX disabled"
|
|
tcpdump_cleanup eth0
|
|
|
|
### Scenario 3: The interface has rx re-enabled.
|
|
# Expect ping to pass.
|
|
set_option_value "${NS1}" rx_enabled true test_team1 eth0
|
|
check_err $? "Failed to reenable RX"
|
|
try_ping
|
|
check_err $? "Ping failed when RX reenabled"
|
|
|
|
log_test "RX failover of '${mode}' test"
|
|
}
|
|
|
|
team_test_tx_enablement()
|
|
{
|
|
team_test_mode_tx_enablement broadcast
|
|
team_test_mode_tx_enablement roundrobin
|
|
team_test_mode_tx_enablement random
|
|
}
|
|
|
|
team_test_rx_enablement()
|
|
{
|
|
team_test_mode_rx_enablement broadcast
|
|
team_test_mode_rx_enablement roundrobin
|
|
team_test_mode_rx_enablement random
|
|
}
|
|
|
|
require_command teamnl
|
|
require_command tcpdump
|
|
require_command ping
|
|
environment_create
|
|
tests_run
|
|
exit "${EXIT_STATUS}"
|