2313 lines · 46.9 KB · Shell
RawDownload
#!/bin/bash# SPDX-License-Identifier: GPL-2.0#shellcheck disable=SC2034 # SC doesn't see our uses of global variables ############################################################################### 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}": "${MCD_TABLE_NAME:=selftests}" # 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}": "${REQUIRE_TEAMD:=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} check_tc_erspan_support(){	local dev=$1; shift 	tc filter add dev $dev ingress pref 1 handle 1 flower \		erspan_opts 1:0:0:0 &> /dev/null	if [[ $? -ne 0 ]]; then		echo "SKIP: iproute2 too old; tc is missing erspan support"		return $ksft_skip	fi	tc filter del dev $dev ingress pref 1 handle 1 flower \		erspan_opts 1:0:0:0 &> /dev/null} # 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 # 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_TEAMD" = "yes" ]]; then	require_command $TEAMDfiif [[ "$REQUIRE_MTOOLS" = "yes" ]]; then	# https://github.com/troglobit/mtools	require_command msend	require_command mreceive	check_mtools_versionfi ############################################################################### Command line options handling check_env() {	if [[ ! (( -n "$LOCAL_V4" && -n "$REMOTE_V4") ||		 ( -n "$LOCAL_V6" && -n "$REMOTE_V6" )) ]]; then		echo "SKIP: Invalid environment, missing or inconsistent LOCAL_V4/REMOTE_V4/LOCAL_V6/REMOTE_V6"		echo "Please see tools/testing/selftests/drivers/net/README.rst"		exit "$ksft_skip"	fi 	if [[ -z "$REMOTE_TYPE" ]]; then		echo "SKIP: Invalid environment, missing REMOTE_TYPE"		exit "$ksft_skip"	fi 	if [[ -z "$REMOTE_ARGS" ]]; then		echo "SKIP: Invalid environment, missing REMOTE_ARGS"		exit "$ksft_skip"	fi} __run_on(){	local target=$1; shift	local type args 	IFS=':' read -r type args <<< "$target" 	case "$type" in	netns)		# Execute command in network namespace		# args contains the namespace name		ip netns exec "$args" "$@"		;;	ssh)		# Execute command via SSH args contains user@host		ssh -n "$args" "$@"		;;	local|*)		# Execute command locally. This is also the fallback		# case for when the interface's target is not found in		# the TARGETS array.		"$@"		;;	esac} run_on(){	local iface=$1; shift	local target="local:" 	if [ "${DRIVER_TEST_CONFORMANT}" = "yes" ]; then		target="${TARGETS[$iface]}"	fi 	__run_on "$target" "$@"} get_ifname_by_ip(){	local target=$1; shift	local ip_addr=$1; shift 	__run_on "$target" ip -j addr show to "$ip_addr" | jq -r '.[].ifname'} # Wait for the device to refresh its HW statistics. Devices latch the stats# reported via ethtool only every stats-block-usecs, so sample after that.hw_stats_settle(){	local iface=$1; shift	local usecs 	# Match only a non-zero integer; 0 or "n/a" use default (20msec)	usecs=$(run_on "$iface" ethtool -c "$iface" 2>/dev/null | \		sed -n 's/^stats-block-usecs:[[:space:]]*\([1-9][0-9]*\)$/\1/p')	usecs=${usecs:-20000} 	sleep "$(echo "$usecs * 1.25 / 1000 / 1000" | bc -l)"} # Whether the test is conforming to the requirements and usage described in# drivers/net/README.rst.: "${DRIVER_TEST_CONFORMANT:=no}" declare -A TARGETS # Based on DRIVER_TEST_CONFORMANT, decide if to source drivers/net/net.config# or not. In the "yes" case, the test expects to pass the arguments through the# variables specified in drivers/net/README.rst file. If not, fallback on# parsing the script arguments for interface names.if [ "${DRIVER_TEST_CONFORMANT}" = "yes" ]; then	if [[ -f $net_forwarding_dir/../../drivers/net/net.config ]]; then		source "$net_forwarding_dir/../../drivers/net/net.config"	fi 	if (( NUM_NETIFS > 2)); then		echo "SKIP: DRIVER_TEST_CONFORMANT=yes and NUM_NETIFS is bigger than 2"		exit "$ksft_skip"	fi 	check_env 	# Populate the NETIFS and TARGETS arrays automatically based on the	# environment variables. The TARGETS array is indexed by the network	# interface name keeping track of the target on which the interface	# resides. Values will be strings of the following format -	# <type>:<args>.	#	# TARGETS[eth0]="local:" - meaning that the eth0 interface is	# accessible locally	# TARGETS[eth1]="netns:foo" - eth1 is in the foo netns	# TARGETS[eth2]="ssh:root@10.0.0.2" - eth2 is accessible through	# running the 'ssh root@10.0.0.2' command. 	unset NETIFS	declare -A NETIFS 	NETIFS[p1]="$NETIF"	TARGETS[$NETIF]="local:" 	# Locate the name of the remote interface	remote_target="$REMOTE_TYPE:$REMOTE_ARGS"	if [[ -v REMOTE_V4 ]]; then		remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V4")	else		remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V6")	fi	if [[ ! -n "$remote_netif" ]]; then		echo "SKIP: cannot find remote interface"		exit "$ksft_skip"	fi 	if [[ "$NETIF" == "$remote_netif" ]]; then		echo "SKIP: local and remote interfaces cannot have the same name"		exit "$ksft_skip"	fi 	NETIFS[p2]="$remote_netif"	TARGETS[$remote_netif]="$REMOTE_TYPE:$REMOTE_ARGS"else	count=0	# Prime NETIFS from the command line, but retain if none given.	if [[ $# -gt 0 ]]; then		unset NETIFS		declare -A NETIFS 		while [[ $# -gt 0 ]]; do			count=$((count + 1))			NETIFS[p$count]="$1"			TARGETS[$1]="local:"			shift		done	fifi ############################################################################### Network interfaces configuration

Lines 1–500 of 2313.