#!/bin/bash# SPDX-License-Identifier: GPL-2.0 ############################################################################### Topology description. p1 looped back to p2, p3 to p4 and so on. declare -A NETIFS=( [p1]=veth0 [p2]=veth1 [p3]=veth2 [p4]=veth3 [p5]=veth4 [p6]=veth5 [p7]=veth6 [p8]=veth7 [p9]=veth8 [p10]=veth9) # Port that does not have a cable connected.: "${NETIF_NO_CABLE:=eth8}" ############################################################################### Defines # Networking utilities.: "${PING:=ping}": "${PING6:=ping6}" # Some distros just use ping.: "${ARPING:=arping}": "${TROUTE6:=traceroute6}" # Packet generator.: "${MZ:=mausezahn}" # Some distributions use 'mz'.: "${MZ_DELAY:=0}" # Host configuration tools.: "${TEAMD:=teamd}": "${MCD:=smcrouted}": "${MC_CLI:=smcroutectl}" # Constants for netdevice bring-up:# Default time in seconds to wait for an interface to come up before giving up# and bailing out. Used during initial setup.: "${INTERFACE_TIMEOUT:=600}"# Like INTERFACE_TIMEOUT, but default for ad-hoc waiting in testing scripts.: "${WAIT_TIMEOUT:=20}"# Time to wait after interfaces participating in the test are all UP.: "${WAIT_TIME:=5}" # Whether to pause on, respectively, after a failure and before cleanup.: "${PAUSE_ON_CLEANUP:=no}" # Whether to create virtual interfaces, and what netdevice type they should be.: "${NETIF_CREATE:=yes}": "${NETIF_TYPE:=veth}" # Constants for ping tests:# How many packets should be sent.: "${PING_COUNT:=10}"# Timeout (in seconds) before ping exits regardless of how many packets have# been sent or received: "${PING_TIMEOUT:=5}" # Minimum ageing_time (in centiseconds) supported by hardware: "${LOW_AGEING_TIME:=1000}" # Whether to check for availability of certain tools.: "${REQUIRE_JQ:=yes}": "${REQUIRE_MZ:=yes}": "${REQUIRE_MTOOLS:=no}" # Whether to override MAC addresses on interfaces participating in the test.: "${STABLE_MAC_ADDRS:=no}" # Flags for tcpdump: "${TCPDUMP_EXTRA_FLAGS:=}" # Flags for TC filters.: "${TC_FLAG:=skip_hw}" # Whether the machine is "slow" -- i.e. might be incapable of running tests# involving heavy traffic. This might be the case on a debug kernel, a VM, or# e.g. a low-power board.: "${KSFT_MACHINE_SLOW:=no}" ############################################################################### Find netifs by test-specified driver name driver_name_get(){ local dev=$1; shift local driver_path="/sys/class/net/$dev/device/driver" if [[ -L $driver_path ]]; then basename `realpath $driver_path` fi} netif_find_driver(){ local ifnames=`ip -j link show | jq -r ".[].ifname"` local count=0 for ifname in $ifnames do local driver_name=`driver_name_get $ifname` if [[ ! -z $driver_name && $driver_name == $NETIF_FIND_DRIVER ]]; then count=$((count + 1)) NETIFS[p$count]="$ifname" fi done} # Whether to find netdevice according to the driver speficied by the importer: "${NETIF_FIND_DRIVER:=}" if [[ $NETIF_FIND_DRIVER ]]; then unset NETIFS declare -A NETIFS netif_find_driverfi net_forwarding_dir=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") if [[ -f $net_forwarding_dir/forwarding.config ]]; then source "$net_forwarding_dir/forwarding.config"fi source "$net_forwarding_dir/../lib.sh" ############################################################################### Sanity checks check_tc_version(){ tc -j &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing JSON support" exit $ksft_skip fi} # Old versions of tc don't understand "mpls_uc"check_tc_mpls_support(){ local dev=$1; shift tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ matchall action pipe &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing MPLS support" return $ksft_skip fi tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ matchall} # Old versions of tc produce invalid json output for mpls lse statisticscheck_tc_mpls_lse_stats(){ local dev=$1; shift local ret; tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ flower mpls lse depth 2 \ action continue &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc-flower is missing extended MPLS support" return $ksft_skip fi tc -j filter show dev $dev ingress protocol mpls_uc | jq . &> /dev/null ret=$? tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ flower if [[ $ret -ne 0 ]]; then echo "SKIP: iproute2 too old; tc-flower produces invalid json output for extended MPLS filters" return $ksft_skip fi} check_tc_shblock_support(){ tc filter help 2>&1 | grep block &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing shared block support" exit $ksft_skip fi} check_tc_chain_support(){ tc help 2>&1|grep chain &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing chain support" exit $ksft_skip fi} check_tc_action_hw_stats_support(){ tc actions help 2>&1 | grep -q hw_stats if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing action hw_stats support" exit $ksft_skip fi} check_tc_fp_support(){ tc qdisc add dev lo mqprio help 2>&1 | grep -q "fp " if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing frame preemption support" exit $ksft_skip fi} check_ethtool_lanes_support(){ ethtool --help 2>&1| grep lanes &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: ethtool too old; it is missing lanes support" exit $ksft_skip fi} check_ethtool_mm_support(){ ethtool --help 2>&1| grep -- '--show-mm' &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: ethtool too old; it is missing MAC Merge layer support" exit $ksft_skip fi} check_ethtool_counter_group_support(){ ethtool --help 2>&1| grep -- '--all-groups' &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: ethtool too old; it is missing standard counter group support" exit $ksft_skip fi} check_ethtool_pmac_std_stats_support(){ local dev=$1; shift local grp=$1; shift [ 0 -ne $(ethtool --json -S $dev --all-groups --src pmac 2>/dev/null \ | jq ".[].\"$grp\" | length") ]} check_locked_port_support(){ if ! bridge -d link show | grep -q " locked"; then echo "SKIP: iproute2 too old; Locked port feature not supported." return $ksft_skip fi} check_port_mab_support(){ if ! bridge -d link show | grep -q "mab"; then echo "SKIP: iproute2 too old; MacAuth feature not supported." return $ksft_skip fi} if [[ "$(id -u)" -ne 0 ]]; then echo "SKIP: need root privileges" exit $ksft_skipfi check_driver(){ local dev=$1; shift local expected=$1; shift local driver_name=`driver_name_get $dev` if [[ $driver_name != $expected ]]; then echo "SKIP: expected driver $expected for $dev, got $driver_name instead" exit $ksft_skip fi} if [[ "$CHECK_TC" = "yes" ]]; then check_tc_versionfi require_command(){ local cmd=$1; shift if [[ ! -x "$(command -v "$cmd")" ]]; then echo "SKIP: $cmd not installed" exit $ksft_skip fi} # IPv6 support was added in v3.0check_mtools_version(){ local version="$(msend -v)" local major version=${version##msend version } major=$(echo $version | cut -d. -f1) if [ $major -lt 3 ]; then echo "SKIP: expected mtools version 3.0, got $version" exit $ksft_skip fi} if [[ "$REQUIRE_JQ" = "yes" ]]; then require_command jqfiif [[ "$REQUIRE_MZ" = "yes" ]]; then require_command $MZfiif [[ "$REQUIRE_MTOOLS" = "yes" ]]; then # https://github.com/troglobit/mtools require_command msend require_command mreceive check_mtools_versionfi ############################################################################### Command line options handling count=0 while [[ $# -gt 0 ]]; do if [[ "$count" -eq "0" ]]; then unset NETIFS declare -A NETIFS fi count=$((count + 1)) NETIFS[p$count]="$1" shiftdone ############################################################################### Network interfaces configuration if [[ ! -v NUM_NETIFS ]]; then echo "SKIP: importer does not define \"NUM_NETIFS\"" exit $ksft_skipfi if (( NUM_NETIFS > ${#NETIFS[@]} )); then echo "SKIP: Importer requires $NUM_NETIFS NETIFS, but only ${#NETIFS[@]} are defined (${NETIFS[@]})" exit $ksft_skipfi for i in $(seq ${#NETIFS[@]}); do if [[ ! ${NETIFS[p$i]} ]]; then echo "SKIP: NETIFS[p$i] not given" exit $ksft_skip fidone create_netif_veth(){ local i for ((i = 1; i <= NUM_NETIFS; ++i)); do local j=$((i+1)) if [ -z ${NETIFS[p$i]} ]; then echo "SKIP: Cannot create interface. Name not specified" exit $ksft_skip fi ip link show dev ${NETIFS[p$i]} &> /dev/null if [[ $? -ne 0 ]]; then ip link add ${NETIFS[p$i]} type veth \ peer name ${NETIFS[p$j]} if [[ $? -ne 0 ]]; then echo "Failed to create netif" exit 1 fi fi i=$j done} create_netif(){ case "$NETIF_TYPE" in veth) create_netif_veth ;; *) echo "Can not create interfaces of type \'$NETIF_TYPE\'" exit 1 ;; esac} declare -A MAC_ADDR_ORIGmac_addr_prepare(){ local new_addr= local dev= for ((i = 1; i <= NUM_NETIFS; ++i)); do dev=${NETIFS[p$i]} new_addr=$(printf "00:01:02:03:04:%02x" $i) MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address') # Strip quotes MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/} ip link set dev $dev address $new_addr done} mac_addr_restore(){ local dev= for ((i = 1; i <= NUM_NETIFS; ++i)); do dev=${NETIFS[p$i]} ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]} done} if [[ "$NETIF_CREATE" = "yes" ]]; then create_netiffi if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then mac_addr_preparefi for ((i = 1; i <= NUM_NETIFS; ++i)); do ip link show dev ${NETIFS[p$i]} &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: could not find all required interfaces" exit $ksft_skip fidone ############################################################################### Helpers not(){ "$@" [[ $? != 0 ]]} get_max(){ local arr=("$@") max=${arr[0]} for cur in ${arr[@]}; do if [[ $cur -gt $max ]]; then max=$cur fi done echo $max} grep_bridge_fdb(){ local addr=$1; shift local word local flag if [ "$1" == "self" ] || [ "$1" == "master" ]; then word=$1; shift if [ "$1" == "-v" ]; then flag=$1; shift fi fi $@ | grep $addr | grep $flag "$word"} wait_for_port_up(){ "$@" | grep -q "Link detected: yes"} wait_for_offload(){ "$@" | grep -q offload} wait_for_trap(){ "$@" | grep -q trap} setup_wait_dev(){Lines 1–500 of 2107. Load more
#!/bin/bash # SPDX-License-Identifier: GPL-2.0 ############################################################################## # Topology description. p1 looped back to p2, p3 to p4 and so on. declare -A NETIFS=( [p1]=veth0 [p2]=veth1 [p3]=veth2 [p4]=veth3 [p5]=veth4 [p6]=veth5 [p7]=veth6 [p8]=veth7 [p9]=veth8 [p10]=veth9 ) # Port that does not have a cable connected. : "${NETIF_NO_CABLE:=eth8}" ############################################################################## # Defines # Networking utilities. : "${PING:=ping}" : "${PING6:=ping6}" # Some distros just use ping. : "${ARPING:=arping}" : "${TROUTE6:=traceroute6}" # Packet generator. : "${MZ:=mausezahn}" # Some distributions use 'mz'. : "${MZ_DELAY:=0}" # Host configuration tools. : "${TEAMD:=teamd}" : "${MCD:=smcrouted}" : "${MC_CLI:=smcroutectl}" # Constants for netdevice bring-up: # Default time in seconds to wait for an interface to come up before giving up # and bailing out. Used during initial setup. : "${INTERFACE_TIMEOUT:=600}" # Like INTERFACE_TIMEOUT, but default for ad-hoc waiting in testing scripts. : "${WAIT_TIMEOUT:=20}" # Time to wait after interfaces participating in the test are all UP. : "${WAIT_TIME:=5}" # Whether to pause on, respectively, after a failure and before cleanup. : "${PAUSE_ON_CLEANUP:=no}" # Whether to create virtual interfaces, and what netdevice type they should be. : "${NETIF_CREATE:=yes}" : "${NETIF_TYPE:=veth}" # Constants for ping tests: # How many packets should be sent. : "${PING_COUNT:=10}" # Timeout (in seconds) before ping exits regardless of how many packets have # been sent or received : "${PING_TIMEOUT:=5}" # Minimum ageing_time (in centiseconds) supported by hardware : "${LOW_AGEING_TIME:=1000}" # Whether to check for availability of certain tools. : "${REQUIRE_JQ:=yes}" : "${REQUIRE_MZ:=yes}" : "${REQUIRE_MTOOLS:=no}" # Whether to override MAC addresses on interfaces participating in the test. : "${STABLE_MAC_ADDRS:=no}" # Flags for tcpdump : "${TCPDUMP_EXTRA_FLAGS:=}" # Flags for TC filters. : "${TC_FLAG:=skip_hw}" # Whether the machine is "slow" -- i.e. might be incapable of running tests # involving heavy traffic. This might be the case on a debug kernel, a VM, or # e.g. a low-power board. : "${KSFT_MACHINE_SLOW:=no}" ############################################################################## # Find netifs by test-specified driver name driver_name_get() { local dev=$1; shift local driver_path="/sys/class/net/$dev/device/driver" if [[ -L $driver_path ]]; then basename `realpath $driver_path` fi } netif_find_driver() { local ifnames=`ip -j link show | jq -r ".[].ifname"` local count=0 for ifname in $ifnames do local driver_name=`driver_name_get $ifname` if [[ ! -z $driver_name && $driver_name == $NETIF_FIND_DRIVER ]]; then count=$((count + 1)) NETIFS[p$count]="$ifname" fi done } # Whether to find netdevice according to the driver speficied by the importer : "${NETIF_FIND_DRIVER:=}" if [[ $NETIF_FIND_DRIVER ]]; then unset NETIFS declare -A NETIFS netif_find_driver fi net_forwarding_dir=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") if [[ -f $net_forwarding_dir/forwarding.config ]]; then source "$net_forwarding_dir/forwarding.config" fi source "$net_forwarding_dir/../lib.sh" ############################################################################## # Sanity checks check_tc_version() { tc -j &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing JSON support" exit $ksft_skip fi } # Old versions of tc don't understand "mpls_uc" check_tc_mpls_support() { local dev=$1; shift tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ matchall action pipe &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing MPLS support" return $ksft_skip fi tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ matchall } # Old versions of tc produce invalid json output for mpls lse statistics check_tc_mpls_lse_stats() { local dev=$1; shift local ret; tc filter add dev $dev ingress protocol mpls_uc pref 1 handle 1 \ flower mpls lse depth 2 \ action continue &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc-flower is missing extended MPLS support" return $ksft_skip fi tc -j filter show dev $dev ingress protocol mpls_uc | jq . &> /dev/null ret=$? tc filter del dev $dev ingress protocol mpls_uc pref 1 handle 1 \ flower if [[ $ret -ne 0 ]]; then echo "SKIP: iproute2 too old; tc-flower produces invalid json output for extended MPLS filters" return $ksft_skip fi } check_tc_shblock_support() { tc filter help 2>&1 | grep block &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing shared block support" exit $ksft_skip fi } check_tc_chain_support() { tc help 2>&1|grep chain &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing chain support" exit $ksft_skip fi } check_tc_action_hw_stats_support() { tc actions help 2>&1 | grep -q hw_stats if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing action hw_stats support" exit $ksft_skip fi } check_tc_fp_support() { tc qdisc add dev lo mqprio help 2>&1 | grep -q "fp " if [[ $? -ne 0 ]]; then echo "SKIP: iproute2 too old; tc is missing frame preemption support" exit $ksft_skip fi } check_ethtool_lanes_support() { ethtool --help 2>&1| grep lanes &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: ethtool too old; it is missing lanes support" exit $ksft_skip fi } check_ethtool_mm_support() { ethtool --help 2>&1| grep -- '--show-mm' &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: ethtool too old; it is missing MAC Merge layer support" exit $ksft_skip fi } check_ethtool_counter_group_support() { ethtool --help 2>&1| grep -- '--all-groups' &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: ethtool too old; it is missing standard counter group support" exit $ksft_skip fi } check_ethtool_pmac_std_stats_support() { local dev=$1; shift local grp=$1; shift [ 0 -ne $(ethtool --json -S $dev --all-groups --src pmac 2>/dev/null \ | jq ".[].\"$grp\" | length") ] } check_locked_port_support() { if ! bridge -d link show | grep -q " locked"; then echo "SKIP: iproute2 too old; Locked port feature not supported." return $ksft_skip fi } check_port_mab_support() { if ! bridge -d link show | grep -q "mab"; then echo "SKIP: iproute2 too old; MacAuth feature not supported." return $ksft_skip fi } if [[ "$(id -u)" -ne 0 ]]; then echo "SKIP: need root privileges" exit $ksft_skip fi check_driver() { local dev=$1; shift local expected=$1; shift local driver_name=`driver_name_get $dev` if [[ $driver_name != $expected ]]; then echo "SKIP: expected driver $expected for $dev, got $driver_name instead" exit $ksft_skip fi } if [[ "$CHECK_TC" = "yes" ]]; then check_tc_version fi require_command() { local cmd=$1; shift if [[ ! -x "$(command -v "$cmd")" ]]; then echo "SKIP: $cmd not installed" exit $ksft_skip fi } # IPv6 support was added in v3.0 check_mtools_version() { local version="$(msend -v)" local major version=${version##msend version } major=$(echo $version | cut -d. -f1) if [ $major -lt 3 ]; then echo "SKIP: expected mtools version 3.0, got $version" exit $ksft_skip fi } if [[ "$REQUIRE_JQ" = "yes" ]]; then require_command jq fi if [[ "$REQUIRE_MZ" = "yes" ]]; then require_command $MZ fi if [[ "$REQUIRE_MTOOLS" = "yes" ]]; then # https://github.com/troglobit/mtools require_command msend require_command mreceive check_mtools_version fi ############################################################################## # Command line options handling count=0 while [[ $# -gt 0 ]]; do if [[ "$count" -eq "0" ]]; then unset NETIFS declare -A NETIFS fi count=$((count + 1)) NETIFS[p$count]="$1" shift done ############################################################################## # Network interfaces configuration if [[ ! -v NUM_NETIFS ]]; then echo "SKIP: importer does not define \"NUM_NETIFS\"" exit $ksft_skip fi if (( NUM_NETIFS > ${#NETIFS[@]} )); then echo "SKIP: Importer requires $NUM_NETIFS NETIFS, but only ${#NETIFS[@]} are defined (${NETIFS[@]})" exit $ksft_skip fi for i in $(seq ${#NETIFS[@]}); do if [[ ! ${NETIFS[p$i]} ]]; then echo "SKIP: NETIFS[p$i] not given" exit $ksft_skip fi done create_netif_veth() { local i for ((i = 1; i <= NUM_NETIFS; ++i)); do local j=$((i+1)) if [ -z ${NETIFS[p$i]} ]; then echo "SKIP: Cannot create interface. Name not specified" exit $ksft_skip fi ip link show dev ${NETIFS[p$i]} &> /dev/null if [[ $? -ne 0 ]]; then ip link add ${NETIFS[p$i]} type veth \ peer name ${NETIFS[p$j]} if [[ $? -ne 0 ]]; then echo "Failed to create netif" exit 1 fi fi i=$j done } create_netif() { case "$NETIF_TYPE" in veth) create_netif_veth ;; *) echo "Can not create interfaces of type \'$NETIF_TYPE\'" exit 1 ;; esac } declare -A MAC_ADDR_ORIG mac_addr_prepare() { local new_addr= local dev= for ((i = 1; i <= NUM_NETIFS; ++i)); do dev=${NETIFS[p$i]} new_addr=$(printf "00:01:02:03:04:%02x" $i) MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address') # Strip quotes MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/} ip link set dev $dev address $new_addr done } mac_addr_restore() { local dev= for ((i = 1; i <= NUM_NETIFS; ++i)); do dev=${NETIFS[p$i]} ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]} done } if [[ "$NETIF_CREATE" = "yes" ]]; then create_netif fi if [[ "$STABLE_MAC_ADDRS" = "yes" ]]; then mac_addr_prepare fi for ((i = 1; i <= NUM_NETIFS; ++i)); do ip link show dev ${NETIFS[p$i]} &> /dev/null if [[ $? -ne 0 ]]; then echo "SKIP: could not find all required interfaces" exit $ksft_skip fi done ############################################################################## # Helpers not() { "$@" [[ $? != 0 ]] } get_max() { local arr=("$@") max=${arr[0]} for cur in ${arr[@]}; do if [[ $cur -gt $max ]]; then max=$cur fi done echo $max } grep_bridge_fdb() { local addr=$1; shift local word local flag if [ "$1" == "self" ] || [ "$1" == "master" ]; then word=$1; shift if [ "$1" == "-v" ]; then flag=$1; shift fi fi $@ | grep $addr | grep $flag "$word" } wait_for_port_up() { "$@" | grep -q "Link detected: yes" } wait_for_offload() { "$@" | grep -q offload } wait_for_trap() { "$@" | grep -q trap } setup_wait_dev() {