173bae673SIdo Schimmel#!/bin/bash 273bae673SIdo Schimmel# SPDX-License-Identifier: GPL-2.0 373bae673SIdo Schimmel 473bae673SIdo Schimmel############################################################################## 573bae673SIdo Schimmel# Defines 673bae673SIdo Schimmel 773bae673SIdo Schimmel# Can be overridden by the configuration file. 873bae673SIdo SchimmelPING=${PING:=ping} 973bae673SIdo SchimmelPING6=${PING6:=ping6} 10d4deb014SIdo SchimmelMZ=${MZ:=mausezahn} 11ca70a562SPetr MachataARPING=${ARPING:=arping} 129d9e6bdeSPetr MachataTEAMD=${TEAMD:=teamd} 1373bae673SIdo SchimmelWAIT_TIME=${WAIT_TIME:=5} 1473bae673SIdo SchimmelPAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} 1573bae673SIdo SchimmelPAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no} 1659be45c3SIdo SchimmelNETIF_TYPE=${NETIF_TYPE:=veth} 1759be45c3SIdo SchimmelNETIF_CREATE=${NETIF_CREATE:=yes} 186d4efadaSNir DotanMCD=${MCD:=smcrouted} 196d4efadaSNir DotanMC_CLI=${MC_CLI:=smcroutectl} 200cd0b1f7SAmit CohenPING_COUNT=${PING_COUNT:=10} 21b6a4fd68SIdo SchimmelPING_TIMEOUT=${PING_TIMEOUT:=5} 228f72a9cfSAmit CohenWAIT_TIMEOUT=${WAIT_TIMEOUT:=20} 238f72a9cfSAmit CohenINTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600} 2408119759STobias WaldekranzLOW_AGEING_TIME=${LOW_AGEING_TIME:=1000} 25d70b51f2SVladimir OlteanREQUIRE_JQ=${REQUIRE_JQ:=yes} 26d70b51f2SVladimir OlteanREQUIRE_MZ=${REQUIRE_MZ:=yes} 27f23cddc7SVladimir OlteanREQUIRE_MTOOLS=${REQUIRE_MTOOLS:=no} 28b343734eSVladimir OlteanSTABLE_MAC_ADDRS=${STABLE_MAC_ADDRS:=no} 29fe32dffdSJoachim WibergTCPDUMP_EXTRA_FLAGS=${TCPDUMP_EXTRA_FLAGS:=} 3038f7c44dSIdo SchimmelTROUTE6=${TROUTE6:=traceroute6} 3173bae673SIdo Schimmel 3287d8fb18SYuval Mintzrelative_path="${BASH_SOURCE%/*}" 3387d8fb18SYuval Mintzif [[ "$relative_path" == "${BASH_SOURCE}" ]]; then 3487d8fb18SYuval Mintz relative_path="." 3587d8fb18SYuval Mintzfi 3687d8fb18SYuval Mintz 3787d8fb18SYuval Mintzif [[ -f $relative_path/forwarding.config ]]; then 3887d8fb18SYuval Mintz source "$relative_path/forwarding.config" 3973bae673SIdo Schimmelfi 4073bae673SIdo Schimmel 41*bb2f3187SBenjamin Poirier# Kselftest framework requirement - SKIP code is 4. 42*bb2f3187SBenjamin Poirierksft_skip=4 43*bb2f3187SBenjamin Poirier 44*bb2f3187SBenjamin Poirierbusywait() 45*bb2f3187SBenjamin Poirier{ 46*bb2f3187SBenjamin Poirier local timeout=$1; shift 47*bb2f3187SBenjamin Poirier 48*bb2f3187SBenjamin Poirier local start_time="$(date -u +%s%3N)" 49*bb2f3187SBenjamin Poirier while true 50*bb2f3187SBenjamin Poirier do 51*bb2f3187SBenjamin Poirier local out 52*bb2f3187SBenjamin Poirier out=$("$@") 53*bb2f3187SBenjamin Poirier local ret=$? 54*bb2f3187SBenjamin Poirier if ((!ret)); then 55*bb2f3187SBenjamin Poirier echo -n "$out" 56*bb2f3187SBenjamin Poirier return 0 57*bb2f3187SBenjamin Poirier fi 58*bb2f3187SBenjamin Poirier 59*bb2f3187SBenjamin Poirier local current_time="$(date -u +%s%3N)" 60*bb2f3187SBenjamin Poirier if ((current_time - start_time > timeout)); then 61*bb2f3187SBenjamin Poirier echo -n "$out" 62*bb2f3187SBenjamin Poirier return 1 63*bb2f3187SBenjamin Poirier fi 64*bb2f3187SBenjamin Poirier done 65*bb2f3187SBenjamin Poirier} 66*bb2f3187SBenjamin Poirier 6773bae673SIdo Schimmel############################################################################## 6873bae673SIdo Schimmel# Sanity checks 6973bae673SIdo Schimmel 70198979beSDavid Aherncheck_tc_version() 71198979beSDavid Ahern{ 72198979beSDavid Ahern tc -j &> /dev/null 73198979beSDavid Ahern if [[ $? -ne 0 ]]; then 74198979beSDavid Ahern echo "SKIP: iproute2 too old; tc is missing JSON support" 757844ec21SPo-Hsu Lin exit $ksft_skip 76198979beSDavid Ahern fi 777f333cbfSJiri Pirko} 78198979beSDavid Ahern 79203ee5cdSGuillaume Nault# Old versions of tc don't understand "mpls_uc" 80203ee5cdSGuillaume Naultcheck_tc_mpls_support() 81203ee5cdSGuillaume Nault{ 82203ee5cdSGuillaume Nault local dev=$1; shift 83203ee5cdSGuillaume Nault 84203ee5cdSGuillaume Nault tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ 85203ee5cdSGuillaume Nault matchall action pipe &> /dev/null 86203ee5cdSGuillaume Nault if [[ $? -ne 0 ]]; then 87203ee5cdSGuillaume Nault echo "SKIP: iproute2 too old; tc is missing MPLS support" 887844ec21SPo-Hsu Lin return $ksft_skip 89203ee5cdSGuillaume Nault fi 90203ee5cdSGuillaume Nault tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ 91203ee5cdSGuillaume Nault matchall 92203ee5cdSGuillaume Nault} 93203ee5cdSGuillaume Nault 94c09bfd9aSGuillaume Nault# Old versions of tc produce invalid json output for mpls lse statistics 95c09bfd9aSGuillaume Naultcheck_tc_mpls_lse_stats() 96c09bfd9aSGuillaume Nault{ 97c09bfd9aSGuillaume Nault local dev=$1; shift 98c09bfd9aSGuillaume Nault local ret; 99c09bfd9aSGuillaume Nault 100c09bfd9aSGuillaume Nault tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ 101c09bfd9aSGuillaume Nault flower mpls lse depth 2 \ 102c09bfd9aSGuillaume Nault action continue &> /dev/null 103c09bfd9aSGuillaume Nault 104c09bfd9aSGuillaume Nault if [[ $? -ne 0 ]]; then 105c09bfd9aSGuillaume Nault echo "SKIP: iproute2 too old; tc-flower is missing extended MPLS support" 1067844ec21SPo-Hsu Lin return $ksft_skip 107c09bfd9aSGuillaume Nault fi 108c09bfd9aSGuillaume Nault 109c09bfd9aSGuillaume Nault tc -j filter show dev $dev ingress protocol mpls_uc | jq . &> /dev/null 110c09bfd9aSGuillaume Nault ret=$? 111c09bfd9aSGuillaume Nault tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ 112c09bfd9aSGuillaume Nault flower 113c09bfd9aSGuillaume Nault 114c09bfd9aSGuillaume Nault if [[ $ret -ne 0 ]]; then 115c09bfd9aSGuillaume Nault echo "SKIP: iproute2 too old; tc-flower produces invalid json output for extended MPLS filters" 1167844ec21SPo-Hsu Lin return $ksft_skip 117c09bfd9aSGuillaume Nault fi 118c09bfd9aSGuillaume Nault} 119c09bfd9aSGuillaume Nault 1207f333cbfSJiri Pirkocheck_tc_shblock_support() 1217f333cbfSJiri Pirko{ 122198979beSDavid Ahern tc filter help 2>&1 | grep block &> /dev/null 123198979beSDavid Ahern if [[ $? -ne 0 ]]; then 124198979beSDavid Ahern echo "SKIP: iproute2 too old; tc is missing shared block support" 1257844ec21SPo-Hsu Lin exit $ksft_skip 126198979beSDavid Ahern fi 127198979beSDavid Ahern} 128198979beSDavid Ahern 1292d73c887SJiri Pirkocheck_tc_chain_support() 1302d73c887SJiri Pirko{ 1312d73c887SJiri Pirko tc help 2>&1|grep chain &> /dev/null 1322d73c887SJiri Pirko if [[ $? -ne 0 ]]; then 1332d73c887SJiri Pirko echo "SKIP: iproute2 too old; tc is missing chain support" 1347844ec21SPo-Hsu Lin exit $ksft_skip 1352d73c887SJiri Pirko fi 1362d73c887SJiri Pirko} 1372d73c887SJiri Pirko 138ee4848acSJiri Pirkocheck_tc_action_hw_stats_support() 139ee4848acSJiri Pirko{ 140ee4848acSJiri Pirko tc actions help 2>&1 | grep -q hw_stats 141ee4848acSJiri Pirko if [[ $? -ne 0 ]]; then 142ee4848acSJiri Pirko echo "SKIP: iproute2 too old; tc is missing action hw_stats support" 1437844ec21SPo-Hsu Lin exit $ksft_skip 144ee4848acSJiri Pirko fi 145ee4848acSJiri Pirko} 146ee4848acSJiri Pirko 147e6991384SVladimir Olteancheck_tc_fp_support() 148e6991384SVladimir Oltean{ 149e6991384SVladimir Oltean tc qdisc add dev lo mqprio help 2>&1 | grep -q "fp " 150e6991384SVladimir Oltean if [[ $? -ne 0 ]]; then 151e6991384SVladimir Oltean echo "SKIP: iproute2 too old; tc is missing frame preemption support" 152e6991384SVladimir Oltean exit $ksft_skip 153e6991384SVladimir Oltean fi 154e6991384SVladimir Oltean} 155e6991384SVladimir Oltean 156f72e2f48SDanielle Ratsoncheck_ethtool_lanes_support() 157f72e2f48SDanielle Ratson{ 158f72e2f48SDanielle Ratson ethtool --help 2>&1| grep lanes &> /dev/null 159f72e2f48SDanielle Ratson if [[ $? -ne 0 ]]; then 160f72e2f48SDanielle Ratson echo "SKIP: ethtool too old; it is missing lanes support" 1617844ec21SPo-Hsu Lin exit $ksft_skip 162f72e2f48SDanielle Ratson fi 163f72e2f48SDanielle Ratson} 164f72e2f48SDanielle Ratson 165e6991384SVladimir Olteancheck_ethtool_mm_support() 166e6991384SVladimir Oltean{ 167e6991384SVladimir Oltean ethtool --help 2>&1| grep -- '--show-mm' &> /dev/null 168e6991384SVladimir Oltean if [[ $? -ne 0 ]]; then 169e6991384SVladimir Oltean echo "SKIP: ethtool too old; it is missing MAC Merge layer support" 170e6991384SVladimir Oltean exit $ksft_skip 171e6991384SVladimir Oltean fi 172e6991384SVladimir Oltean} 173e6991384SVladimir Oltean 174b2b681a4SHans Schultzcheck_locked_port_support() 175b2b681a4SHans Schultz{ 176b2b681a4SHans Schultz if ! bridge -d link show | grep -q " locked"; then 177b2b681a4SHans Schultz echo "SKIP: iproute2 too old; Locked port feature not supported." 178b2b681a4SHans Schultz return $ksft_skip 179b2b681a4SHans Schultz fi 180b2b681a4SHans Schultz} 181b2b681a4SHans Schultz 1824a331d34SHans J. Schultzcheck_port_mab_support() 1834a331d34SHans J. Schultz{ 1844a331d34SHans J. Schultz if ! bridge -d link show | grep -q "mab"; then 1854a331d34SHans J. Schultz echo "SKIP: iproute2 too old; MacAuth feature not supported." 1864a331d34SHans J. Schultz return $ksft_skip 1874a331d34SHans J. Schultz fi 1884a331d34SHans J. Schultz} 1894a331d34SHans J. Schultz 19066e13186SIdo Schimmelskip_on_veth() 19166e13186SIdo Schimmel{ 19266e13186SIdo Schimmel local kind=$(ip -j -d link show dev ${NETIFS[p1]} | 19366e13186SIdo Schimmel jq -r '.[].linkinfo.info_kind') 19466e13186SIdo Schimmel 19566e13186SIdo Schimmel if [[ $kind == veth ]]; then 19666e13186SIdo Schimmel echo "SKIP: Test cannot be run with veth pairs" 19766e13186SIdo Schimmel exit $ksft_skip 19866e13186SIdo Schimmel fi 19966e13186SIdo Schimmel} 20066e13186SIdo Schimmel 20173bae673SIdo Schimmelif [[ "$(id -u)" -ne 0 ]]; then 20273bae673SIdo Schimmel echo "SKIP: need root privileges" 2037844ec21SPo-Hsu Lin exit $ksft_skip 20473bae673SIdo Schimmelfi 20573bae673SIdo Schimmel 206198979beSDavid Ahernif [[ "$CHECK_TC" = "yes" ]]; then 207198979beSDavid Ahern check_tc_version 2084908e24bSJiri Pirkofi 2094908e24bSJiri Pirko 210e094574fSPetr Machatarequire_command() 211e094574fSPetr Machata{ 212e094574fSPetr Machata local cmd=$1; shift 21373bae673SIdo Schimmel 214e094574fSPetr Machata if [[ ! -x "$(command -v "$cmd")" ]]; then 215e094574fSPetr Machata echo "SKIP: $cmd not installed" 2167844ec21SPo-Hsu Lin exit $ksft_skip 217d4deb014SIdo Schimmel fi 218e094574fSPetr Machata} 219e094574fSPetr Machata 220d70b51f2SVladimir Olteanif [[ "$REQUIRE_JQ" = "yes" ]]; then 221e094574fSPetr Machata require_command jq 222d70b51f2SVladimir Olteanfi 223d70b51f2SVladimir Olteanif [[ "$REQUIRE_MZ" = "yes" ]]; then 224e094574fSPetr Machata require_command $MZ 225d70b51f2SVladimir Olteanfi 226f23cddc7SVladimir Olteanif [[ "$REQUIRE_MTOOLS" = "yes" ]]; then 227f23cddc7SVladimir Oltean # https://github.com/vladimiroltean/mtools/ 228f23cddc7SVladimir Oltean # patched for IPv6 support 229f23cddc7SVladimir Oltean require_command msend 230f23cddc7SVladimir Oltean require_command mreceive 231f23cddc7SVladimir Olteanfi 232d4deb014SIdo Schimmel 23373bae673SIdo Schimmelif [[ ! -v NUM_NETIFS ]]; then 23473bae673SIdo Schimmel echo "SKIP: importer does not define \"NUM_NETIFS\"" 2357844ec21SPo-Hsu Lin exit $ksft_skip 23673bae673SIdo Schimmelfi 23773bae673SIdo Schimmel 23873bae673SIdo Schimmel############################################################################## 239781fe631SJiri Pirko# Command line options handling 240781fe631SJiri Pirko 241781fe631SJiri Pirkocount=0 242781fe631SJiri Pirko 243781fe631SJiri Pirkowhile [[ $# -gt 0 ]]; do 244781fe631SJiri Pirko if [[ "$count" -eq "0" ]]; then 245781fe631SJiri Pirko unset NETIFS 246781fe631SJiri Pirko declare -A NETIFS 247781fe631SJiri Pirko fi 248781fe631SJiri Pirko count=$((count + 1)) 249781fe631SJiri Pirko NETIFS[p$count]="$1" 250781fe631SJiri Pirko shift 251781fe631SJiri Pirkodone 252781fe631SJiri Pirko 253781fe631SJiri Pirko############################################################################## 25473bae673SIdo Schimmel# Network interfaces configuration 25573bae673SIdo Schimmel 256190f887cSDavid Aherncreate_netif_veth() 257190f887cSDavid Ahern{ 258190f887cSDavid Ahern local i 259190f887cSDavid Ahern 260601bc1c1SPetr Machata for ((i = 1; i <= NUM_NETIFS; ++i)); do 261190f887cSDavid Ahern local j=$((i+1)) 262190f887cSDavid Ahern 263d72c83b1SIdo Schimmel if [ -z ${NETIFS[p$i]} ]; then 264d72c83b1SIdo Schimmel echo "SKIP: Cannot create interface. Name not specified" 265d72c83b1SIdo Schimmel exit $ksft_skip 266d72c83b1SIdo Schimmel fi 267d72c83b1SIdo Schimmel 268190f887cSDavid Ahern ip link show dev ${NETIFS[p$i]} &> /dev/null 269190f887cSDavid Ahern if [[ $? -ne 0 ]]; then 270190f887cSDavid Ahern ip link add ${NETIFS[p$i]} type veth \ 271190f887cSDavid Ahern peer name ${NETIFS[p$j]} 272190f887cSDavid Ahern if [[ $? -ne 0 ]]; then 273190f887cSDavid Ahern echo "Failed to create netif" 274190f887cSDavid Ahern exit 1 275190f887cSDavid Ahern fi 276190f887cSDavid Ahern fi 277190f887cSDavid Ahern i=$j 278190f887cSDavid Ahern done 279190f887cSDavid Ahern} 280190f887cSDavid Ahern 281190f887cSDavid Aherncreate_netif() 282190f887cSDavid Ahern{ 283190f887cSDavid Ahern case "$NETIF_TYPE" in 284190f887cSDavid Ahern veth) create_netif_veth 285190f887cSDavid Ahern ;; 286190f887cSDavid Ahern *) echo "Can not create interfaces of type \'$NETIF_TYPE\'" 287190f887cSDavid Ahern exit 1 288190f887cSDavid Ahern ;; 289190f887cSDavid Ahern esac 290190f887cSDavid Ahern} 291190f887cSDavid Ahern 292b343734eSVladimir Olteandeclare -A MAC_ADDR_ORIG 293b343734eSVladimir Olteanmac_addr_prepare() 294b343734eSVladimir Oltean{ 295b343734eSVladimir Oltean local new_addr= 296b343734eSVladimir Oltean local dev= 297b343734eSVladimir Oltean 298b343734eSVladimir Oltean for ((i = 1; i <= NUM_NETIFS; ++i)); do 299b343734eSVladimir Oltean dev=${NETIFS[p$i]} 300b343734eSVladimir Oltean new_addr=$(printf "00:01:02:03:04:%02x" $i) 301b343734eSVladimir Oltean 302b343734eSVladimir Oltean MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address') 303b343734eSVladimir Oltean # Strip quotes 304b343734eSVladimir Oltean MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/} 305b343734eSVladimir Oltean ip link set dev $dev address $new_addr 306b343734eSVladimir Oltean done 307b343734eSVladimir Oltean} 308b343734eSVladimir Oltean 309b343734eSVladimir Olteanmac_addr_restore() 310b343734eSVladimir Oltean{ 311b343734eSVladimir Oltean local dev= 312b343734eSVladimir Oltean 313b343734eSVladimir Oltean for ((i = 1; i <= NUM_NETIFS; ++i)); do 314b343734eSVladimir Oltean dev=${NETIFS[p$i]} 315b343734eSVladimir Oltean ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]} 316b343734eSVladimir Oltean done 317b343734eSVladimir Oltean} 318b343734eSVladimir Oltean 319190f887cSDavid Ahernif [[ "$NETIF_CREATE" = "yes" ]]; then 320190f887cSDavid Ahern create_netif 321190f887cSDavid Ahernfi 322190f887cSDavid Ahern 323b343734eSVladimir Olteanif [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then 324b343734eSVladimir Oltean mac_addr_prepare 325b343734eSVladimir Olteanfi 326b343734eSVladimir Oltean 327601bc1c1SPetr Machatafor ((i = 1; i <= NUM_NETIFS; ++i)); do 32873bae673SIdo Schimmel ip link show dev ${NETIFS[p$i]} &> /dev/null 32973bae673SIdo Schimmel if [[ $? -ne 0 ]]; then 33073bae673SIdo Schimmel echo "SKIP: could not find all required interfaces" 3317844ec21SPo-Hsu Lin exit $ksft_skip 33273bae673SIdo Schimmel fi 33373bae673SIdo Schimmeldone 33473bae673SIdo Schimmel 33573bae673SIdo Schimmel############################################################################## 33673bae673SIdo Schimmel# Helpers 33773bae673SIdo Schimmel 33873bae673SIdo Schimmel# Exit status to return at the end. Set in case one of the tests fails. 33973bae673SIdo SchimmelEXIT_STATUS=0 34073bae673SIdo Schimmel# Per-test return value. Clear at the beginning of each test. 34173bae673SIdo SchimmelRET=0 34273bae673SIdo Schimmel 34373bae673SIdo Schimmelcheck_err() 34473bae673SIdo Schimmel{ 34573bae673SIdo Schimmel local err=$1 34673bae673SIdo Schimmel local msg=$2 34773bae673SIdo Schimmel 34873bae673SIdo Schimmel if [[ $RET -eq 0 && $err -ne 0 ]]; then 34973bae673SIdo Schimmel RET=$err 35073bae673SIdo Schimmel retmsg=$msg 35173bae673SIdo Schimmel fi 35273bae673SIdo Schimmel} 35373bae673SIdo Schimmel 35473bae673SIdo Schimmelcheck_fail() 35573bae673SIdo Schimmel{ 35673bae673SIdo Schimmel local err=$1 35773bae673SIdo Schimmel local msg=$2 35873bae673SIdo Schimmel 35973bae673SIdo Schimmel if [[ $RET -eq 0 && $err -eq 0 ]]; then 36073bae673SIdo Schimmel RET=1 36173bae673SIdo Schimmel retmsg=$msg 36273bae673SIdo Schimmel fi 36373bae673SIdo Schimmel} 36473bae673SIdo Schimmel 36596fa91d2SPetr Machatacheck_err_fail() 36696fa91d2SPetr Machata{ 36796fa91d2SPetr Machata local should_fail=$1; shift 36896fa91d2SPetr Machata local err=$1; shift 36996fa91d2SPetr Machata local what=$1; shift 37096fa91d2SPetr Machata 37196fa91d2SPetr Machata if ((should_fail)); then 37296fa91d2SPetr Machata check_fail $err "$what succeeded, but should have failed" 37396fa91d2SPetr Machata else 37496fa91d2SPetr Machata check_err $err "$what failed" 37596fa91d2SPetr Machata fi 37696fa91d2SPetr Machata} 37796fa91d2SPetr Machata 37873bae673SIdo Schimmellog_test() 37973bae673SIdo Schimmel{ 38073bae673SIdo Schimmel local test_name=$1 38173bae673SIdo Schimmel local opt_str=$2 38273bae673SIdo Schimmel 38373bae673SIdo Schimmel if [[ $# -eq 2 ]]; then 38473bae673SIdo Schimmel opt_str="($opt_str)" 38573bae673SIdo Schimmel fi 38673bae673SIdo Schimmel 38773bae673SIdo Schimmel if [[ $RET -ne 0 ]]; then 38873bae673SIdo Schimmel EXIT_STATUS=1 38973bae673SIdo Schimmel printf "TEST: %-60s [FAIL]\n" "$test_name $opt_str" 39073bae673SIdo Schimmel if [[ ! -z "$retmsg" ]]; then 39173bae673SIdo Schimmel printf "\t%s\n" "$retmsg" 39273bae673SIdo Schimmel fi 39373bae673SIdo Schimmel if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 39473bae673SIdo Schimmel echo "Hit enter to continue, 'q' to quit" 39573bae673SIdo Schimmel read a 39673bae673SIdo Schimmel [ "$a" = "q" ] && exit 1 39773bae673SIdo Schimmel fi 39873bae673SIdo Schimmel return 1 39973bae673SIdo Schimmel fi 40073bae673SIdo Schimmel 4013cab0de9SIdo Schimmel printf "TEST: %-60s [ OK ]\n" "$test_name $opt_str" 40273bae673SIdo Schimmel return 0 40373bae673SIdo Schimmel} 40473bae673SIdo Schimmel 405b8bfafe4SPetr Machatalog_test_skip() 406b8bfafe4SPetr Machata{ 407b8bfafe4SPetr Machata local test_name=$1 408b8bfafe4SPetr Machata local opt_str=$2 409b8bfafe4SPetr Machata 410b8bfafe4SPetr Machata printf "TEST: %-60s [SKIP]\n" "$test_name $opt_str" 411b8bfafe4SPetr Machata return 0 412b8bfafe4SPetr Machata} 413b8bfafe4SPetr Machata 4143d578d87SIdo Schimmellog_info() 4153d578d87SIdo Schimmel{ 4163d578d87SIdo Schimmel local msg=$1 4173d578d87SIdo Schimmel 4183d578d87SIdo Schimmel echo "INFO: $msg" 4193d578d87SIdo Schimmel} 4203d578d87SIdo Schimmel 42105ef614cSDanielle Ratsonnot() 42205ef614cSDanielle Ratson{ 42305ef614cSDanielle Ratson "$@" 42405ef614cSDanielle Ratson [[ $? != 0 ]] 42505ef614cSDanielle Ratson} 42605ef614cSDanielle Ratson 427f72e2f48SDanielle Ratsonget_max() 428f72e2f48SDanielle Ratson{ 429f72e2f48SDanielle Ratson local arr=("$@") 430f72e2f48SDanielle Ratson 431f72e2f48SDanielle Ratson max=${arr[0]} 432f72e2f48SDanielle Ratson for cur in ${arr[@]}; do 433f72e2f48SDanielle Ratson if [[ $cur -gt $max ]]; then 434f72e2f48SDanielle Ratson max=$cur 435f72e2f48SDanielle Ratson fi 436f72e2f48SDanielle Ratson done 437f72e2f48SDanielle Ratson 438f72e2f48SDanielle Ratson echo $max 439f72e2f48SDanielle Ratson} 440f72e2f48SDanielle Ratson 44105ef614cSDanielle Ratsongrep_bridge_fdb() 44205ef614cSDanielle Ratson{ 44305ef614cSDanielle Ratson local addr=$1; shift 44405ef614cSDanielle Ratson local word 44505ef614cSDanielle Ratson local flag 44605ef614cSDanielle Ratson 44705ef614cSDanielle Ratson if [ "$1" == "self" ] || [ "$1" == "master" ]; then 44805ef614cSDanielle Ratson word=$1; shift 44905ef614cSDanielle Ratson if [ "$1" == "-v" ]; then 45005ef614cSDanielle Ratson flag=$1; shift 45105ef614cSDanielle Ratson fi 45205ef614cSDanielle Ratson fi 45305ef614cSDanielle Ratson 45405ef614cSDanielle Ratson $@ | grep $addr | grep $flag "$word" 45505ef614cSDanielle Ratson} 45605ef614cSDanielle Ratson 457f72e2f48SDanielle Ratsonwait_for_port_up() 458f72e2f48SDanielle Ratson{ 459f72e2f48SDanielle Ratson "$@" | grep -q "Link detected: yes" 460f72e2f48SDanielle Ratson} 461f72e2f48SDanielle Ratson 4620c22f993SDanielle Ratsonwait_for_offload() 4630c22f993SDanielle Ratson{ 4640c22f993SDanielle Ratson "$@" | grep -q offload 4650c22f993SDanielle Ratson} 4660c22f993SDanielle Ratson 467ffd3e9b0SIdo Schimmelwait_for_trap() 468ffd3e9b0SIdo Schimmel{ 469ffd3e9b0SIdo Schimmel "$@" | grep -q trap 470ffd3e9b0SIdo Schimmel} 471ffd3e9b0SIdo Schimmel 4724121d947SPetr Machatauntil_counter_is() 4734121d947SPetr Machata{ 474844f0556SPetr Machata local expr=$1; shift 4754121d947SPetr Machata local current=$("$@") 4764121d947SPetr Machata 4774121d947SPetr Machata echo $((current)) 478844f0556SPetr Machata ((current $expr)) 4794121d947SPetr Machata} 4804121d947SPetr Machata 4814121d947SPetr Machatabusywait_for_counter() 4824121d947SPetr Machata{ 4834121d947SPetr Machata local timeout=$1; shift 4844121d947SPetr Machata local delta=$1; shift 4854121d947SPetr Machata 4864121d947SPetr Machata local base=$("$@") 487844f0556SPetr Machata busywait "$timeout" until_counter_is ">= $((base + delta))" "$@" 4884121d947SPetr Machata} 4894121d947SPetr Machata 490010079baSPetr Machatasetup_wait_dev() 49173bae673SIdo Schimmel{ 492010079baSPetr Machata local dev=$1; shift 4938f72a9cfSAmit Cohen local wait_time=${1:-$WAIT_TIME}; shift 494010079baSPetr Machata 4958f72a9cfSAmit Cohen setup_wait_dev_with_timeout "$dev" $INTERFACE_TIMEOUT $wait_time 4968f72a9cfSAmit Cohen 4978f72a9cfSAmit Cohen if (($?)); then 4988f72a9cfSAmit Cohen check_err 1 4998f72a9cfSAmit Cohen log_test setup_wait_dev ": Interface $dev does not come up." 5008f72a9cfSAmit Cohen exit 1 5018f72a9cfSAmit Cohen fi 5028f72a9cfSAmit Cohen} 5038f72a9cfSAmit Cohen 5048f72a9cfSAmit Cohensetup_wait_dev_with_timeout() 5058f72a9cfSAmit Cohen{ 5068f72a9cfSAmit Cohen local dev=$1; shift 5078f72a9cfSAmit Cohen local max_iterations=${1:-$WAIT_TIMEOUT}; shift 5088f72a9cfSAmit Cohen local wait_time=${1:-$WAIT_TIME}; shift 5098f72a9cfSAmit Cohen local i 5108f72a9cfSAmit Cohen 5118f72a9cfSAmit Cohen for ((i = 1; i <= $max_iterations; ++i)); do 512010079baSPetr Machata ip link show dev $dev up \ 51373bae673SIdo Schimmel | grep 'state UP' &> /dev/null 51473bae673SIdo Schimmel if [[ $? -ne 0 ]]; then 51573bae673SIdo Schimmel sleep 1 51673bae673SIdo Schimmel else 5178f72a9cfSAmit Cohen sleep $wait_time 5188f72a9cfSAmit Cohen return 0 51973bae673SIdo Schimmel fi 52073bae673SIdo Schimmel done 5218f72a9cfSAmit Cohen 5228f72a9cfSAmit Cohen return 1 523010079baSPetr Machata} 524010079baSPetr Machata 525010079baSPetr Machatasetup_wait() 526010079baSPetr Machata{ 52768d9cea5SPetr Machata local num_netifs=${1:-$NUM_NETIFS} 5288f72a9cfSAmit Cohen local i 52968d9cea5SPetr Machata 53068d9cea5SPetr Machata for ((i = 1; i <= num_netifs; ++i)); do 5318f72a9cfSAmit Cohen setup_wait_dev ${NETIFS[p$i]} 0 53273bae673SIdo Schimmel done 53373bae673SIdo Schimmel 53473bae673SIdo Schimmel # Make sure links are ready. 53573bae673SIdo Schimmel sleep $WAIT_TIME 53673bae673SIdo Schimmel} 53773bae673SIdo Schimmel 538d87e5edbSJiri Pirkocmd_jq() 539d87e5edbSJiri Pirko{ 540d87e5edbSJiri Pirko local cmd=$1 541d87e5edbSJiri Pirko local jq_exp=$2 542c04d71b5SJiri Pirko local jq_opts=$3 543d87e5edbSJiri Pirko local ret 544d87e5edbSJiri Pirko local output 545d87e5edbSJiri Pirko 546d87e5edbSJiri Pirko output="$($cmd)" 547d87e5edbSJiri Pirko # it the command fails, return error right away 548d87e5edbSJiri Pirko ret=$? 549d87e5edbSJiri Pirko if [[ $ret -ne 0 ]]; then 550d87e5edbSJiri Pirko return $ret 551d87e5edbSJiri Pirko fi 552c04d71b5SJiri Pirko output=$(echo $output | jq -r $jq_opts "$jq_exp") 553c04d71b5SJiri Pirko ret=$? 554c04d71b5SJiri Pirko if [[ $ret -ne 0 ]]; then 555c04d71b5SJiri Pirko return $ret 556c04d71b5SJiri Pirko fi 557d87e5edbSJiri Pirko echo $output 558d87e5edbSJiri Pirko # return success only in case of non-empty output 559d87e5edbSJiri Pirko [ ! -z "$output" ] 560d87e5edbSJiri Pirko} 561d87e5edbSJiri Pirko 56273bae673SIdo Schimmelpre_cleanup() 56373bae673SIdo Schimmel{ 56473bae673SIdo Schimmel if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then 56573bae673SIdo Schimmel echo "Pausing before cleanup, hit any key to continue" 56673bae673SIdo Schimmel read 56773bae673SIdo Schimmel fi 568b343734eSVladimir Oltean 569b343734eSVladimir Oltean if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then 570b343734eSVladimir Oltean mac_addr_restore 571b343734eSVladimir Oltean fi 57273bae673SIdo Schimmel} 57373bae673SIdo Schimmel 57473bae673SIdo Schimmelvrf_prepare() 57573bae673SIdo Schimmel{ 57673bae673SIdo Schimmel ip -4 rule add pref 32765 table local 57773bae673SIdo Schimmel ip -4 rule del pref 0 57873bae673SIdo Schimmel ip -6 rule add pref 32765 table local 57973bae673SIdo Schimmel ip -6 rule del pref 0 58073bae673SIdo Schimmel} 58173bae673SIdo Schimmel 58273bae673SIdo Schimmelvrf_cleanup() 58373bae673SIdo Schimmel{ 58473bae673SIdo Schimmel ip -6 rule add pref 0 table local 58573bae673SIdo Schimmel ip -6 rule del pref 32765 58673bae673SIdo Schimmel ip -4 rule add pref 0 table local 58773bae673SIdo Schimmel ip -4 rule del pref 32765 58873bae673SIdo Schimmel} 58973bae673SIdo Schimmel 59073bae673SIdo Schimmel__last_tb_id=0 59173bae673SIdo Schimmeldeclare -A __TB_IDS 59273bae673SIdo Schimmel 59373bae673SIdo Schimmel__vrf_td_id_assign() 59473bae673SIdo Schimmel{ 59573bae673SIdo Schimmel local vrf_name=$1 59673bae673SIdo Schimmel 59773bae673SIdo Schimmel __last_tb_id=$((__last_tb_id + 1)) 59873bae673SIdo Schimmel __TB_IDS[$vrf_name]=$__last_tb_id 59973bae673SIdo Schimmel return $__last_tb_id 60073bae673SIdo Schimmel} 60173bae673SIdo Schimmel 60273bae673SIdo Schimmel__vrf_td_id_lookup() 60373bae673SIdo Schimmel{ 60473bae673SIdo Schimmel local vrf_name=$1 60573bae673SIdo Schimmel 60673bae673SIdo Schimmel return ${__TB_IDS[$vrf_name]} 60773bae673SIdo Schimmel} 60873bae673SIdo Schimmel 60973bae673SIdo Schimmelvrf_create() 61073bae673SIdo Schimmel{ 61173bae673SIdo Schimmel local vrf_name=$1 61273bae673SIdo Schimmel local tb_id 61373bae673SIdo Schimmel 61473bae673SIdo Schimmel __vrf_td_id_assign $vrf_name 61573bae673SIdo Schimmel tb_id=$? 61673bae673SIdo Schimmel 61773bae673SIdo Schimmel ip link add dev $vrf_name type vrf table $tb_id 61873bae673SIdo Schimmel ip -4 route add table $tb_id unreachable default metric 4278198272 61973bae673SIdo Schimmel ip -6 route add table $tb_id unreachable default metric 4278198272 62073bae673SIdo Schimmel} 62173bae673SIdo Schimmel 62273bae673SIdo Schimmelvrf_destroy() 62373bae673SIdo Schimmel{ 62473bae673SIdo Schimmel local vrf_name=$1 62573bae673SIdo Schimmel local tb_id 62673bae673SIdo Schimmel 62773bae673SIdo Schimmel __vrf_td_id_lookup $vrf_name 62873bae673SIdo Schimmel tb_id=$? 62973bae673SIdo Schimmel 63073bae673SIdo Schimmel ip -6 route del table $tb_id unreachable default metric 4278198272 63173bae673SIdo Schimmel ip -4 route del table $tb_id unreachable default metric 4278198272 63273bae673SIdo Schimmel ip link del dev $vrf_name 63373bae673SIdo Schimmel} 63473bae673SIdo Schimmel 63573bae673SIdo Schimmel__addr_add_del() 63673bae673SIdo Schimmel{ 63773bae673SIdo Schimmel local if_name=$1 63873bae673SIdo Schimmel local add_del=$2 63973bae673SIdo Schimmel local array 64073bae673SIdo Schimmel 64173bae673SIdo Schimmel shift 64273bae673SIdo Schimmel shift 64373bae673SIdo Schimmel array=("${@}") 64473bae673SIdo Schimmel 64573bae673SIdo Schimmel for addrstr in "${array[@]}"; do 64673bae673SIdo Schimmel ip address $add_del $addrstr dev $if_name 64773bae673SIdo Schimmel done 64873bae673SIdo Schimmel} 64973bae673SIdo Schimmel 6503368b223SPetr Machata__simple_if_init() 6513368b223SPetr Machata{ 6523368b223SPetr Machata local if_name=$1; shift 6533368b223SPetr Machata local vrf_name=$1; shift 6543368b223SPetr Machata local addrs=("${@}") 6553368b223SPetr Machata 6563368b223SPetr Machata ip link set dev $if_name master $vrf_name 6573368b223SPetr Machata ip link set dev $if_name up 6583368b223SPetr Machata 6593368b223SPetr Machata __addr_add_del $if_name add "${addrs[@]}" 6603368b223SPetr Machata} 6613368b223SPetr Machata 6623368b223SPetr Machata__simple_if_fini() 6633368b223SPetr Machata{ 6643368b223SPetr Machata local if_name=$1; shift 6653368b223SPetr Machata local addrs=("${@}") 6663368b223SPetr Machata 6673368b223SPetr Machata __addr_add_del $if_name del "${addrs[@]}" 6683368b223SPetr Machata 6693368b223SPetr Machata ip link set dev $if_name down 6703368b223SPetr Machata ip link set dev $if_name nomaster 6713368b223SPetr Machata} 6723368b223SPetr Machata 67373bae673SIdo Schimmelsimple_if_init() 67473bae673SIdo Schimmel{ 67573bae673SIdo Schimmel local if_name=$1 67673bae673SIdo Schimmel local vrf_name 67773bae673SIdo Schimmel local array 67873bae673SIdo Schimmel 67973bae673SIdo Schimmel shift 68073bae673SIdo Schimmel vrf_name=v$if_name 68173bae673SIdo Schimmel array=("${@}") 68273bae673SIdo Schimmel 68373bae673SIdo Schimmel vrf_create $vrf_name 68473bae673SIdo Schimmel ip link set dev $vrf_name up 6853368b223SPetr Machata __simple_if_init $if_name $vrf_name "${array[@]}" 68673bae673SIdo Schimmel} 68773bae673SIdo Schimmel 68873bae673SIdo Schimmelsimple_if_fini() 68973bae673SIdo Schimmel{ 69073bae673SIdo Schimmel local if_name=$1 69173bae673SIdo Schimmel local vrf_name 69273bae673SIdo Schimmel local array 69373bae673SIdo Schimmel 69473bae673SIdo Schimmel shift 69573bae673SIdo Schimmel vrf_name=v$if_name 69673bae673SIdo Schimmel array=("${@}") 69773bae673SIdo Schimmel 6983368b223SPetr Machata __simple_if_fini $if_name "${array[@]}" 69973bae673SIdo Schimmel vrf_destroy $vrf_name 70073bae673SIdo Schimmel} 70173bae673SIdo Schimmel 7027d4cbae0SPetr Machatatunnel_create() 7037d4cbae0SPetr Machata{ 7047d4cbae0SPetr Machata local name=$1; shift 7057d4cbae0SPetr Machata local type=$1; shift 7067d4cbae0SPetr Machata local local=$1; shift 7077d4cbae0SPetr Machata local remote=$1; shift 7087d4cbae0SPetr Machata 7097d4cbae0SPetr Machata ip link add name $name type $type \ 7107d4cbae0SPetr Machata local $local remote $remote "$@" 7117d4cbae0SPetr Machata ip link set dev $name up 7127d4cbae0SPetr Machata} 7137d4cbae0SPetr Machata 7147d4cbae0SPetr Machatatunnel_destroy() 7157d4cbae0SPetr Machata{ 7167d4cbae0SPetr Machata local name=$1; shift 7177d4cbae0SPetr Machata 7187d4cbae0SPetr Machata ip link del dev $name 7197d4cbae0SPetr Machata} 7207d4cbae0SPetr Machata 7210e7a504cSPetr Machatavlan_create() 7220e7a504cSPetr Machata{ 7230e7a504cSPetr Machata local if_name=$1; shift 7240e7a504cSPetr Machata local vid=$1; shift 7250e7a504cSPetr Machata local vrf=$1; shift 7260e7a504cSPetr Machata local ips=("${@}") 7270e7a504cSPetr Machata local name=$if_name.$vid 7280e7a504cSPetr Machata 7290e7a504cSPetr Machata ip link add name $name link $if_name type vlan id $vid 7300e7a504cSPetr Machata if [ "$vrf" != "" ]; then 7310e7a504cSPetr Machata ip link set dev $name master $vrf 7320e7a504cSPetr Machata fi 7330e7a504cSPetr Machata ip link set dev $name up 7340e7a504cSPetr Machata __addr_add_del $name add "${ips[@]}" 7350e7a504cSPetr Machata} 7360e7a504cSPetr Machata 7370e7a504cSPetr Machatavlan_destroy() 7380e7a504cSPetr Machata{ 7390e7a504cSPetr Machata local if_name=$1; shift 7400e7a504cSPetr Machata local vid=$1; shift 7410e7a504cSPetr Machata local name=$if_name.$vid 7420e7a504cSPetr Machata 7430e7a504cSPetr Machata ip link del dev $name 7440e7a504cSPetr Machata} 7450e7a504cSPetr Machata 7469d9e6bdeSPetr Machatateam_create() 7479d9e6bdeSPetr Machata{ 7489d9e6bdeSPetr Machata local if_name=$1; shift 7499d9e6bdeSPetr Machata local mode=$1; shift 7509d9e6bdeSPetr Machata 7519d9e6bdeSPetr Machata require_command $TEAMD 7529d9e6bdeSPetr Machata $TEAMD -t $if_name -d -c '{"runner": {"name": "'$mode'"}}' 7539d9e6bdeSPetr Machata for slave in "$@"; do 7549d9e6bdeSPetr Machata ip link set dev $slave down 7559d9e6bdeSPetr Machata ip link set dev $slave master $if_name 7569d9e6bdeSPetr Machata ip link set dev $slave up 7579d9e6bdeSPetr Machata done 7589d9e6bdeSPetr Machata ip link set dev $if_name up 7599d9e6bdeSPetr Machata} 7609d9e6bdeSPetr Machata 7619d9e6bdeSPetr Machatateam_destroy() 7629d9e6bdeSPetr Machata{ 7639d9e6bdeSPetr Machata local if_name=$1; shift 7649d9e6bdeSPetr Machata 7659d9e6bdeSPetr Machata $TEAMD -t $if_name -k 7669d9e6bdeSPetr Machata} 7679d9e6bdeSPetr Machata 76873bae673SIdo Schimmelmaster_name_get() 76973bae673SIdo Schimmel{ 77073bae673SIdo Schimmel local if_name=$1 77173bae673SIdo Schimmel 77273bae673SIdo Schimmel ip -j link show dev $if_name | jq -r '.[]["master"]' 77373bae673SIdo Schimmel} 77473bae673SIdo Schimmel 775d1038cd0SPetr Machatalink_stats_get() 776d1038cd0SPetr Machata{ 777d1038cd0SPetr Machata local if_name=$1; shift 778d1038cd0SPetr Machata local dir=$1; shift 779d1038cd0SPetr Machata local stat=$1; shift 780d1038cd0SPetr Machata 781d1038cd0SPetr Machata ip -j -s link show dev $if_name \ 782d1038cd0SPetr Machata | jq '.[]["stats64"]["'$dir'"]["'$stat'"]' 783d1038cd0SPetr Machata} 784d1038cd0SPetr Machata 7853d578d87SIdo Schimmellink_stats_tx_packets_get() 7863d578d87SIdo Schimmel{ 787d1038cd0SPetr Machata link_stats_get $1 tx packets 788d1038cd0SPetr Machata} 7893d578d87SIdo Schimmel 790d1038cd0SPetr Machatalink_stats_rx_errors_get() 791d1038cd0SPetr Machata{ 792d1038cd0SPetr Machata link_stats_get $1 rx errors 7933d578d87SIdo Schimmel} 7943d578d87SIdo Schimmel 7957d4cbae0SPetr Machatatc_rule_stats_get() 7967d4cbae0SPetr Machata{ 7977d4cbae0SPetr Machata local dev=$1; shift 7987d4cbae0SPetr Machata local pref=$1; shift 799a66d62d8SPetr Machata local dir=$1; shift 800c143139bSPetr Machata local selector=${1:-.packets}; shift 8017d4cbae0SPetr Machata 802a66d62d8SPetr Machata tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \ 803c143139bSPetr Machata | jq ".[1].options.actions[].stats$selector" 8047d4cbae0SPetr Machata} 8057d4cbae0SPetr Machata 80684ea1f85SPetr Machatatc_rule_handle_stats_get() 80784ea1f85SPetr Machata{ 80884ea1f85SPetr Machata local id=$1; shift 80984ea1f85SPetr Machata local handle=$1; shift 81084ea1f85SPetr Machata local selector=${1:-.packets}; shift 811b6d1599fSHangbin Liu local netns=${1:-""}; shift 81284ea1f85SPetr Machata 813b6d1599fSHangbin Liu tc $netns -j -s filter show $id \ 81484ea1f85SPetr Machata | jq ".[] | select(.options.handle == $handle) | \ 81584ea1f85SPetr Machata .options.actions[0].stats$selector" 81684ea1f85SPetr Machata} 81784ea1f85SPetr Machata 8183136a369SPetr Machataethtool_stats_get() 8193136a369SPetr Machata{ 8203136a369SPetr Machata local dev=$1; shift 8213136a369SPetr Machata local stat=$1; shift 8223136a369SPetr Machata 8233136a369SPetr Machata ethtool -S $dev | grep "^ *$stat:" | head -n 1 | cut -d: -f2 8243136a369SPetr Machata} 8253136a369SPetr Machata 826b5bf7126SVladimir Olteanethtool_std_stats_get() 827b5bf7126SVladimir Oltean{ 828b5bf7126SVladimir Oltean local dev=$1; shift 829b5bf7126SVladimir Oltean local grp=$1; shift 830b5bf7126SVladimir Oltean local name=$1; shift 831b5bf7126SVladimir Oltean local src=$1; shift 832b5bf7126SVladimir Oltean 833b5bf7126SVladimir Oltean ethtool --json -S $dev --groups $grp -- --src $src | \ 834b5bf7126SVladimir Oltean jq '.[]."'"$grp"'"."'$name'"' 835b5bf7126SVladimir Oltean} 836b5bf7126SVladimir Oltean 8373de611b5SPetr Machataqdisc_stats_get() 8383de611b5SPetr Machata{ 8393de611b5SPetr Machata local dev=$1; shift 8403de611b5SPetr Machata local handle=$1; shift 8413de611b5SPetr Machata local selector=$1; shift 8423de611b5SPetr Machata 8433de611b5SPetr Machata tc -j -s qdisc show dev "$dev" \ 8443de611b5SPetr Machata | jq '.[] | select(.handle == "'"$handle"'") | '"$selector" 8453de611b5SPetr Machata} 8463de611b5SPetr Machata 847b9b72999SPetr Machataqdisc_parent_stats_get() 848b9b72999SPetr Machata{ 849b9b72999SPetr Machata local dev=$1; shift 850b9b72999SPetr Machata local parent=$1; shift 851b9b72999SPetr Machata local selector=$1; shift 852b9b72999SPetr Machata 853b9b72999SPetr Machata tc -j -s qdisc show dev "$dev" invisible \ 854b9b72999SPetr Machata | jq '.[] | select(.parent == "'"$parent"'") | '"$selector" 855b9b72999SPetr Machata} 856b9b72999SPetr Machata 8570857d6f8SStephen Suryaputraipv6_stats_get() 8580857d6f8SStephen Suryaputra{ 8590857d6f8SStephen Suryaputra local dev=$1; shift 8600857d6f8SStephen Suryaputra local stat=$1; shift 8610857d6f8SStephen Suryaputra 8620857d6f8SStephen Suryaputra cat /proc/net/dev_snmp6/$dev | grep "^$stat" | cut -f2 8630857d6f8SStephen Suryaputra} 8640857d6f8SStephen Suryaputra 86532fb67a3SPetr Machatahw_stats_get() 86632fb67a3SPetr Machata{ 86732fb67a3SPetr Machata local suite=$1; shift 86832fb67a3SPetr Machata local if_name=$1; shift 86932fb67a3SPetr Machata local dir=$1; shift 87032fb67a3SPetr Machata local stat=$1; shift 87132fb67a3SPetr Machata 87232fb67a3SPetr Machata ip -j stats show dev $if_name group offload subgroup $suite | 87332fb67a3SPetr Machata jq ".[0].stats64.$dir.$stat" 87432fb67a3SPetr Machata} 87532fb67a3SPetr Machata 876adc6c7ecSPetr Machatahumanize() 877adc6c7ecSPetr Machata{ 878adc6c7ecSPetr Machata local speed=$1; shift 879adc6c7ecSPetr Machata 880adc6c7ecSPetr Machata for unit in bps Kbps Mbps Gbps; do 881adc6c7ecSPetr Machata if (($(echo "$speed < 1024" | bc))); then 882adc6c7ecSPetr Machata break 883adc6c7ecSPetr Machata fi 884adc6c7ecSPetr Machata 885adc6c7ecSPetr Machata speed=$(echo "scale=1; $speed / 1024" | bc) 886adc6c7ecSPetr Machata done 887adc6c7ecSPetr Machata 888adc6c7ecSPetr Machata echo "$speed${unit}" 889adc6c7ecSPetr Machata} 890adc6c7ecSPetr Machata 891adc6c7ecSPetr Machatarate() 892adc6c7ecSPetr Machata{ 893adc6c7ecSPetr Machata local t0=$1; shift 894adc6c7ecSPetr Machata local t1=$1; shift 895adc6c7ecSPetr Machata local interval=$1; shift 896adc6c7ecSPetr Machata 897adc6c7ecSPetr Machata echo $((8 * (t1 - t0) / interval)) 898adc6c7ecSPetr Machata} 899adc6c7ecSPetr Machata 90053b61f29SBaowen Zhengpackets_rate() 90153b61f29SBaowen Zheng{ 90253b61f29SBaowen Zheng local t0=$1; shift 90353b61f29SBaowen Zheng local t1=$1; shift 90453b61f29SBaowen Zheng local interval=$1; shift 90553b61f29SBaowen Zheng 90653b61f29SBaowen Zheng echo $(((t1 - t0) / interval)) 90753b61f29SBaowen Zheng} 90853b61f29SBaowen Zheng 9094e4272d2SJiri Pirkomac_get() 9104e4272d2SJiri Pirko{ 9114e4272d2SJiri Pirko local if_name=$1 9124e4272d2SJiri Pirko 9134e4272d2SJiri Pirko ip -j link show dev $if_name | jq -r '.[]["address"]' 9144e4272d2SJiri Pirko} 9154e4272d2SJiri Pirko 916a5114df6SVladimir Olteanipv6_lladdr_get() 917a5114df6SVladimir Oltean{ 918a5114df6SVladimir Oltean local if_name=$1 919a5114df6SVladimir Oltean 920a5114df6SVladimir Oltean ip -j addr show dev $if_name | \ 921a5114df6SVladimir Oltean jq -r '.[]["addr_info"][] | select(.scope == "link").local' | \ 922a5114df6SVladimir Oltean head -1 923a5114df6SVladimir Oltean} 924a5114df6SVladimir Oltean 925d4deb014SIdo Schimmelbridge_ageing_time_get() 926d4deb014SIdo Schimmel{ 927d4deb014SIdo Schimmel local bridge=$1 928d4deb014SIdo Schimmel local ageing_time 929d4deb014SIdo Schimmel 930d4deb014SIdo Schimmel # Need to divide by 100 to convert to seconds. 931d4deb014SIdo Schimmel ageing_time=$(ip -j -d link show dev $bridge \ 932d4deb014SIdo Schimmel | jq '.[]["linkinfo"]["info_data"]["ageing_time"]') 933d4deb014SIdo Schimmel echo $((ageing_time / 100)) 934d4deb014SIdo Schimmel} 935d4deb014SIdo Schimmel 936f5ae5778SPetr Machatadeclare -A SYSCTL_ORIG 937f5ae5778SPetr Machatasysctl_set() 938f5ae5778SPetr Machata{ 939f5ae5778SPetr Machata local key=$1; shift 940f5ae5778SPetr Machata local value=$1; shift 941f5ae5778SPetr Machata 942f5ae5778SPetr Machata SYSCTL_ORIG[$key]=$(sysctl -n $key) 9433a082086SHangbin Liu sysctl -qw $key="$value" 944f5ae5778SPetr Machata} 945f5ae5778SPetr Machata 946f5ae5778SPetr Machatasysctl_restore() 947f5ae5778SPetr Machata{ 948f5ae5778SPetr Machata local key=$1; shift 949f5ae5778SPetr Machata 9503a082086SHangbin Liu sysctl -qw $key="${SYSCTL_ORIG[$key]}" 951f5ae5778SPetr Machata} 952f5ae5778SPetr Machata 9537b7bc875SIdo Schimmelforwarding_enable() 9547b7bc875SIdo Schimmel{ 955d51d10aaSPetr Machata sysctl_set net.ipv4.conf.all.forwarding 1 956d51d10aaSPetr Machata sysctl_set net.ipv6.conf.all.forwarding 1 9577b7bc875SIdo Schimmel} 9587b7bc875SIdo Schimmel 9597b7bc875SIdo Schimmelforwarding_restore() 9607b7bc875SIdo Schimmel{ 961d51d10aaSPetr Machata sysctl_restore net.ipv6.conf.all.forwarding 962d51d10aaSPetr Machata sysctl_restore net.ipv4.conf.all.forwarding 9637b7bc875SIdo Schimmel} 9647b7bc875SIdo Schimmel 965a381ed12SPetr Machatadeclare -A MTU_ORIG 966a381ed12SPetr Machatamtu_set() 967a381ed12SPetr Machata{ 968a381ed12SPetr Machata local dev=$1; shift 969a381ed12SPetr Machata local mtu=$1; shift 970a381ed12SPetr Machata 971a381ed12SPetr Machata MTU_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].mtu') 972a381ed12SPetr Machata ip link set dev $dev mtu $mtu 973a381ed12SPetr Machata} 974a381ed12SPetr Machata 975a381ed12SPetr Machatamtu_restore() 976a381ed12SPetr Machata{ 977a381ed12SPetr Machata local dev=$1; shift 978a381ed12SPetr Machata 979a381ed12SPetr Machata ip link set dev $dev mtu ${MTU_ORIG["$dev"]} 980a381ed12SPetr Machata} 981a381ed12SPetr Machata 9822f19f212SJiri Pirkotc_offload_check() 9832f19f212SJiri Pirko{ 98468d9cea5SPetr Machata local num_netifs=${1:-$NUM_NETIFS} 98568d9cea5SPetr Machata 98668d9cea5SPetr Machata for ((i = 1; i <= num_netifs; ++i)); do 9872f19f212SJiri Pirko ethtool -k ${NETIFS[p$i]} \ 9882f19f212SJiri Pirko | grep "hw-tc-offload: on" &> /dev/null 9892f19f212SJiri Pirko if [[ $? -ne 0 ]]; then 9902f19f212SJiri Pirko return 1 9912f19f212SJiri Pirko fi 9922f19f212SJiri Pirko done 9932f19f212SJiri Pirko 9942f19f212SJiri Pirko return 0 9952f19f212SJiri Pirko} 9962f19f212SJiri Pirko 99787c0c046SPetr Machatatrap_install() 9987d4cbae0SPetr Machata{ 9997d4cbae0SPetr Machata local dev=$1; shift 10007d4cbae0SPetr Machata local direction=$1; shift 10017d4cbae0SPetr Machata 1002ac0fcadfSPetr Machata # Some devices may not support or need in-hardware trapping of traffic 1003ac0fcadfSPetr Machata # (e.g. the veth pairs that this library creates for non-existent 1004ac0fcadfSPetr Machata # loopbacks). Use continue instead, so that there is a filter in there 1005ac0fcadfSPetr Machata # (some tests check counters), and so that other filters are still 1006ac0fcadfSPetr Machata # processed. 1007ac0fcadfSPetr Machata tc filter add dev $dev $direction pref 1 \ 1008ac0fcadfSPetr Machata flower skip_sw action trap 2>/dev/null \ 1009ac0fcadfSPetr Machata || tc filter add dev $dev $direction pref 1 \ 1010ac0fcadfSPetr Machata flower action continue 101187c0c046SPetr Machata} 101287c0c046SPetr Machata 101387c0c046SPetr Machatatrap_uninstall() 101487c0c046SPetr Machata{ 101587c0c046SPetr Machata local dev=$1; shift 101687c0c046SPetr Machata local direction=$1; shift 101787c0c046SPetr Machata 1018ac0fcadfSPetr Machata tc filter del dev $dev $direction pref 1 flower 101987c0c046SPetr Machata} 102087c0c046SPetr Machata 102187c0c046SPetr Machataslow_path_trap_install() 102287c0c046SPetr Machata{ 1023ac0fcadfSPetr Machata # For slow-path testing, we need to install a trap to get to 1024ac0fcadfSPetr Machata # slow path the packets that would otherwise be switched in HW. 102587c0c046SPetr Machata if [ "${tcflags/skip_hw}" != "$tcflags" ]; then 102687c0c046SPetr Machata trap_install "$@" 10277d4cbae0SPetr Machata fi 10287d4cbae0SPetr Machata} 10297d4cbae0SPetr Machata 10307d4cbae0SPetr Machataslow_path_trap_uninstall() 10317d4cbae0SPetr Machata{ 10327d4cbae0SPetr Machata if [ "${tcflags/skip_hw}" != "$tcflags" ]; then 103387c0c046SPetr Machata trap_uninstall "$@" 10347d4cbae0SPetr Machata fi 10357d4cbae0SPetr Machata} 10367d4cbae0SPetr Machata 10377d4cbae0SPetr Machata__icmp_capture_add_del() 10387d4cbae0SPetr Machata{ 10397d4cbae0SPetr Machata local add_del=$1; shift 10407d4cbae0SPetr Machata local pref=$1; shift 10417d4cbae0SPetr Machata local vsuf=$1; shift 10427d4cbae0SPetr Machata local tundev=$1; shift 10437d4cbae0SPetr Machata local filter=$1; shift 10447d4cbae0SPetr Machata 10457d4cbae0SPetr Machata tc filter $add_del dev "$tundev" ingress \ 10467d4cbae0SPetr Machata proto ip$vsuf pref $pref \ 10477d4cbae0SPetr Machata flower ip_proto icmp$vsuf $filter \ 10487d4cbae0SPetr Machata action pass 10497d4cbae0SPetr Machata} 10507d4cbae0SPetr Machata 10517d4cbae0SPetr Machataicmp_capture_install() 10527d4cbae0SPetr Machata{ 10537d4cbae0SPetr Machata __icmp_capture_add_del add 100 "" "$@" 10547d4cbae0SPetr Machata} 10557d4cbae0SPetr Machata 10567d4cbae0SPetr Machataicmp_capture_uninstall() 10577d4cbae0SPetr Machata{ 10587d4cbae0SPetr Machata __icmp_capture_add_del del 100 "" "$@" 10597d4cbae0SPetr Machata} 10607d4cbae0SPetr Machata 10617d4cbae0SPetr Machataicmp6_capture_install() 10627d4cbae0SPetr Machata{ 10637d4cbae0SPetr Machata __icmp_capture_add_del add 100 v6 "$@" 10647d4cbae0SPetr Machata} 10657d4cbae0SPetr Machata 10667d4cbae0SPetr Machataicmp6_capture_uninstall() 10677d4cbae0SPetr Machata{ 10687d4cbae0SPetr Machata __icmp_capture_add_del del 100 v6 "$@" 10697d4cbae0SPetr Machata} 10707d4cbae0SPetr Machata 10712004a9bcSPetr Machata__vlan_capture_add_del() 10722004a9bcSPetr Machata{ 10732004a9bcSPetr Machata local add_del=$1; shift 10742004a9bcSPetr Machata local pref=$1; shift 10752004a9bcSPetr Machata local dev=$1; shift 10762004a9bcSPetr Machata local filter=$1; shift 10772004a9bcSPetr Machata 10782004a9bcSPetr Machata tc filter $add_del dev "$dev" ingress \ 10792004a9bcSPetr Machata proto 802.1q pref $pref \ 10802004a9bcSPetr Machata flower $filter \ 10812004a9bcSPetr Machata action pass 10822004a9bcSPetr Machata} 10832004a9bcSPetr Machata 10842004a9bcSPetr Machatavlan_capture_install() 10852004a9bcSPetr Machata{ 10862004a9bcSPetr Machata __vlan_capture_add_del add 100 "$@" 10872004a9bcSPetr Machata} 10882004a9bcSPetr Machata 10892004a9bcSPetr Machatavlan_capture_uninstall() 10902004a9bcSPetr Machata{ 10912004a9bcSPetr Machata __vlan_capture_add_del del 100 "$@" 10922004a9bcSPetr Machata} 10932004a9bcSPetr Machata 1094cf608698SPetr Machata__dscp_capture_add_del() 1095cf608698SPetr Machata{ 1096cf608698SPetr Machata local add_del=$1; shift 1097cf608698SPetr Machata local dev=$1; shift 1098cf608698SPetr Machata local base=$1; shift 1099cf608698SPetr Machata local dscp; 1100cf608698SPetr Machata 1101cf608698SPetr Machata for prio in {0..7}; do 1102cf608698SPetr Machata dscp=$((base + prio)) 1103cf608698SPetr Machata __icmp_capture_add_del $add_del $((dscp + 100)) "" $dev \ 1104cf608698SPetr Machata "skip_hw ip_tos $((dscp << 2))" 1105cf608698SPetr Machata done 1106cf608698SPetr Machata} 1107cf608698SPetr Machata 1108cf608698SPetr Machatadscp_capture_install() 1109cf608698SPetr Machata{ 1110cf608698SPetr Machata local dev=$1; shift 1111cf608698SPetr Machata local base=$1; shift 1112cf608698SPetr Machata 1113cf608698SPetr Machata __dscp_capture_add_del add $dev $base 1114cf608698SPetr Machata} 1115cf608698SPetr Machata 1116cf608698SPetr Machatadscp_capture_uninstall() 1117cf608698SPetr Machata{ 1118cf608698SPetr Machata local dev=$1; shift 1119cf608698SPetr Machata local base=$1; shift 1120cf608698SPetr Machata 1121cf608698SPetr Machata __dscp_capture_add_del del $dev $base 1122cf608698SPetr Machata} 1123cf608698SPetr Machata 1124cf608698SPetr Machatadscp_fetch_stats() 1125cf608698SPetr Machata{ 1126cf608698SPetr Machata local dev=$1; shift 1127cf608698SPetr Machata local base=$1; shift 1128cf608698SPetr Machata 1129cf608698SPetr Machata for prio in {0..7}; do 1130cf608698SPetr Machata local dscp=$((base + prio)) 1131cf608698SPetr Machata local t=$(tc_rule_stats_get $dev $((dscp + 100))) 1132cf608698SPetr Machata echo "[$dscp]=$t " 1133cf608698SPetr Machata done 1134cf608698SPetr Machata} 1135cf608698SPetr Machata 11367d4cbae0SPetr Machatamatchall_sink_create() 11377d4cbae0SPetr Machata{ 11387d4cbae0SPetr Machata local dev=$1; shift 11397d4cbae0SPetr Machata 11407d4cbae0SPetr Machata tc qdisc add dev $dev clsact 11417d4cbae0SPetr Machata tc filter add dev $dev ingress \ 11427d4cbae0SPetr Machata pref 10000 \ 11437d4cbae0SPetr Machata matchall \ 11447d4cbae0SPetr Machata action drop 11457d4cbae0SPetr Machata} 11467d4cbae0SPetr Machata 11470eb8053cSIdo Schimmeltests_run() 11480eb8053cSIdo Schimmel{ 11490eb8053cSIdo Schimmel local current_test 11500eb8053cSIdo Schimmel 11510eb8053cSIdo Schimmel for current_test in ${TESTS:-$ALL_TESTS}; do 11520eb8053cSIdo Schimmel $current_test 11530eb8053cSIdo Schimmel done 11540eb8053cSIdo Schimmel} 11550eb8053cSIdo Schimmel 1156b2c47872SPetr Machatamultipath_eval() 1157b2c47872SPetr Machata{ 1158b2c47872SPetr Machata local desc="$1" 1159b2c47872SPetr Machata local weight_rp12=$2 1160b2c47872SPetr Machata local weight_rp13=$3 1161b2c47872SPetr Machata local packets_rp12=$4 1162b2c47872SPetr Machata local packets_rp13=$5 1163b2c47872SPetr Machata local weights_ratio packets_ratio diff 1164b2c47872SPetr Machata 1165b2c47872SPetr Machata RET=0 1166b2c47872SPetr Machata 11671b86fa3bSPetr Machata if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then 11681b86fa3bSPetr Machata weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \ 11691b86fa3bSPetr Machata | bc -l) 11701b86fa3bSPetr Machata else 11711b86fa3bSPetr Machata weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" \ 11721b86fa3bSPetr Machata | bc -l) 11731b86fa3bSPetr Machata fi 11741b86fa3bSPetr Machata 1175b2c47872SPetr Machata if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then 1176b2c47872SPetr Machata check_err 1 "Packet difference is 0" 1177b2c47872SPetr Machata log_test "Multipath" 1178b2c47872SPetr Machata log_info "Expected ratio $weights_ratio" 1179b2c47872SPetr Machata return 1180b2c47872SPetr Machata fi 1181b2c47872SPetr Machata 1182b2c47872SPetr Machata if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then 1183b2c47872SPetr Machata packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \ 1184b2c47872SPetr Machata | bc -l) 1185b2c47872SPetr Machata else 11861b86fa3bSPetr Machata packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" \ 11871b86fa3bSPetr Machata | bc -l) 1188b2c47872SPetr Machata fi 1189b2c47872SPetr Machata 1190b2c47872SPetr Machata diff=$(echo $weights_ratio - $packets_ratio | bc -l) 1191b2c47872SPetr Machata diff=${diff#-} 1192b2c47872SPetr Machata 1193b2c47872SPetr Machata test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0 1194b2c47872SPetr Machata check_err $? "Too large discrepancy between expected and measured ratios" 1195b2c47872SPetr Machata log_test "$desc" 1196b2c47872SPetr Machata log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio" 1197b2c47872SPetr Machata} 1198b2c47872SPetr Machata 1199d0540d17SPetr Machatain_ns() 1200d0540d17SPetr Machata{ 1201d0540d17SPetr Machata local name=$1; shift 1202d0540d17SPetr Machata 1203d0540d17SPetr Machata ip netns exec $name bash <<-EOF 1204d0540d17SPetr Machata NUM_NETIFS=0 1205d0540d17SPetr Machata source lib.sh 1206d0540d17SPetr Machata $(for a in "$@"; do printf "%q${IFS:0:1}" "$a"; done) 1207d0540d17SPetr Machata EOF 1208d0540d17SPetr Machata} 1209d0540d17SPetr Machata 121073bae673SIdo Schimmel############################################################################## 121173bae673SIdo Schimmel# Tests 121273bae673SIdo Schimmel 1213967450c5SNikolay Aleksandrovping_do() 121473bae673SIdo Schimmel{ 121573bae673SIdo Schimmel local if_name=$1 121673bae673SIdo Schimmel local dip=$2 1217d20b0f21SPetr Machata local args=$3 121873bae673SIdo Schimmel local vrf_name 121973bae673SIdo Schimmel 122073bae673SIdo Schimmel vrf_name=$(master_name_get $if_name) 1221b6a4fd68SIdo Schimmel ip vrf exec $vrf_name \ 12220cd0b1f7SAmit Cohen $PING $args $dip -c $PING_COUNT -i 0.1 \ 12230cd0b1f7SAmit Cohen -w $PING_TIMEOUT &> /dev/null 1224967450c5SNikolay Aleksandrov} 1225967450c5SNikolay Aleksandrov 1226967450c5SNikolay Aleksandrovping_test() 1227967450c5SNikolay Aleksandrov{ 1228967450c5SNikolay Aleksandrov RET=0 1229967450c5SNikolay Aleksandrov 1230967450c5SNikolay Aleksandrov ping_do $1 $2 123173bae673SIdo Schimmel check_err $? 123258c7a2d1SPetr Machata log_test "ping$3" 123373bae673SIdo Schimmel} 123473bae673SIdo Schimmel 12355f44a714SPetr Machataping_test_fails() 12365f44a714SPetr Machata{ 12375f44a714SPetr Machata RET=0 12385f44a714SPetr Machata 12395f44a714SPetr Machata ping_do $1 $2 12405f44a714SPetr Machata check_fail $? 12415f44a714SPetr Machata log_test "ping fails$3" 12425f44a714SPetr Machata} 12435f44a714SPetr Machata 1244967450c5SNikolay Aleksandrovping6_do() 124573bae673SIdo Schimmel{ 124673bae673SIdo Schimmel local if_name=$1 124773bae673SIdo Schimmel local dip=$2 1248d20b0f21SPetr Machata local args=$3 124973bae673SIdo Schimmel local vrf_name 125073bae673SIdo Schimmel 125173bae673SIdo Schimmel vrf_name=$(master_name_get $if_name) 1252b6a4fd68SIdo Schimmel ip vrf exec $vrf_name \ 12530cd0b1f7SAmit Cohen $PING6 $args $dip -c $PING_COUNT -i 0.1 \ 12540cd0b1f7SAmit Cohen -w $PING_TIMEOUT &> /dev/null 1255967450c5SNikolay Aleksandrov} 1256967450c5SNikolay Aleksandrov 1257967450c5SNikolay Aleksandrovping6_test() 1258967450c5SNikolay Aleksandrov{ 1259967450c5SNikolay Aleksandrov RET=0 1260967450c5SNikolay Aleksandrov 1261967450c5SNikolay Aleksandrov ping6_do $1 $2 126273bae673SIdo Schimmel check_err $? 126358c7a2d1SPetr Machata log_test "ping6$3" 126473bae673SIdo Schimmel} 1265d4deb014SIdo Schimmel 12665f44a714SPetr Machataping6_test_fails() 12675f44a714SPetr Machata{ 12685f44a714SPetr Machata RET=0 12695f44a714SPetr Machata 12705f44a714SPetr Machata ping6_do $1 $2 12715f44a714SPetr Machata check_fail $? 12725f44a714SPetr Machata log_test "ping6 fails$3" 12735f44a714SPetr Machata} 12745f44a714SPetr Machata 1275d4deb014SIdo Schimmellearning_test() 1276d4deb014SIdo Schimmel{ 1277d4deb014SIdo Schimmel local bridge=$1 1278d4deb014SIdo Schimmel local br_port1=$2 # Connected to `host1_if`. 1279d4deb014SIdo Schimmel local host1_if=$3 1280d4deb014SIdo Schimmel local host2_if=$4 1281d4deb014SIdo Schimmel local mac=de:ad:be:ef:13:37 1282d4deb014SIdo Schimmel local ageing_time 1283d4deb014SIdo Schimmel 1284d4deb014SIdo Schimmel RET=0 1285d4deb014SIdo Schimmel 1286d4deb014SIdo Schimmel bridge -j fdb show br $bridge brport $br_port1 \ 1287d4deb014SIdo Schimmel | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null 1288d4deb014SIdo Schimmel check_fail $? "Found FDB record when should not" 1289d4deb014SIdo Schimmel 1290d4deb014SIdo Schimmel # Disable unknown unicast flooding on `br_port1` to make sure 1291d4deb014SIdo Schimmel # packets are only forwarded through the port after a matching 1292d4deb014SIdo Schimmel # FDB entry was installed. 1293d4deb014SIdo Schimmel bridge link set dev $br_port1 flood off 1294d4deb014SIdo Schimmel 12951a635d3eSVladimir Oltean ip link set $host1_if promisc on 1296d4deb014SIdo Schimmel tc qdisc add dev $host1_if ingress 1297d4deb014SIdo Schimmel tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \ 1298d4deb014SIdo Schimmel flower dst_mac $mac action drop 1299d4deb014SIdo Schimmel 1300d4deb014SIdo Schimmel $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q 1301d4deb014SIdo Schimmel sleep 1 1302d4deb014SIdo Schimmel 1303d4deb014SIdo Schimmel tc -j -s filter show dev $host1_if ingress \ 1304d4deb014SIdo Schimmel | jq -e ".[] | select(.options.handle == 101) \ 1305d4deb014SIdo Schimmel | select(.options.actions[0].stats.packets == 1)" &> /dev/null 130683844aacSVladimir Oltean check_fail $? "Packet reached first host when should not" 1307d4deb014SIdo Schimmel 1308d4deb014SIdo Schimmel $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q 1309d4deb014SIdo Schimmel sleep 1 1310d4deb014SIdo Schimmel 1311d4deb014SIdo Schimmel bridge -j fdb show br $bridge brport $br_port1 \ 1312d4deb014SIdo Schimmel | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null 1313d4deb014SIdo Schimmel check_err $? "Did not find FDB record when should" 1314d4deb014SIdo Schimmel 1315d4deb014SIdo Schimmel $MZ $host2_if -c 1 -p 64 -b $mac -t ip -q 1316d4deb014SIdo Schimmel sleep 1 1317d4deb014SIdo Schimmel 1318d4deb014SIdo Schimmel tc -j -s filter show dev $host1_if ingress \ 1319d4deb014SIdo Schimmel | jq -e ".[] | select(.options.handle == 101) \ 1320d4deb014SIdo Schimmel | select(.options.actions[0].stats.packets == 1)" &> /dev/null 1321d4deb014SIdo Schimmel check_err $? "Packet did not reach second host when should" 1322d4deb014SIdo Schimmel 1323d4deb014SIdo Schimmel # Wait for 10 seconds after the ageing time to make sure FDB 1324d4deb014SIdo Schimmel # record was aged-out. 1325d4deb014SIdo Schimmel ageing_time=$(bridge_ageing_time_get $bridge) 1326d4deb014SIdo Schimmel sleep $((ageing_time + 10)) 1327d4deb014SIdo Schimmel 1328d4deb014SIdo Schimmel bridge -j fdb show br $bridge brport $br_port1 \ 1329d4deb014SIdo Schimmel | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null 1330d4deb014SIdo Schimmel check_fail $? "Found FDB record when should not" 1331d4deb014SIdo Schimmel 1332d4deb014SIdo Schimmel bridge link set dev $br_port1 learning off 1333d4deb014SIdo Schimmel 1334d4deb014SIdo Schimmel $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q 1335d4deb014SIdo Schimmel sleep 1 1336d4deb014SIdo Schimmel 1337d4deb014SIdo Schimmel bridge -j fdb show br $bridge brport $br_port1 \ 1338d4deb014SIdo Schimmel | jq -e ".[] | select(.mac == \"$mac\")" &> /dev/null 1339d4deb014SIdo Schimmel check_fail $? "Found FDB record when should not" 1340d4deb014SIdo Schimmel 1341d4deb014SIdo Schimmel bridge link set dev $br_port1 learning on 1342d4deb014SIdo Schimmel 1343d4deb014SIdo Schimmel tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower 1344d4deb014SIdo Schimmel tc qdisc del dev $host1_if ingress 13451a635d3eSVladimir Oltean ip link set $host1_if promisc off 1346d4deb014SIdo Schimmel 1347d4deb014SIdo Schimmel bridge link set dev $br_port1 flood on 1348d4deb014SIdo Schimmel 1349d4deb014SIdo Schimmel log_test "FDB learning" 1350d4deb014SIdo Schimmel} 1351236dd50bSIdo Schimmel 1352236dd50bSIdo Schimmelflood_test_do() 1353236dd50bSIdo Schimmel{ 1354236dd50bSIdo Schimmel local should_flood=$1 1355236dd50bSIdo Schimmel local mac=$2 1356236dd50bSIdo Schimmel local ip=$3 1357236dd50bSIdo Schimmel local host1_if=$4 1358236dd50bSIdo Schimmel local host2_if=$5 1359236dd50bSIdo Schimmel local err=0 1360236dd50bSIdo Schimmel 1361236dd50bSIdo Schimmel # Add an ACL on `host2_if` which will tell us whether the packet 1362236dd50bSIdo Schimmel # was flooded to it or not. 1363b8e629b0SVladimir Oltean ip link set $host2_if promisc on 1364236dd50bSIdo Schimmel tc qdisc add dev $host2_if ingress 1365236dd50bSIdo Schimmel tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \ 1366236dd50bSIdo Schimmel flower dst_mac $mac action drop 1367236dd50bSIdo Schimmel 1368236dd50bSIdo Schimmel $MZ $host1_if -c 1 -p 64 -b $mac -B $ip -t ip -q 1369236dd50bSIdo Schimmel sleep 1 1370236dd50bSIdo Schimmel 1371236dd50bSIdo Schimmel tc -j -s filter show dev $host2_if ingress \ 1372236dd50bSIdo Schimmel | jq -e ".[] | select(.options.handle == 101) \ 1373236dd50bSIdo Schimmel | select(.options.actions[0].stats.packets == 1)" &> /dev/null 1374236dd50bSIdo Schimmel if [[ $? -ne 0 && $should_flood == "true" || \ 1375236dd50bSIdo Schimmel $? -eq 0 && $should_flood == "false" ]]; then 1376236dd50bSIdo Schimmel err=1 1377236dd50bSIdo Schimmel fi 1378236dd50bSIdo Schimmel 1379236dd50bSIdo Schimmel tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower 1380236dd50bSIdo Schimmel tc qdisc del dev $host2_if ingress 1381b8e629b0SVladimir Oltean ip link set $host2_if promisc off 1382236dd50bSIdo Schimmel 1383236dd50bSIdo Schimmel return $err 1384236dd50bSIdo Schimmel} 1385236dd50bSIdo Schimmel 1386236dd50bSIdo Schimmelflood_unicast_test() 1387236dd50bSIdo Schimmel{ 1388236dd50bSIdo Schimmel local br_port=$1 1389236dd50bSIdo Schimmel local host1_if=$2 1390236dd50bSIdo Schimmel local host2_if=$3 1391236dd50bSIdo Schimmel local mac=de:ad:be:ef:13:37 1392236dd50bSIdo Schimmel local ip=192.0.2.100 1393236dd50bSIdo Schimmel 1394236dd50bSIdo Schimmel RET=0 1395236dd50bSIdo Schimmel 1396236dd50bSIdo Schimmel bridge link set dev $br_port flood off 1397236dd50bSIdo Schimmel 1398236dd50bSIdo Schimmel flood_test_do false $mac $ip $host1_if $host2_if 1399236dd50bSIdo Schimmel check_err $? "Packet flooded when should not" 1400236dd50bSIdo Schimmel 1401236dd50bSIdo Schimmel bridge link set dev $br_port flood on 1402236dd50bSIdo Schimmel 1403236dd50bSIdo Schimmel flood_test_do true $mac $ip $host1_if $host2_if 1404236dd50bSIdo Schimmel check_err $? "Packet was not flooded when should" 1405236dd50bSIdo Schimmel 1406236dd50bSIdo Schimmel log_test "Unknown unicast flood" 1407236dd50bSIdo Schimmel} 1408236dd50bSIdo Schimmel 1409236dd50bSIdo Schimmelflood_multicast_test() 1410236dd50bSIdo Schimmel{ 1411236dd50bSIdo Schimmel local br_port=$1 1412236dd50bSIdo Schimmel local host1_if=$2 1413236dd50bSIdo Schimmel local host2_if=$3 1414236dd50bSIdo Schimmel local mac=01:00:5e:00:00:01 1415236dd50bSIdo Schimmel local ip=239.0.0.1 1416236dd50bSIdo Schimmel 1417236dd50bSIdo Schimmel RET=0 1418236dd50bSIdo Schimmel 1419236dd50bSIdo Schimmel bridge link set dev $br_port mcast_flood off 1420236dd50bSIdo Schimmel 1421236dd50bSIdo Schimmel flood_test_do false $mac $ip $host1_if $host2_if 1422236dd50bSIdo Schimmel check_err $? "Packet flooded when should not" 1423236dd50bSIdo Schimmel 1424236dd50bSIdo Schimmel bridge link set dev $br_port mcast_flood on 1425236dd50bSIdo Schimmel 1426236dd50bSIdo Schimmel flood_test_do true $mac $ip $host1_if $host2_if 1427236dd50bSIdo Schimmel check_err $? "Packet was not flooded when should" 1428236dd50bSIdo Schimmel 1429236dd50bSIdo Schimmel log_test "Unregistered multicast flood" 1430236dd50bSIdo Schimmel} 1431236dd50bSIdo Schimmel 1432236dd50bSIdo Schimmelflood_test() 1433236dd50bSIdo Schimmel{ 1434236dd50bSIdo Schimmel # `br_port` is connected to `host2_if` 1435236dd50bSIdo Schimmel local br_port=$1 1436236dd50bSIdo Schimmel local host1_if=$2 1437236dd50bSIdo Schimmel local host2_if=$3 1438236dd50bSIdo Schimmel 1439236dd50bSIdo Schimmel flood_unicast_test $br_port $host1_if $host2_if 1440236dd50bSIdo Schimmel flood_multicast_test $br_port $host1_if $host2_if 1441236dd50bSIdo Schimmel} 14424cf9b8f9SPetr Machata 14434113b048SPetr Machata__start_traffic() 14444cf9b8f9SPetr Machata{ 14451531cc63SPetr Machata local pktsize=$1; shift 14464113b048SPetr Machata local proto=$1; shift 14474cf9b8f9SPetr Machata local h_in=$1; shift # Where the traffic egresses the host 14484cf9b8f9SPetr Machata local sip=$1; shift 14494cf9b8f9SPetr Machata local dip=$1; shift 14504cf9b8f9SPetr Machata local dmac=$1; shift 14514cf9b8f9SPetr Machata 14521531cc63SPetr Machata $MZ $h_in -p $pktsize -A $sip -B $dip -c 0 \ 14534113b048SPetr Machata -a own -b $dmac -t "$proto" -q "$@" & 14544cf9b8f9SPetr Machata sleep 1 14554cf9b8f9SPetr Machata} 14564cf9b8f9SPetr Machata 14571531cc63SPetr Machatastart_traffic_pktsize() 14581531cc63SPetr Machata{ 14591531cc63SPetr Machata local pktsize=$1; shift 14601531cc63SPetr Machata 14611531cc63SPetr Machata __start_traffic $pktsize udp "$@" 14621531cc63SPetr Machata} 14631531cc63SPetr Machata 14641531cc63SPetr Machatastart_tcp_traffic_pktsize() 14651531cc63SPetr Machata{ 14661531cc63SPetr Machata local pktsize=$1; shift 14671531cc63SPetr Machata 14681531cc63SPetr Machata __start_traffic $pktsize tcp "$@" 14691531cc63SPetr Machata} 14701531cc63SPetr Machata 14714113b048SPetr Machatastart_traffic() 14724113b048SPetr Machata{ 14731531cc63SPetr Machata start_traffic_pktsize 8000 "$@" 14744113b048SPetr Machata} 14754113b048SPetr Machata 14764113b048SPetr Machatastart_tcp_traffic() 14774113b048SPetr Machata{ 14781531cc63SPetr Machata start_tcp_traffic_pktsize 8000 "$@" 14794113b048SPetr Machata} 14804113b048SPetr Machata 14814cf9b8f9SPetr Machatastop_traffic() 14824cf9b8f9SPetr Machata{ 14834cf9b8f9SPetr Machata # Suppress noise from killing mausezahn. 14844cf9b8f9SPetr Machata { kill %% && wait %%; } 2>/dev/null 14854cf9b8f9SPetr Machata} 14868cd6b020SVladimir Oltean 14876182c5c5SJoachim Wibergdeclare -A cappid 14886182c5c5SJoachim Wibergdeclare -A capfile 14896182c5c5SJoachim Wibergdeclare -A capout 14906182c5c5SJoachim Wiberg 14918cd6b020SVladimir Olteantcpdump_start() 14928cd6b020SVladimir Oltean{ 14938cd6b020SVladimir Oltean local if_name=$1; shift 14948cd6b020SVladimir Oltean local ns=$1; shift 14958cd6b020SVladimir Oltean 14966182c5c5SJoachim Wiberg capfile[$if_name]=$(mktemp) 14976182c5c5SJoachim Wiberg capout[$if_name]=$(mktemp) 14988cd6b020SVladimir Oltean 14998cd6b020SVladimir Oltean if [ -z $ns ]; then 15008cd6b020SVladimir Oltean ns_cmd="" 15018cd6b020SVladimir Oltean else 15028cd6b020SVladimir Oltean ns_cmd="ip netns exec ${ns}" 15038cd6b020SVladimir Oltean fi 15048cd6b020SVladimir Oltean 15058cd6b020SVladimir Oltean if [ -z $SUDO_USER ] ; then 15068cd6b020SVladimir Oltean capuser="" 15078cd6b020SVladimir Oltean else 15088cd6b020SVladimir Oltean capuser="-Z $SUDO_USER" 15098cd6b020SVladimir Oltean fi 15108cd6b020SVladimir Oltean 1511fe32dffdSJoachim Wiberg $ns_cmd tcpdump $TCPDUMP_EXTRA_FLAGS -e -n -Q in -i $if_name \ 15126182c5c5SJoachim Wiberg -s 65535 -B 32768 $capuser -w ${capfile[$if_name]} \ 15136182c5c5SJoachim Wiberg > "${capout[$if_name]}" 2>&1 & 15146182c5c5SJoachim Wiberg cappid[$if_name]=$! 15158cd6b020SVladimir Oltean 15168cd6b020SVladimir Oltean sleep 1 15178cd6b020SVladimir Oltean} 15188cd6b020SVladimir Oltean 15198cd6b020SVladimir Olteantcpdump_stop() 15208cd6b020SVladimir Oltean{ 15216182c5c5SJoachim Wiberg local if_name=$1 15226182c5c5SJoachim Wiberg local pid=${cappid[$if_name]} 15236182c5c5SJoachim Wiberg 15246182c5c5SJoachim Wiberg $ns_cmd kill "$pid" && wait "$pid" 15258cd6b020SVladimir Oltean sleep 1 15268cd6b020SVladimir Oltean} 15278cd6b020SVladimir Oltean 15288cd6b020SVladimir Olteantcpdump_cleanup() 15298cd6b020SVladimir Oltean{ 15306182c5c5SJoachim Wiberg local if_name=$1 15316182c5c5SJoachim Wiberg 15326182c5c5SJoachim Wiberg rm ${capfile[$if_name]} ${capout[$if_name]} 15338cd6b020SVladimir Oltean} 15348cd6b020SVladimir Oltean 15358cd6b020SVladimir Olteantcpdump_show() 15368cd6b020SVladimir Oltean{ 15376182c5c5SJoachim Wiberg local if_name=$1 15386182c5c5SJoachim Wiberg 15396182c5c5SJoachim Wiberg tcpdump -e -n -r ${capfile[$if_name]} 2>&1 15408cd6b020SVladimir Oltean} 1541537e4825SNikolay Aleksandrov 1542537e4825SNikolay Aleksandrov# return 0 if the packet wasn't seen on host2_if or 1 if it was 1543537e4825SNikolay Aleksandrovmcast_packet_test() 1544537e4825SNikolay Aleksandrov{ 1545537e4825SNikolay Aleksandrov local mac=$1 1546537e4825SNikolay Aleksandrov local src_ip=$2 1547537e4825SNikolay Aleksandrov local ip=$3 1548537e4825SNikolay Aleksandrov local host1_if=$4 1549537e4825SNikolay Aleksandrov local host2_if=$5 1550537e4825SNikolay Aleksandrov local seen=0 1551450b0b84SNikolay Aleksandrov local tc_proto="ip" 1552450b0b84SNikolay Aleksandrov local mz_v6arg="" 1553450b0b84SNikolay Aleksandrov 1554450b0b84SNikolay Aleksandrov # basic check to see if we were passed an IPv4 address, if not assume IPv6 1555450b0b84SNikolay Aleksandrov if [[ ! $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 1556450b0b84SNikolay Aleksandrov tc_proto="ipv6" 1557450b0b84SNikolay Aleksandrov mz_v6arg="-6" 1558450b0b84SNikolay Aleksandrov fi 1559537e4825SNikolay Aleksandrov 1560537e4825SNikolay Aleksandrov # Add an ACL on `host2_if` which will tell us whether the packet 1561537e4825SNikolay Aleksandrov # was received by it or not. 1562537e4825SNikolay Aleksandrov tc qdisc add dev $host2_if ingress 1563450b0b84SNikolay Aleksandrov tc filter add dev $host2_if ingress protocol $tc_proto pref 1 handle 101 \ 1564537e4825SNikolay Aleksandrov flower ip_proto udp dst_mac $mac action drop 1565537e4825SNikolay Aleksandrov 1566450b0b84SNikolay Aleksandrov $MZ $host1_if $mz_v6arg -c 1 -p 64 -b $mac -A $src_ip -B $ip -t udp "dp=4096,sp=2048" -q 1567537e4825SNikolay Aleksandrov sleep 1 1568537e4825SNikolay Aleksandrov 1569537e4825SNikolay Aleksandrov tc -j -s filter show dev $host2_if ingress \ 1570537e4825SNikolay Aleksandrov | jq -e ".[] | select(.options.handle == 101) \ 1571537e4825SNikolay Aleksandrov | select(.options.actions[0].stats.packets == 1)" &> /dev/null 1572537e4825SNikolay Aleksandrov if [[ $? -eq 0 ]]; then 1573537e4825SNikolay Aleksandrov seen=1 1574537e4825SNikolay Aleksandrov fi 1575537e4825SNikolay Aleksandrov 1576450b0b84SNikolay Aleksandrov tc filter del dev $host2_if ingress protocol $tc_proto pref 1 handle 101 flower 1577537e4825SNikolay Aleksandrov tc qdisc del dev $host2_if ingress 1578537e4825SNikolay Aleksandrov 1579537e4825SNikolay Aleksandrov return $seen 1580537e4825SNikolay Aleksandrov} 158195e6f430SNikolay Aleksandrov 158295e6f430SNikolay Aleksandrovbrmcast_check_sg_entries() 158395e6f430SNikolay Aleksandrov{ 158495e6f430SNikolay Aleksandrov local report=$1; shift 158595e6f430SNikolay Aleksandrov local slist=("$@") 158695e6f430SNikolay Aleksandrov local sarg="" 158795e6f430SNikolay Aleksandrov 158895e6f430SNikolay Aleksandrov for src in "${slist[@]}"; do 158995e6f430SNikolay Aleksandrov sarg="${sarg} and .source_list[].address == \"$src\"" 159095e6f430SNikolay Aleksandrov done 159195e6f430SNikolay Aleksandrov bridge -j -d -s mdb show dev br0 \ 159295e6f430SNikolay Aleksandrov | jq -e ".[].mdb[] | \ 159395e6f430SNikolay Aleksandrov select(.grp == \"$TEST_GROUP\" and .source_list != null $sarg)" &>/dev/null 159495e6f430SNikolay Aleksandrov check_err $? "Wrong *,G entry source list after $report report" 159595e6f430SNikolay Aleksandrov 159695e6f430SNikolay Aleksandrov for sgent in "${slist[@]}"; do 159795e6f430SNikolay Aleksandrov bridge -j -d -s mdb show dev br0 \ 159895e6f430SNikolay Aleksandrov | jq -e ".[].mdb[] | \ 159995e6f430SNikolay Aleksandrov select(.grp == \"$TEST_GROUP\" and .src == \"$sgent\")" &>/dev/null 160095e6f430SNikolay Aleksandrov check_err $? "Missing S,G entry ($sgent, $TEST_GROUP)" 160195e6f430SNikolay Aleksandrov done 160295e6f430SNikolay Aleksandrov} 160395e6f430SNikolay Aleksandrov 160495e6f430SNikolay Aleksandrovbrmcast_check_sg_fwding() 160595e6f430SNikolay Aleksandrov{ 160695e6f430SNikolay Aleksandrov local should_fwd=$1; shift 160795e6f430SNikolay Aleksandrov local sources=("$@") 160895e6f430SNikolay Aleksandrov 160995e6f430SNikolay Aleksandrov for src in "${sources[@]}"; do 161095e6f430SNikolay Aleksandrov local retval=0 161195e6f430SNikolay Aleksandrov 161295e6f430SNikolay Aleksandrov mcast_packet_test $TEST_GROUP_MAC $src $TEST_GROUP $h2 $h1 161395e6f430SNikolay Aleksandrov retval=$? 161495e6f430SNikolay Aleksandrov if [ $should_fwd -eq 1 ]; then 161595e6f430SNikolay Aleksandrov check_fail $retval "Didn't forward traffic from S,G ($src, $TEST_GROUP)" 161695e6f430SNikolay Aleksandrov else 161795e6f430SNikolay Aleksandrov check_err $retval "Forwarded traffic for blocked S,G ($src, $TEST_GROUP)" 161895e6f430SNikolay Aleksandrov fi 161995e6f430SNikolay Aleksandrov done 162095e6f430SNikolay Aleksandrov} 162195e6f430SNikolay Aleksandrov 162295e6f430SNikolay Aleksandrovbrmcast_check_sg_state() 162395e6f430SNikolay Aleksandrov{ 162495e6f430SNikolay Aleksandrov local is_blocked=$1; shift 162595e6f430SNikolay Aleksandrov local sources=("$@") 162695e6f430SNikolay Aleksandrov local should_fail=1 162795e6f430SNikolay Aleksandrov 162895e6f430SNikolay Aleksandrov if [ $is_blocked -eq 1 ]; then 162995e6f430SNikolay Aleksandrov should_fail=0 163095e6f430SNikolay Aleksandrov fi 163195e6f430SNikolay Aleksandrov 163295e6f430SNikolay Aleksandrov for src in "${sources[@]}"; do 163395e6f430SNikolay Aleksandrov bridge -j -d -s mdb show dev br0 \ 163495e6f430SNikolay Aleksandrov | jq -e ".[].mdb[] | \ 163595e6f430SNikolay Aleksandrov select(.grp == \"$TEST_GROUP\" and .source_list != null) | 163695e6f430SNikolay Aleksandrov .source_list[] | 163795e6f430SNikolay Aleksandrov select(.address == \"$src\") | 163895e6f430SNikolay Aleksandrov select(.timer == \"0.00\")" &>/dev/null 163995e6f430SNikolay Aleksandrov check_err_fail $should_fail $? "Entry $src has zero timer" 164095e6f430SNikolay Aleksandrov 164195e6f430SNikolay Aleksandrov bridge -j -d -s mdb show dev br0 \ 164295e6f430SNikolay Aleksandrov | jq -e ".[].mdb[] | \ 164395e6f430SNikolay Aleksandrov select(.grp == \"$TEST_GROUP\" and .src == \"$src\" and \ 164495e6f430SNikolay Aleksandrov .flags[] == \"blocked\")" &>/dev/null 164595e6f430SNikolay Aleksandrov check_err_fail $should_fail $? "Entry $src has blocked flag" 164695e6f430SNikolay Aleksandrov done 164795e6f430SNikolay Aleksandrov} 16489b18942eSPetr Machata 1649f23cddc7SVladimir Olteanmc_join() 1650f23cddc7SVladimir Oltean{ 1651f23cddc7SVladimir Oltean local if_name=$1 1652f23cddc7SVladimir Oltean local group=$2 1653f23cddc7SVladimir Oltean local vrf_name=$(master_name_get $if_name) 1654f23cddc7SVladimir Oltean 1655f23cddc7SVladimir Oltean # We don't care about actual reception, just about joining the 1656f23cddc7SVladimir Oltean # IP multicast group and adding the L2 address to the device's 1657f23cddc7SVladimir Oltean # MAC filtering table 1658f23cddc7SVladimir Oltean ip vrf exec $vrf_name \ 1659f23cddc7SVladimir Oltean mreceive -g $group -I $if_name > /dev/null 2>&1 & 1660f23cddc7SVladimir Oltean mreceive_pid=$! 1661f23cddc7SVladimir Oltean 1662f23cddc7SVladimir Oltean sleep 1 1663f23cddc7SVladimir Oltean} 1664f23cddc7SVladimir Oltean 1665f23cddc7SVladimir Olteanmc_leave() 1666f23cddc7SVladimir Oltean{ 1667f23cddc7SVladimir Oltean kill "$mreceive_pid" && wait "$mreceive_pid" 1668f23cddc7SVladimir Oltean} 1669f23cddc7SVladimir Oltean 1670f23cddc7SVladimir Olteanmc_send() 1671f23cddc7SVladimir Oltean{ 1672f23cddc7SVladimir Oltean local if_name=$1 1673f23cddc7SVladimir Oltean local groups=$2 1674f23cddc7SVladimir Oltean local vrf_name=$(master_name_get $if_name) 1675f23cddc7SVladimir Oltean 1676f23cddc7SVladimir Oltean ip vrf exec $vrf_name \ 1677f23cddc7SVladimir Oltean msend -g $groups -I $if_name -c 1 > /dev/null 2>&1 1678f23cddc7SVladimir Oltean} 1679f23cddc7SVladimir Oltean 16809b18942eSPetr Machatastart_ip_monitor() 16819b18942eSPetr Machata{ 16829b18942eSPetr Machata local mtype=$1; shift 16839b18942eSPetr Machata local ip=${1-ip}; shift 16849b18942eSPetr Machata 16859b18942eSPetr Machata # start the monitor in the background 16869b18942eSPetr Machata tmpfile=`mktemp /var/run/nexthoptestXXX` 16879b18942eSPetr Machata mpid=`($ip monitor $mtype > $tmpfile & echo $!) 2>/dev/null` 16889b18942eSPetr Machata sleep 0.2 16899b18942eSPetr Machata echo "$mpid $tmpfile" 16909b18942eSPetr Machata} 16919b18942eSPetr Machata 16929b18942eSPetr Machatastop_ip_monitor() 16939b18942eSPetr Machata{ 16949b18942eSPetr Machata local mpid=$1; shift 16959b18942eSPetr Machata local tmpfile=$1; shift 16969b18942eSPetr Machata local el=$1; shift 16979b18942eSPetr Machata local what=$1; shift 16989b18942eSPetr Machata 16999b18942eSPetr Machata sleep 0.2 17009b18942eSPetr Machata kill $mpid 17019b18942eSPetr Machata local lines=`grep '^\w' $tmpfile | wc -l` 17029b18942eSPetr Machata test $lines -eq $el 17039b18942eSPetr Machata check_err $? "$what: $lines lines of events, expected $el" 17049b18942eSPetr Machata rm -rf $tmpfile 17059b18942eSPetr Machata} 17069b18942eSPetr Machata 17079b18942eSPetr Machatahw_stats_monitor_test() 17089b18942eSPetr Machata{ 17099b18942eSPetr Machata local dev=$1; shift 17109b18942eSPetr Machata local type=$1; shift 17119b18942eSPetr Machata local make_suitable=$1; shift 17129b18942eSPetr Machata local make_unsuitable=$1; shift 17139b18942eSPetr Machata local ip=${1-ip}; shift 17149b18942eSPetr Machata 17159b18942eSPetr Machata RET=0 17169b18942eSPetr Machata 17179b18942eSPetr Machata # Expect a notification about enablement. 17189b18942eSPetr Machata local ipmout=$(start_ip_monitor stats "$ip") 17199b18942eSPetr Machata $ip stats set dev $dev ${type}_stats on 17209b18942eSPetr Machata stop_ip_monitor $ipmout 1 "${type}_stats enablement" 17219b18942eSPetr Machata 17229b18942eSPetr Machata # Expect a notification about offload. 17239b18942eSPetr Machata local ipmout=$(start_ip_monitor stats "$ip") 17249b18942eSPetr Machata $make_suitable 17259b18942eSPetr Machata stop_ip_monitor $ipmout 1 "${type}_stats installation" 17269b18942eSPetr Machata 17279b18942eSPetr Machata # Expect a notification about loss of offload. 17289b18942eSPetr Machata local ipmout=$(start_ip_monitor stats "$ip") 17299b18942eSPetr Machata $make_unsuitable 17309b18942eSPetr Machata stop_ip_monitor $ipmout 1 "${type}_stats deinstallation" 17319b18942eSPetr Machata 17329b18942eSPetr Machata # Expect a notification about disablement 17339b18942eSPetr Machata local ipmout=$(start_ip_monitor stats "$ip") 17349b18942eSPetr Machata $ip stats set dev $dev ${type}_stats off 17359b18942eSPetr Machata stop_ip_monitor $ipmout 1 "${type}_stats disablement" 17369b18942eSPetr Machata 17379b18942eSPetr Machata log_test "${type}_stats notifications" 17389b18942eSPetr Machata} 1739344dd2c9SPetr Machata 1740fcf49276SPetr Machataipv4_to_bytes() 1741fcf49276SPetr Machata{ 1742fcf49276SPetr Machata local IP=$1; shift 1743fcf49276SPetr Machata 1744fcf49276SPetr Machata printf '%02x:' ${IP//./ } | 1745fcf49276SPetr Machata sed 's/:$//' 1746fcf49276SPetr Machata} 1747fcf49276SPetr Machata 1748fcf49276SPetr Machata# Convert a given IPv6 address, `IP' such that the :: token, if present, is 1749fcf49276SPetr Machata# expanded, and each 16-bit group is padded with zeroes to be 4 hexadecimal 1750fcf49276SPetr Machata# digits. An optional `BYTESEP' parameter can be given to further separate 1751fcf49276SPetr Machata# individual bytes of each 16-bit group. 1752fcf49276SPetr Machataexpand_ipv6() 1753fcf49276SPetr Machata{ 1754fcf49276SPetr Machata local IP=$1; shift 1755fcf49276SPetr Machata local bytesep=$1; shift 1756fcf49276SPetr Machata 1757fcf49276SPetr Machata local cvt_ip=${IP/::/_} 1758fcf49276SPetr Machata local colons=${cvt_ip//[^:]/} 1759fcf49276SPetr Machata local allcol=::::::: 1760fcf49276SPetr Machata # IP where :: -> the appropriate number of colons: 1761fcf49276SPetr Machata local allcol_ip=${cvt_ip/_/${allcol:${#colons}}} 1762fcf49276SPetr Machata 1763fcf49276SPetr Machata echo $allcol_ip | tr : '\n' | 1764fcf49276SPetr Machata sed s/^/0000/ | 1765fcf49276SPetr Machata sed 's/.*\(..\)\(..\)/\1'"$bytesep"'\2/' | 1766fcf49276SPetr Machata tr '\n' : | 1767fcf49276SPetr Machata sed 's/:$//' 1768fcf49276SPetr Machata} 1769fcf49276SPetr Machata 1770fcf49276SPetr Machataipv6_to_bytes() 1771fcf49276SPetr Machata{ 1772fcf49276SPetr Machata local IP=$1; shift 1773fcf49276SPetr Machata 1774fcf49276SPetr Machata expand_ipv6 "$IP" : 1775fcf49276SPetr Machata} 1776fcf49276SPetr Machata 1777952e0ee3SPetr Machatau16_to_bytes() 1778952e0ee3SPetr Machata{ 1779952e0ee3SPetr Machata local u16=$1; shift 1780952e0ee3SPetr Machata 1781952e0ee3SPetr Machata printf "%04x" $u16 | sed 's/^/000/;s/^.*\(..\)\(..\)$/\1:\2/' 1782952e0ee3SPetr Machata} 1783952e0ee3SPetr Machata 1784952e0ee3SPetr Machata# Given a mausezahn-formatted payload (colon-separated bytes given as %02x), 1785952e0ee3SPetr Machata# possibly with a keyword CHECKSUM stashed where a 16-bit checksum should be, 1786952e0ee3SPetr Machata# calculate checksum as per RFC 1071, assuming the CHECKSUM field (if any) 1787952e0ee3SPetr Machata# stands for 00:00. 1788952e0ee3SPetr Machatapayload_template_calc_checksum() 1789952e0ee3SPetr Machata{ 1790952e0ee3SPetr Machata local payload=$1; shift 1791952e0ee3SPetr Machata 1792952e0ee3SPetr Machata ( 1793952e0ee3SPetr Machata # Set input radix. 1794952e0ee3SPetr Machata echo "16i" 1795952e0ee3SPetr Machata # Push zero for the initial checksum. 1796952e0ee3SPetr Machata echo 0 1797952e0ee3SPetr Machata 1798952e0ee3SPetr Machata # Pad the payload with a terminating 00: in case we get an odd 1799952e0ee3SPetr Machata # number of bytes. 1800952e0ee3SPetr Machata echo "${payload%:}:00:" | 1801952e0ee3SPetr Machata sed 's/CHECKSUM/00:00/g' | 1802952e0ee3SPetr Machata tr '[:lower:]' '[:upper:]' | 1803952e0ee3SPetr Machata # Add the word to the checksum. 1804952e0ee3SPetr Machata sed 's/\(..\):\(..\):/\1\2+\n/g' | 1805952e0ee3SPetr Machata # Strip the extra odd byte we pushed if left unconverted. 1806952e0ee3SPetr Machata sed 's/\(..\):$//' 1807952e0ee3SPetr Machata 1808952e0ee3SPetr Machata echo "10000 ~ +" # Calculate and add carry. 1809952e0ee3SPetr Machata echo "FFFF r - p" # Bit-flip and print. 1810952e0ee3SPetr Machata ) | 1811952e0ee3SPetr Machata dc | 1812952e0ee3SPetr Machata tr '[:upper:]' '[:lower:]' 1813952e0ee3SPetr Machata} 1814952e0ee3SPetr Machata 1815952e0ee3SPetr Machatapayload_template_expand_checksum() 1816952e0ee3SPetr Machata{ 1817952e0ee3SPetr Machata local payload=$1; shift 1818952e0ee3SPetr Machata local checksum=$1; shift 1819952e0ee3SPetr Machata 1820952e0ee3SPetr Machata local ckbytes=$(u16_to_bytes $checksum) 1821952e0ee3SPetr Machata 1822952e0ee3SPetr Machata echo "$payload" | sed "s/CHECKSUM/$ckbytes/g" 1823952e0ee3SPetr Machata} 1824952e0ee3SPetr Machata 1825952e0ee3SPetr Machatapayload_template_nbytes() 1826952e0ee3SPetr Machata{ 1827952e0ee3SPetr Machata local payload=$1; shift 1828952e0ee3SPetr Machata 1829952e0ee3SPetr Machata payload_template_expand_checksum "${payload%:}" 0 | 1830952e0ee3SPetr Machata sed 's/:/\n/g' | wc -l 1831952e0ee3SPetr Machata} 1832952e0ee3SPetr Machata 1833344dd2c9SPetr Machataigmpv3_is_in_get() 1834344dd2c9SPetr Machata{ 1835506a1ac9SPetr Machata local GRP=$1; shift 1836705d4bc7SPetr Machata local sources=("$@") 1837506a1ac9SPetr Machata 1838344dd2c9SPetr Machata local igmpv3 1839705d4bc7SPetr Machata local nsources=$(u16_to_bytes ${#sources[@]}) 1840344dd2c9SPetr Machata 1841705d4bc7SPetr Machata # IS_IN ( $sources ) 1842344dd2c9SPetr Machata igmpv3=$(: 1843344dd2c9SPetr Machata )"22:"$( : Type - Membership Report 1844344dd2c9SPetr Machata )"00:"$( : Reserved 1845506a1ac9SPetr Machata )"CHECKSUM:"$( : Checksum 1846344dd2c9SPetr Machata )"00:00:"$( : Reserved 1847344dd2c9SPetr Machata )"00:01:"$( : Number of Group Records 1848344dd2c9SPetr Machata )"01:"$( : Record Type - IS_IN 1849344dd2c9SPetr Machata )"00:"$( : Aux Data Len 1850705d4bc7SPetr Machata )"${nsources}:"$( : Number of Sources 1851506a1ac9SPetr Machata )"$(ipv4_to_bytes $GRP):"$( : Multicast Address 1852705d4bc7SPetr Machata )"$(for src in "${sources[@]}"; do 1853705d4bc7SPetr Machata ipv4_to_bytes $src 1854705d4bc7SPetr Machata echo -n : 1855705d4bc7SPetr Machata done)"$( : Source Addresses 1856344dd2c9SPetr Machata ) 1857506a1ac9SPetr Machata local checksum=$(payload_template_calc_checksum "$igmpv3") 1858344dd2c9SPetr Machata 1859506a1ac9SPetr Machata payload_template_expand_checksum "$igmpv3" $checksum 1860344dd2c9SPetr Machata} 1861344dd2c9SPetr Machata 18629ae85469SPetr Machataigmpv2_leave_get() 18639ae85469SPetr Machata{ 18649ae85469SPetr Machata local GRP=$1; shift 18659ae85469SPetr Machata 18669ae85469SPetr Machata local payload=$(: 18679ae85469SPetr Machata )"17:"$( : Type - Leave Group 18689ae85469SPetr Machata )"00:"$( : Max Resp Time - not meaningful 18699ae85469SPetr Machata )"CHECKSUM:"$( : Checksum 18709ae85469SPetr Machata )"$(ipv4_to_bytes $GRP)"$( : Group Address 18719ae85469SPetr Machata ) 18729ae85469SPetr Machata local checksum=$(payload_template_calc_checksum "$payload") 18739ae85469SPetr Machata 18749ae85469SPetr Machata payload_template_expand_checksum "$payload" $checksum 18759ae85469SPetr Machata} 18769ae85469SPetr Machata 1877344dd2c9SPetr Machatamldv2_is_in_get() 1878344dd2c9SPetr Machata{ 1879506a1ac9SPetr Machata local SIP=$1; shift 1880506a1ac9SPetr Machata local GRP=$1; shift 1881705d4bc7SPetr Machata local sources=("$@") 1882506a1ac9SPetr Machata 1883344dd2c9SPetr Machata local hbh 1884344dd2c9SPetr Machata local icmpv6 1885705d4bc7SPetr Machata local nsources=$(u16_to_bytes ${#sources[@]}) 1886344dd2c9SPetr Machata 1887344dd2c9SPetr Machata hbh=$(: 1888344dd2c9SPetr Machata )"3a:"$( : Next Header - ICMPv6 1889344dd2c9SPetr Machata )"00:"$( : Hdr Ext Len 1890344dd2c9SPetr Machata )"00:00:00:00:00:00:"$( : Options and Padding 1891344dd2c9SPetr Machata ) 1892344dd2c9SPetr Machata 1893344dd2c9SPetr Machata icmpv6=$(: 1894344dd2c9SPetr Machata )"8f:"$( : Type - MLDv2 Report 1895344dd2c9SPetr Machata )"00:"$( : Code 1896506a1ac9SPetr Machata )"CHECKSUM:"$( : Checksum 1897344dd2c9SPetr Machata )"00:00:"$( : Reserved 1898344dd2c9SPetr Machata )"00:01:"$( : Number of Group Records 1899344dd2c9SPetr Machata )"01:"$( : Record Type - IS_IN 1900344dd2c9SPetr Machata )"00:"$( : Aux Data Len 1901705d4bc7SPetr Machata )"${nsources}:"$( : Number of Sources 1902506a1ac9SPetr Machata )"$(ipv6_to_bytes $GRP):"$( : Multicast address 1903705d4bc7SPetr Machata )"$(for src in "${sources[@]}"; do 1904705d4bc7SPetr Machata ipv6_to_bytes $src 1905705d4bc7SPetr Machata echo -n : 1906705d4bc7SPetr Machata done)"$( : Source Addresses 1907344dd2c9SPetr Machata ) 1908344dd2c9SPetr Machata 1909506a1ac9SPetr Machata local len=$(u16_to_bytes $(payload_template_nbytes $icmpv6)) 1910506a1ac9SPetr Machata local sudohdr=$(: 1911506a1ac9SPetr Machata )"$(ipv6_to_bytes $SIP):"$( : SIP 1912506a1ac9SPetr Machata )"$(ipv6_to_bytes $GRP):"$( : DIP is multicast address 1913506a1ac9SPetr Machata )"${len}:"$( : Upper-layer length 1914506a1ac9SPetr Machata )"00:3a:"$( : Zero and next-header 1915506a1ac9SPetr Machata ) 1916506a1ac9SPetr Machata local checksum=$(payload_template_calc_checksum ${sudohdr}${icmpv6}) 1917506a1ac9SPetr Machata 1918506a1ac9SPetr Machata payload_template_expand_checksum "$hbh$icmpv6" $checksum 1919344dd2c9SPetr Machata} 19209ae85469SPetr Machata 19219ae85469SPetr Machatamldv1_done_get() 19229ae85469SPetr Machata{ 19239ae85469SPetr Machata local SIP=$1; shift 19249ae85469SPetr Machata local GRP=$1; shift 19259ae85469SPetr Machata 19269ae85469SPetr Machata local hbh 19279ae85469SPetr Machata local icmpv6 19289ae85469SPetr Machata 19299ae85469SPetr Machata hbh=$(: 19309ae85469SPetr Machata )"3a:"$( : Next Header - ICMPv6 19319ae85469SPetr Machata )"00:"$( : Hdr Ext Len 19329ae85469SPetr Machata )"00:00:00:00:00:00:"$( : Options and Padding 19339ae85469SPetr Machata ) 19349ae85469SPetr Machata 19359ae85469SPetr Machata icmpv6=$(: 19369ae85469SPetr Machata )"84:"$( : Type - MLDv1 Done 19379ae85469SPetr Machata )"00:"$( : Code 19389ae85469SPetr Machata )"CHECKSUM:"$( : Checksum 19399ae85469SPetr Machata )"00:00:"$( : Max Resp Delay - not meaningful 19409ae85469SPetr Machata )"00:00:"$( : Reserved 19419ae85469SPetr Machata )"$(ipv6_to_bytes $GRP):"$( : Multicast address 19429ae85469SPetr Machata ) 19439ae85469SPetr Machata 19449ae85469SPetr Machata local len=$(u16_to_bytes $(payload_template_nbytes $icmpv6)) 19459ae85469SPetr Machata local sudohdr=$(: 19469ae85469SPetr Machata )"$(ipv6_to_bytes $SIP):"$( : SIP 19479ae85469SPetr Machata )"$(ipv6_to_bytes $GRP):"$( : DIP is multicast address 19489ae85469SPetr Machata )"${len}:"$( : Upper-layer length 19499ae85469SPetr Machata )"00:3a:"$( : Zero and next-header 19509ae85469SPetr Machata ) 19519ae85469SPetr Machata local checksum=$(payload_template_calc_checksum ${sudohdr}${icmpv6}) 19529ae85469SPetr Machata 19539ae85469SPetr Machata payload_template_expand_checksum "$hbh$icmpv6" $checksum 19549ae85469SPetr Machata} 19558fcac792SPetr Machata 19568fcac792SPetr Machatabail_on_lldpad() 19578fcac792SPetr Machata{ 19588fcac792SPetr Machata local reason1="$1"; shift 19598fcac792SPetr Machata local reason2="$1"; shift 19608fcac792SPetr Machata 19618fcac792SPetr Machata if systemctl is-active --quiet lldpad; then 19628fcac792SPetr Machata 19638fcac792SPetr Machata cat >/dev/stderr <<-EOF 19648fcac792SPetr Machata WARNING: lldpad is running 19658fcac792SPetr Machata 19668fcac792SPetr Machata lldpad will likely $reason1, and this test will 19678fcac792SPetr Machata $reason2. Both are not supported at the same time, 19688fcac792SPetr Machata one of them is arbitrarily going to overwrite the 19698fcac792SPetr Machata other. That will cause spurious failures (or, unlikely, 19708fcac792SPetr Machata passes) of this test. 19718fcac792SPetr Machata EOF 19728fcac792SPetr Machata 19738fcac792SPetr Machata if [[ -z $ALLOW_LLDPAD ]]; then 19748fcac792SPetr Machata cat >/dev/stderr <<-EOF 19758fcac792SPetr Machata 19768fcac792SPetr Machata If you want to run the test anyway, please set 19778fcac792SPetr Machata an environment variable ALLOW_LLDPAD to a 19788fcac792SPetr Machata non-empty string. 19798fcac792SPetr Machata EOF 19808fcac792SPetr Machata exit 1 19818fcac792SPetr Machata else 19828fcac792SPetr Machata return 19838fcac792SPetr Machata fi 19848fcac792SPetr Machata fi 19858fcac792SPetr Machata} 1986