1*d3870724SMarc Harvey#!/bin/bash 2*d3870724SMarc Harvey# SPDX-License-Identifier: GPL-2.0 3*d3870724SMarc Harvey 4*d3870724SMarc Harvey# These tests verify the decoupled RX and TX enablement of team driver member 5*d3870724SMarc Harvey# interfaces. 6*d3870724SMarc Harvey# 7*d3870724SMarc Harvey# Topology 8*d3870724SMarc Harvey# 9*d3870724SMarc Harvey# +---------------------+ NS1 10*d3870724SMarc Harvey# | test_team1 | 11*d3870724SMarc Harvey# | | | 12*d3870724SMarc Harvey# | eth0 | 13*d3870724SMarc Harvey# | | | 14*d3870724SMarc Harvey# | | | 15*d3870724SMarc Harvey# +---------------------+ 16*d3870724SMarc Harvey# | 17*d3870724SMarc Harvey# +---------------------+ NS2 18*d3870724SMarc Harvey# | | | 19*d3870724SMarc Harvey# | | | 20*d3870724SMarc Harvey# | eth0 | 21*d3870724SMarc Harvey# | | | 22*d3870724SMarc Harvey# | test_team2 | 23*d3870724SMarc Harvey# +---------------------+ 24*d3870724SMarc Harvey 25*d3870724SMarc Harveyexport ALL_TESTS=" 26*d3870724SMarc Harvey team_test_tx_enablement 27*d3870724SMarc Harvey team_test_rx_enablement 28*d3870724SMarc Harvey" 29*d3870724SMarc Harvey 30*d3870724SMarc Harveytest_dir="$(dirname "$0")" 31*d3870724SMarc Harvey# shellcheck disable=SC1091 32*d3870724SMarc Harveysource "${test_dir}/../../../net/lib.sh" 33*d3870724SMarc Harvey# shellcheck disable=SC1091 34*d3870724SMarc Harveysource "${test_dir}/team_lib.sh" 35*d3870724SMarc Harvey 36*d3870724SMarc HarveyNS1="" 37*d3870724SMarc HarveyNS2="" 38*d3870724SMarc Harveyexport NODAD="nodad" 39*d3870724SMarc HarveyPREFIX_LENGTH="64" 40*d3870724SMarc HarveyNS1_IP="fd00::1" 41*d3870724SMarc HarveyNS2_IP="fd00::2" 42*d3870724SMarc HarveyNS1_IP4="192.168.0.1" 43*d3870724SMarc HarveyNS2_IP4="192.168.0.2" 44*d3870724SMarc HarveyMEMBERS=("eth0") 45*d3870724SMarc HarveyPING_COUNT=5 46*d3870724SMarc HarveyPING_TIMEOUT_S=1 47*d3870724SMarc HarveyPING_INTERVAL=0.1 48*d3870724SMarc Harvey 49*d3870724SMarc Harveywhile getopts "4" opt; do 50*d3870724SMarc Harvey case $opt in 51*d3870724SMarc Harvey 4) 52*d3870724SMarc Harvey echo "IPv4 mode selected." 53*d3870724SMarc Harvey export NODAD= 54*d3870724SMarc Harvey PREFIX_LENGTH="24" 55*d3870724SMarc Harvey NS1_IP="${NS1_IP4}" 56*d3870724SMarc Harvey NS2_IP="${NS2_IP4}" 57*d3870724SMarc Harvey ;; 58*d3870724SMarc Harvey \?) 59*d3870724SMarc Harvey echo "Invalid option: -$OPTARG" >&2 60*d3870724SMarc Harvey exit 1 61*d3870724SMarc Harvey ;; 62*d3870724SMarc Harvey esac 63*d3870724SMarc Harveydone 64*d3870724SMarc Harvey 65*d3870724SMarc Harvey# This has to be sourced after opts are gathered... 66*d3870724SMarc Harveyexport REQUIRE_MZ=no 67*d3870724SMarc Harveyexport NUM_NETIFS=0 68*d3870724SMarc Harvey# shellcheck disable=SC1091 69*d3870724SMarc Harveysource "${test_dir}/../../../net/forwarding/lib.sh" 70*d3870724SMarc Harvey 71*d3870724SMarc Harvey# Create the network namespaces, veth pair, and team devices in the specified 72*d3870724SMarc Harvey# mode. 73*d3870724SMarc Harvey# Globals: 74*d3870724SMarc Harvey# RET - Used by test infra, set by `check_err` functions. 75*d3870724SMarc Harvey# Arguments: 76*d3870724SMarc Harvey# mode - The team driver mode to use for the team devices. 77*d3870724SMarc Harveyenvironment_create() 78*d3870724SMarc Harvey{ 79*d3870724SMarc Harvey trap cleanup_all_ns EXIT 80*d3870724SMarc Harvey setup_ns ns1 ns2 81*d3870724SMarc Harvey NS1="${NS_LIST[0]}" 82*d3870724SMarc Harvey NS2="${NS_LIST[1]}" 83*d3870724SMarc Harvey 84*d3870724SMarc Harvey # Create the interfaces. 85*d3870724SMarc Harvey ip -n "${NS1}" link add eth0 type veth peer name eth0 netns "${NS2}" 86*d3870724SMarc Harvey ip -n "${NS1}" link add test_team1 type team 87*d3870724SMarc Harvey ip -n "${NS2}" link add test_team2 type team 88*d3870724SMarc Harvey 89*d3870724SMarc Harvey # Set up the receiving network namespace's team interface. 90*d3870724SMarc Harvey setup_team "${NS2}" test_team2 roundrobin "${NS2_IP}" \ 91*d3870724SMarc Harvey "${PREFIX_LENGTH}" "${MEMBERS[@]}" 92*d3870724SMarc Harvey} 93*d3870724SMarc Harvey 94*d3870724SMarc Harvey# Set a particular option value for team or team port. 95*d3870724SMarc Harvey# Arguments: 96*d3870724SMarc Harvey# namespace - The namespace name that has the team. 97*d3870724SMarc Harvey# option_name - The option name to set. 98*d3870724SMarc Harvey# option_value - The value to set the option to. 99*d3870724SMarc Harvey# team_name - The name of team to set the option for. 100*d3870724SMarc Harvey# member_name - The (optional) optional name of the member port. 101*d3870724SMarc Harveyset_option_value() 102*d3870724SMarc Harvey{ 103*d3870724SMarc Harvey local namespace="$1" 104*d3870724SMarc Harvey local option_name="$2" 105*d3870724SMarc Harvey local option_value="$3" 106*d3870724SMarc Harvey local team_name="$4" 107*d3870724SMarc Harvey local member_name="$5" 108*d3870724SMarc Harvey local port_flag="--port=${member_name}" 109*d3870724SMarc Harvey 110*d3870724SMarc Harvey ip netns exec "${namespace}" teamnl "${team_name}" setoption \ 111*d3870724SMarc Harvey "${option_name}" "${option_value}" "${port_flag}" 112*d3870724SMarc Harvey return $? 113*d3870724SMarc Harvey} 114*d3870724SMarc Harvey 115*d3870724SMarc Harvey# Send some pings and return the ping command return value. 116*d3870724SMarc Harveytry_ping() 117*d3870724SMarc Harvey{ 118*d3870724SMarc Harvey ip netns exec "${NS1}" ping -i "${PING_INTERVAL}" -c "${PING_COUNT}" \ 119*d3870724SMarc Harvey "${NS2_IP}" -W "${PING_TIMEOUT_S}" 120*d3870724SMarc Harvey} 121*d3870724SMarc Harvey 122*d3870724SMarc Harvey# Checks tcpdump output from net/forwarding lib, and checks if there are any 123*d3870724SMarc Harvey# ICMP(4 or 6) packets. 124*d3870724SMarc Harvey# Arguments: 125*d3870724SMarc Harvey# interface - The interface name to search for. 126*d3870724SMarc Harvey# ip_address - The destination IP address (4 or 6) to search for. 127*d3870724SMarc Harveydid_interface_receive_icmp() 128*d3870724SMarc Harvey{ 129*d3870724SMarc Harvey local interface="$1" 130*d3870724SMarc Harvey local ip_address="$2" 131*d3870724SMarc Harvey local packet_count 132*d3870724SMarc Harvey 133*d3870724SMarc Harvey packet_count=$(tcpdump_show "$interface" | grep -c \ 134*d3870724SMarc Harvey "> ${ip_address}: ICMP") 135*d3870724SMarc Harvey echo "Packet count for ${interface} was ${packet_count}" 136*d3870724SMarc Harvey 137*d3870724SMarc Harvey if [[ "$packet_count" -gt 0 ]]; then 138*d3870724SMarc Harvey true 139*d3870724SMarc Harvey else 140*d3870724SMarc Harvey false 141*d3870724SMarc Harvey fi 142*d3870724SMarc Harvey} 143*d3870724SMarc Harvey 144*d3870724SMarc Harvey# Test JUST tx enablement with a given mode. 145*d3870724SMarc Harvey# Globals: 146*d3870724SMarc Harvey# RET - Used by test infra, set by `check_err` functions. 147*d3870724SMarc Harvey# Arguments: 148*d3870724SMarc Harvey# mode - The mode to set the team interfaces to. 149*d3870724SMarc Harveyteam_test_mode_tx_enablement() 150*d3870724SMarc Harvey{ 151*d3870724SMarc Harvey local mode="$1" 152*d3870724SMarc Harvey export RET=0 153*d3870724SMarc Harvey 154*d3870724SMarc Harvey # Set up the sender team with the correct mode. 155*d3870724SMarc Harvey setup_team "${NS1}" test_team1 "${mode}" "${NS1_IP}" \ 156*d3870724SMarc Harvey "${PREFIX_LENGTH}" "${MEMBERS[@]}" 157*d3870724SMarc Harvey check_err $? "Failed to set up sender team" 158*d3870724SMarc Harvey 159*d3870724SMarc Harvey ### Scenario 1: Member interface initially enabled. 160*d3870724SMarc Harvey # Expect ping to pass 161*d3870724SMarc Harvey try_ping 162*d3870724SMarc Harvey check_err $? "Ping failed when TX enabled" 163*d3870724SMarc Harvey 164*d3870724SMarc Harvey ### Scenario 2: One tx-side interface disabled. 165*d3870724SMarc Harvey # Expect ping to fail. 166*d3870724SMarc Harvey set_option_value "${NS1}" tx_enabled false test_team1 eth0 167*d3870724SMarc Harvey check_err $? "Failed to disable TX" 168*d3870724SMarc Harvey tcpdump_start eth0 "${NS2}" 169*d3870724SMarc Harvey try_ping 170*d3870724SMarc Harvey check_fail $? "Ping succeeded when TX disabled" 171*d3870724SMarc Harvey tcpdump_stop eth0 172*d3870724SMarc Harvey # Expect no packets to be transmitted, since TX is disabled. 173*d3870724SMarc Harvey did_interface_receive_icmp eth0 "${NS2_IP}" 174*d3870724SMarc Harvey check_fail $? "eth0 IS transmitting when TX disabled" 175*d3870724SMarc Harvey tcpdump_cleanup eth0 176*d3870724SMarc Harvey 177*d3870724SMarc Harvey ### Scenario 3: The interface has tx re-enabled. 178*d3870724SMarc Harvey # Expect ping to pass. 179*d3870724SMarc Harvey set_option_value "${NS1}" tx_enabled true test_team1 eth0 180*d3870724SMarc Harvey check_err $? "Failed to reenable TX" 181*d3870724SMarc Harvey try_ping 182*d3870724SMarc Harvey check_err $? "Ping failed when TX reenabled" 183*d3870724SMarc Harvey 184*d3870724SMarc Harvey log_test "TX failover of '${mode}' test" 185*d3870724SMarc Harvey} 186*d3870724SMarc Harvey 187*d3870724SMarc Harvey# Test JUST rx enablement with a given mode. 188*d3870724SMarc Harvey# Globals: 189*d3870724SMarc Harvey# RET - Used by test infra, set by `check_err` functions. 190*d3870724SMarc Harvey# Arguments: 191*d3870724SMarc Harvey# mode - The mode to set the team interfaces to. 192*d3870724SMarc Harveyteam_test_mode_rx_enablement() 193*d3870724SMarc Harvey{ 194*d3870724SMarc Harvey local mode="$1" 195*d3870724SMarc Harvey export RET=0 196*d3870724SMarc Harvey 197*d3870724SMarc Harvey # Set up the sender team with the correct mode. 198*d3870724SMarc Harvey setup_team "${NS1}" test_team1 "${mode}" "${NS1_IP}" \ 199*d3870724SMarc Harvey "${PREFIX_LENGTH}" "${MEMBERS[@]}" 200*d3870724SMarc Harvey check_err $? "Failed to set up sender team" 201*d3870724SMarc Harvey 202*d3870724SMarc Harvey ### Scenario 1: Member interface initially enabled. 203*d3870724SMarc Harvey # Expect ping to pass 204*d3870724SMarc Harvey try_ping 205*d3870724SMarc Harvey check_err $? "Ping failed when RX enabled" 206*d3870724SMarc Harvey 207*d3870724SMarc Harvey ### Scenario 2: One rx-side interface disabled. 208*d3870724SMarc Harvey # Expect ping to fail. 209*d3870724SMarc Harvey set_option_value "${NS1}" rx_enabled false test_team1 eth0 210*d3870724SMarc Harvey check_err $? "Failed to disable RX" 211*d3870724SMarc Harvey tcpdump_start eth0 "${NS2}" 212*d3870724SMarc Harvey try_ping 213*d3870724SMarc Harvey check_fail $? "Ping succeeded when RX disabled" 214*d3870724SMarc Harvey tcpdump_stop eth0 215*d3870724SMarc Harvey # Expect packets to be transmitted, since only RX is disabled. 216*d3870724SMarc Harvey did_interface_receive_icmp eth0 "${NS2_IP}" 217*d3870724SMarc Harvey check_err $? "eth0 not transmitting when RX disabled" 218*d3870724SMarc Harvey tcpdump_cleanup eth0 219*d3870724SMarc Harvey 220*d3870724SMarc Harvey ### Scenario 3: The interface has rx re-enabled. 221*d3870724SMarc Harvey # Expect ping to pass. 222*d3870724SMarc Harvey set_option_value "${NS1}" rx_enabled true test_team1 eth0 223*d3870724SMarc Harvey check_err $? "Failed to reenable RX" 224*d3870724SMarc Harvey try_ping 225*d3870724SMarc Harvey check_err $? "Ping failed when RX reenabled" 226*d3870724SMarc Harvey 227*d3870724SMarc Harvey log_test "RX failover of '${mode}' test" 228*d3870724SMarc Harvey} 229*d3870724SMarc Harvey 230*d3870724SMarc Harveyteam_test_tx_enablement() 231*d3870724SMarc Harvey{ 232*d3870724SMarc Harvey team_test_mode_tx_enablement broadcast 233*d3870724SMarc Harvey team_test_mode_tx_enablement roundrobin 234*d3870724SMarc Harvey team_test_mode_tx_enablement random 235*d3870724SMarc Harvey} 236*d3870724SMarc Harvey 237*d3870724SMarc Harveyteam_test_rx_enablement() 238*d3870724SMarc Harvey{ 239*d3870724SMarc Harvey team_test_mode_rx_enablement broadcast 240*d3870724SMarc Harvey team_test_mode_rx_enablement roundrobin 241*d3870724SMarc Harvey team_test_mode_rx_enablement random 242*d3870724SMarc Harvey} 243*d3870724SMarc Harvey 244*d3870724SMarc Harveyrequire_command teamnl 245*d3870724SMarc Harveyrequire_command tcpdump 246*d3870724SMarc Harveyrequire_command ping 247*d3870724SMarc Harveyenvironment_create 248*d3870724SMarc Harveytests_run 249*d3870724SMarc Harveyexit "${EXIT_STATUS}" 250