blob: 0d3d9c98e9f5b9b9d29dc2542baf5173da78cf86 [file] [edit]
#!/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}"