#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # These tests verify the basic failover capability of the team driver via the # `enabled` team driver option across different team driver modes. This does not # rely on teamd, and instead just uses teamnl to set the `enabled` option # directly. # # Topology: # # +-------------------------+ NS1 # | test_team1 | # | + | # | eth0 | eth1 | # | +---+---+ | # | | | | # +-------------------------+ # | | # +-------------------------+ NS2 # | | | | # | +-------+ | # | eth0 | eth1 | # | + | # | test_team2 | # +-------------------------+ export ALL_TESTS="team_test_failover" 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" "eth1") 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 # 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 eth1 type veth peer name eth1 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[@]}" } # Check that failover works for a specific team driver 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_failover() { 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" start_listening_and_sending ### Scenario 1: All interfaces initially enabled. save_tcpdump_outputs "${NS2}" "${MEMBERS[@]}" did_interface_receive eth0 "${NS2_IP}" check_err $? "eth0 not transmitting when both links enabled" did_interface_receive eth1 "${NS2_IP}" check_err $? "eth1 not transmitting when both links enabled" clear_tcpdump_outputs "${MEMBERS[@]}" ### Scenario 2: One tx-side interface disabled. ip netns exec "${NS1}" teamnl test_team1 setoption enabled false \ --port=eth1 slowwait 2 bash -c "ip netns exec ${NS1} teamnl test_team1 getoption \ enabled --port=eth1 | grep -q false" save_tcpdump_outputs "${NS2}" "${MEMBERS[@]}" did_interface_receive eth0 "${NS2_IP}" check_err $? "eth0 not transmitting when enabled" did_interface_receive eth1 "${NS2_IP}" check_fail $? "eth1 IS transmitting when disabled" clear_tcpdump_outputs "${MEMBERS[@]}" ### Scenario 3: The interface is re-enabled. ip netns exec "${NS1}" teamnl test_team1 setoption enabled true \ --port=eth1 slowwait 2 bash -c "ip netns exec ${NS1} teamnl test_team1 getoption \ enabled --port=eth1 | grep -q true" save_tcpdump_outputs "${NS2}" "${MEMBERS[@]}" did_interface_receive eth0 "${NS2_IP}" check_err $? "eth0 not transmitting when both links enabled" did_interface_receive eth1 "${NS2_IP}" check_err $? "eth1 not transmitting when both links enabled" clear_tcpdump_outputs "${MEMBERS[@]}" log_test "Failover of '${mode}' test" # Clean up stop_sending_and_listening } team_test_failover() { team_test_mode_failover broadcast team_test_mode_failover roundrobin team_test_mode_failover random # Don't test `activebackup` or `loadbalance` modes, since they are too # complicated for just setting `enabled` to work. They use more than # the `enabled` option for transmit. } require_command teamnl require_command iperf3 require_command tcpdump environment_create tests_run exit "${EXIT_STATUS}"