1462 lines · 27.3 KB · Shell
RawDownload
#!/bin/bash# SPDX-License-Identifier: GPL-2.0 ############################################################################### Defines # Can be overridden by the configuration file.PING=${PING:=ping}PING6=${PING6:=ping6}MZ=${MZ:=mausezahn}ARPING=${ARPING:=arping}TEAMD=${TEAMD:=teamd}WAIT_TIME=${WAIT_TIME:=5}PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no}NETIF_TYPE=${NETIF_TYPE:=veth}NETIF_CREATE=${NETIF_CREATE:=yes}MCD=${MCD:=smcrouted}MC_CLI=${MC_CLI:=smcroutectl}PING_TIMEOUT=${PING_TIMEOUT:=5}WAIT_TIMEOUT=${WAIT_TIMEOUT:=20}INTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600} relative_path="${BASH_SOURCE%/*}"if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then	relative_path="."fi if [[ -f $relative_path/forwarding.config ]]; then	source "$relative_path/forwarding.config"fi ############################################################################### Sanity checks check_tc_version(){	tc -j &> /dev/null	if [[ $? -ne 0 ]]; then		echo "SKIP: iproute2 too old; tc is missing JSON support"		exit 1	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 1	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 1	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 1	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 1	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 1	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 1	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 1	fi} if [[ "$(id -u)" -ne 0 ]]; then	echo "SKIP: need root privileges"	exit 0fi 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 1	fi} require_command jqrequire_command $MZ if [[ ! -v NUM_NETIFS ]]; then	echo "SKIP: importer does not define \"NUM_NETIFS\""	exit 1fi ############################################################################### 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 create_netif_veth(){	local i 	for ((i = 1; i <= NUM_NETIFS; ++i)); do		local j=$((i+1)) 		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} if [[ "$NETIF_CREATE" = "yes" ]]; then	create_netiffi 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 1	fidone ############################################################################### Helpers # Exit status to return at the end. Set in case one of the tests fails.EXIT_STATUS=0# Per-test return value. Clear at the beginning of each test.RET=0 check_err(){	local err=$1	local msg=$2 	if [[ $RET -eq 0 && $err -ne 0 ]]; then		RET=$err		retmsg=$msg	fi} check_fail(){	local err=$1	local msg=$2 	if [[ $RET -eq 0 && $err -eq 0 ]]; then		RET=1		retmsg=$msg	fi} check_err_fail(){	local should_fail=$1; shift	local err=$1; shift	local what=$1; shift 	if ((should_fail)); then		check_fail $err "$what succeeded, but should have failed"	else		check_err $err "$what failed"	fi} log_test(){	local test_name=$1	local opt_str=$2 	if [[ $# -eq 2 ]]; then		opt_str="($opt_str)"	fi 	if [[ $RET -ne 0 ]]; then		EXIT_STATUS=1		printf "TEST: %-60s  [FAIL]\n" "$test_name $opt_str"		if [[ ! -z "$retmsg" ]]; then			printf "\t%s\n" "$retmsg"		fi		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then			echo "Hit enter to continue, 'q' to quit"			read a			[ "$a" = "q" ] && exit 1		fi		return 1	fi 	printf "TEST: %-60s  [ OK ]\n" "$test_name $opt_str"	return 0} log_info(){	local msg=$1 	echo "INFO: $msg"} busywait(){	local timeout=$1; shift 	local start_time="$(date -u +%s%3N)"	while true	do		local out		out=$("$@")		local ret=$?		if ((!ret)); then			echo -n "$out"			return 0		fi 		local current_time="$(date -u +%s%3N)"		if ((current_time - start_time > timeout)); then			echo -n "$out"			return 1		fi	done} 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} until_counter_is(){	local expr=$1; shift	local current=$("$@") 	echo $((current))	((current $expr))} busywait_for_counter(){	local timeout=$1; shift	local delta=$1; shift 	local base=$("$@")	busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"} setup_wait_dev(){	local dev=$1; shift	local wait_time=${1:-$WAIT_TIME}; shift 	setup_wait_dev_with_timeout "$dev" $INTERFACE_TIMEOUT $wait_time 	if (($?)); then		check_err 1		log_test setup_wait_dev ": Interface $dev does not come up."		exit 1	fi} setup_wait_dev_with_timeout(){	local dev=$1; shift	local max_iterations=${1:-$WAIT_TIMEOUT}; shift	local wait_time=${1:-$WAIT_TIME}; shift	local i 	for ((i = 1; i <= $max_iterations; ++i)); do		ip link show dev $dev up \			| grep 'state UP' &> /dev/null		if [[ $? -ne 0 ]]; then			sleep 1		else			sleep $wait_time			return 0		fi	done 	return 1} setup_wait(){	local num_netifs=${1:-$NUM_NETIFS}	local i 	for ((i = 1; i <= num_netifs; ++i)); do		setup_wait_dev ${NETIFS[p$i]} 0	done 	# Make sure links are ready.	sleep $WAIT_TIME} cmd_jq(){	local cmd=$1	local jq_exp=$2	local jq_opts=$3	local ret	local output 	output="$($cmd)"	# it the command fails, return error right away	ret=$?	if [[ $ret -ne 0 ]]; then		return $ret	fi	output=$(echo $output | jq -r $jq_opts "$jq_exp")	ret=$?	if [[ $ret -ne 0 ]]; then		return $ret	fi	echo $output	# return success only in case of non-empty output	[ ! -z "$output" ]} lldpad_app_wait_set(){	local dev=$1; shift 	while lldptool -t -i $dev -V APP -c app | grep -Eq "pending|unknown"; do		echo "$dev: waiting for lldpad to push pending APP updates"		sleep 5	done} lldpad_app_wait_del(){	# Give lldpad a chance to push down the changes. If the device is downed	# too soon, the updates will be left pending. However, they will have	# been struck off the lldpad's DB already, so we won't be able to tell	# they are pending. Then on next test iteration this would cause	# weirdness as newly-added APP rules conflict with the old ones,	# sometimes getting stuck in an "unknown" state.	sleep 5} pre_cleanup(){	if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then		echo "Pausing before cleanup, hit any key to continue"		read	fi} vrf_prepare(){	ip -4 rule add pref 32765 table local	ip -4 rule del pref 0	ip -6 rule add pref 32765 table local	ip -6 rule del pref 0} vrf_cleanup(){	ip -6 rule add pref 0 table local	ip -6 rule del pref 32765	ip -4 rule add pref 0 table local	ip -4 rule del pref 32765} __last_tb_id=0declare -A __TB_IDS __vrf_td_id_assign(){

Lines 1–500 of 1462.