brintos

brintos / linux-shallow public Read only

0
0
Text · 77.5 KiB · 5f3c28f Raw
2697 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# This test is for checking IPv4 and IPv6 FIB behavior in response to5# different events.6source lib.sh7ret=08 9# all tests in this script. Can be overridden with -t option10TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \11       ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics \12       ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \13       ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \14       ipv4_mpath_list ipv6_mpath_list"15 16VERBOSE=017PAUSE_ON_FAIL=no18PAUSE=no19 20which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)21 22log_test()23{24	local rc=$125	local expected=$226	local msg="$3"27 28	if [ ${rc} -eq ${expected} ]; then29		printf "    TEST: %-60s  [ OK ]\n" "${msg}"30		nsuccess=$((nsuccess+1))31	else32		ret=133		nfail=$((nfail+1))34		printf "    TEST: %-60s  [FAIL]\n" "${msg}"35		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then36		echo37			echo "hit enter to continue, 'q' to quit"38			read a39			[ "$a" = "q" ] && exit 140		fi41	fi42 43	if [ "${PAUSE}" = "yes" ]; then44		echo45		echo "hit enter to continue, 'q' to quit"46		read a47		[ "$a" = "q" ] && exit 148	fi49}50 51setup()52{53	set -e54	setup_ns ns155	IP="$(which ip) -netns $ns1"56	NS_EXEC="$(which ip) netns exec $ns1"57	ip netns exec $ns1 sysctl -qw net.ipv4.ip_forward=158	ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.forwarding=159 60	$IP link add dummy0 type dummy61	$IP link set dev dummy0 up62	$IP address add 198.51.100.1/24 dev dummy063	$IP -6 address add 2001:db8:1::1/64 dev dummy064	set +e65 66}67 68cleanup()69{70	$IP link del dev dummy0 &> /dev/null71	cleanup_ns $ns1 $ns272}73 74get_linklocal()75{76	local dev=$177	local addr78 79	addr=$($IP -6 -br addr show dev ${dev} | \80	awk '{81		for (i = 3; i <= NF; ++i) {82			if ($i ~ /^fe80/)83				print $i84		}85	}'86	)87	addr=${addr/\/*}88 89	[ -z "$addr" ] && return 190 91	echo $addr92 93	return 094}95 96fib_unreg_unicast_test()97{98	echo99	echo "Single path route test"100 101	setup102 103	echo "    Start point"104	$IP route get fibmatch 198.51.100.2 &> /dev/null105	log_test $? 0 "IPv4 fibmatch"106	$IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null107	log_test $? 0 "IPv6 fibmatch"108 109	set -e110	$IP link del dev dummy0111	set +e112 113	echo "    Nexthop device deleted"114	$IP route get fibmatch 198.51.100.2 &> /dev/null115	log_test $? 2 "IPv4 fibmatch - no route"116	$IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null117	log_test $? 2 "IPv6 fibmatch - no route"118 119	cleanup120}121 122fib_unreg_multipath_test()123{124 125	echo126	echo "Multipath route test"127 128	setup129 130	set -e131	$IP link add dummy1 type dummy132	$IP link set dev dummy1 up133	$IP address add 192.0.2.1/24 dev dummy1134	$IP -6 address add 2001:db8:2::1/64 dev dummy1135 136	$IP route add 203.0.113.0/24 \137		nexthop via 198.51.100.2 dev dummy0 \138		nexthop via 192.0.2.2 dev dummy1139	$IP -6 route add 2001:db8:3::/64 \140		nexthop via 2001:db8:1::2 dev dummy0 \141		nexthop via 2001:db8:2::2 dev dummy1142	set +e143 144	echo "    Start point"145	$IP route get fibmatch 203.0.113.1 &> /dev/null146	log_test $? 0 "IPv4 fibmatch"147	$IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null148	log_test $? 0 "IPv6 fibmatch"149 150	set -e151	$IP link del dev dummy0152	set +e153 154	echo "    One nexthop device deleted"155	$IP route get fibmatch 203.0.113.1 &> /dev/null156	log_test $? 2 "IPv4 - multipath route removed on delete"157 158	$IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null159	# In IPv6 we do not flush the entire multipath route.160	log_test $? 0 "IPv6 - multipath down to single path"161 162	set -e163	$IP link del dev dummy1164	set +e165 166	echo "    Second nexthop device deleted"167	$IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null168	log_test $? 2 "IPv6 - no route"169 170	cleanup171}172 173fib_unreg_test()174{175	fib_unreg_unicast_test176	fib_unreg_multipath_test177}178 179fib_down_unicast_test()180{181	echo182	echo "Single path, admin down"183 184	setup185 186	echo "    Start point"187	$IP route get fibmatch 198.51.100.2 &> /dev/null188	log_test $? 0 "IPv4 fibmatch"189	$IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null190	log_test $? 0 "IPv6 fibmatch"191 192	set -e193	$IP link set dev dummy0 down194	set +e195 196	echo "    Route deleted on down"197	$IP route get fibmatch 198.51.100.2 &> /dev/null198	log_test $? 2 "IPv4 fibmatch"199	$IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null200	log_test $? 2 "IPv6 fibmatch"201 202	cleanup203}204 205fib_down_multipath_test_do()206{207	local down_dev=$1208	local up_dev=$2209 210	$IP route get fibmatch 203.0.113.1 \211		oif $down_dev &> /dev/null212	log_test $? 2 "IPv4 fibmatch on down device"213	$IP -6 route get fibmatch 2001:db8:3::1 \214		oif $down_dev &> /dev/null215	log_test $? 2 "IPv6 fibmatch on down device"216 217	$IP route get fibmatch 203.0.113.1 \218		oif $up_dev &> /dev/null219	log_test $? 0 "IPv4 fibmatch on up device"220	$IP -6 route get fibmatch 2001:db8:3::1 \221		oif $up_dev &> /dev/null222	log_test $? 0 "IPv6 fibmatch on up device"223 224	$IP route get fibmatch 203.0.113.1 | \225		grep $down_dev | grep -q "dead linkdown"226	log_test $? 0 "IPv4 flags on down device"227	$IP -6 route get fibmatch 2001:db8:3::1 | \228		grep $down_dev | grep -q "dead linkdown"229	log_test $? 0 "IPv6 flags on down device"230 231	$IP route get fibmatch 203.0.113.1 | \232		grep $up_dev | grep -q "dead linkdown"233	log_test $? 1 "IPv4 flags on up device"234	$IP -6 route get fibmatch 2001:db8:3::1 | \235		grep $up_dev | grep -q "dead linkdown"236	log_test $? 1 "IPv6 flags on up device"237}238 239fib_down_multipath_test()240{241	echo242	echo "Admin down multipath"243 244	setup245 246	set -e247	$IP link add dummy1 type dummy248	$IP link set dev dummy1 up249 250	$IP address add 192.0.2.1/24 dev dummy1251	$IP -6 address add 2001:db8:2::1/64 dev dummy1252 253	$IP route add 203.0.113.0/24 \254		nexthop via 198.51.100.2 dev dummy0 \255		nexthop via 192.0.2.2 dev dummy1256	$IP -6 route add 2001:db8:3::/64 \257		nexthop via 2001:db8:1::2 dev dummy0 \258		nexthop via 2001:db8:2::2 dev dummy1259	set +e260 261	echo "    Verify start point"262	$IP route get fibmatch 203.0.113.1 &> /dev/null263	log_test $? 0 "IPv4 fibmatch"264 265	$IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null266	log_test $? 0 "IPv6 fibmatch"267 268	set -e269	$IP link set dev dummy0 down270	set +e271 272	echo "    One device down, one up"273	fib_down_multipath_test_do "dummy0" "dummy1"274 275	set -e276	$IP link set dev dummy0 up277	$IP link set dev dummy1 down278	set +e279 280	echo "    Other device down and up"281	fib_down_multipath_test_do "dummy1" "dummy0"282 283	set -e284	$IP link set dev dummy0 down285	set +e286 287	echo "    Both devices down"288	$IP route get fibmatch 203.0.113.1 &> /dev/null289	log_test $? 2 "IPv4 fibmatch"290	$IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null291	log_test $? 2 "IPv6 fibmatch"292 293	$IP link del dev dummy1294	cleanup295}296 297fib_down_test()298{299	fib_down_unicast_test300	fib_down_multipath_test301}302 303# Local routes should not be affected when carrier changes.304fib_carrier_local_test()305{306	echo307	echo "Local carrier tests - single path"308 309	setup310 311	set -e312	$IP link set dev dummy0 carrier on313	set +e314 315	echo "    Start point"316	$IP route get fibmatch 198.51.100.1 &> /dev/null317	log_test $? 0 "IPv4 fibmatch"318	$IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null319	log_test $? 0 "IPv6 fibmatch"320 321	$IP route get fibmatch 198.51.100.1 | \322		grep -q "linkdown"323	log_test $? 1 "IPv4 - no linkdown flag"324	$IP -6 route get fibmatch 2001:db8:1::1 | \325		grep -q "linkdown"326	log_test $? 1 "IPv6 - no linkdown flag"327 328	set -e329	$IP link set dev dummy0 carrier off330	sleep 1331	set +e332 333	echo "    Carrier off on nexthop"334	$IP route get fibmatch 198.51.100.1 &> /dev/null335	log_test $? 0 "IPv4 fibmatch"336	$IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null337	log_test $? 0 "IPv6 fibmatch"338 339	$IP route get fibmatch 198.51.100.1 | \340		grep -q "linkdown"341	log_test $? 1 "IPv4 - linkdown flag set"342	$IP -6 route get fibmatch 2001:db8:1::1 | \343		grep -q "linkdown"344	log_test $? 1 "IPv6 - linkdown flag set"345 346	set -e347	$IP address add 192.0.2.1/24 dev dummy0348	$IP -6 address add 2001:db8:2::1/64 dev dummy0349	set +e350 351	echo "    Route to local address with carrier down"352	$IP route get fibmatch 192.0.2.1 &> /dev/null353	log_test $? 0 "IPv4 fibmatch"354	$IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null355	log_test $? 0 "IPv6 fibmatch"356 357	$IP route get fibmatch 192.0.2.1 | \358		grep -q "linkdown"359	log_test $? 1 "IPv4 linkdown flag set"360	$IP -6 route get fibmatch 2001:db8:2::1 | \361		grep -q "linkdown"362	log_test $? 1 "IPv6 linkdown flag set"363 364	cleanup365}366 367fib_carrier_unicast_test()368{369	ret=0370 371	echo372	echo "Single path route carrier test"373 374	setup375 376	set -e377	$IP link set dev dummy0 carrier on378	set +e379 380	echo "    Start point"381	$IP route get fibmatch 198.51.100.2 &> /dev/null382	log_test $? 0 "IPv4 fibmatch"383	$IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null384	log_test $? 0 "IPv6 fibmatch"385 386	$IP route get fibmatch 198.51.100.2 | \387		grep -q "linkdown"388	log_test $? 1 "IPv4 no linkdown flag"389	$IP -6 route get fibmatch 2001:db8:1::2 | \390		grep -q "linkdown"391	log_test $? 1 "IPv6 no linkdown flag"392 393	set -e394	$IP link set dev dummy0 carrier off395	sleep 1396	set +e397 398	echo "    Carrier down"399	$IP route get fibmatch 198.51.100.2 &> /dev/null400	log_test $? 0 "IPv4 fibmatch"401	$IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null402	log_test $? 0 "IPv6 fibmatch"403 404	$IP route get fibmatch 198.51.100.2 | \405		grep -q "linkdown"406	log_test $? 0 "IPv4 linkdown flag set"407	$IP -6 route get fibmatch 2001:db8:1::2 | \408		grep -q "linkdown"409	log_test $? 0 "IPv6 linkdown flag set"410 411	set -e412	$IP address add 192.0.2.1/24 dev dummy0413	$IP -6 address add 2001:db8:2::1/64 dev dummy0414	set +e415 416	echo "    Second address added with carrier down"417	$IP route get fibmatch 192.0.2.2 &> /dev/null418	log_test $? 0 "IPv4 fibmatch"419	$IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null420	log_test $? 0 "IPv6 fibmatch"421 422	$IP route get fibmatch 192.0.2.2 | \423		grep -q "linkdown"424	log_test $? 0 "IPv4 linkdown flag set"425	$IP -6 route get fibmatch 2001:db8:2::2 | \426		grep -q "linkdown"427	log_test $? 0 "IPv6 linkdown flag set"428 429	cleanup430}431 432fib_carrier_test()433{434	fib_carrier_local_test435	fib_carrier_unicast_test436}437 438fib_rp_filter_test()439{440	echo441	echo "IPv4 rp_filter tests"442 443	setup444 445	set -e446	setup_ns ns2447 448	$IP link add name veth1 type veth peer name veth2449	$IP link set dev veth2 netns $ns2450	$IP address add 192.0.2.1/24 dev veth1451	ip -netns $ns2 address add 192.0.2.1/24 dev veth2452	$IP link set dev veth1 up453	ip -netns $ns2 link set dev veth2 up454 455	$IP link set dev lo address 52:54:00:6a:c7:5e456	$IP link set dev veth1 address 52:54:00:6a:c7:5e457	ip -netns $ns2 link set dev lo address 52:54:00:6a:c7:5e458	ip -netns $ns2 link set dev veth2 address 52:54:00:6a:c7:5e459 460	# 1. (ns2) redirect lo's egress to veth2's egress461	ip netns exec $ns2 tc qdisc add dev lo parent root handle 1: fq_codel462	ip netns exec $ns2 tc filter add dev lo parent 1: protocol arp basic \463		action mirred egress redirect dev veth2464	ip netns exec $ns2 tc filter add dev lo parent 1: protocol ip basic \465		action mirred egress redirect dev veth2466 467	# 2. (ns1) redirect veth1's ingress to lo's ingress468	$NS_EXEC tc qdisc add dev veth1 ingress469	$NS_EXEC tc filter add dev veth1 ingress protocol arp basic \470		action mirred ingress redirect dev lo471	$NS_EXEC tc filter add dev veth1 ingress protocol ip basic \472		action mirred ingress redirect dev lo473 474	# 3. (ns1) redirect lo's egress to veth1's egress475	$NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel476	$NS_EXEC tc filter add dev lo parent 1: protocol arp basic \477		action mirred egress redirect dev veth1478	$NS_EXEC tc filter add dev lo parent 1: protocol ip basic \479		action mirred egress redirect dev veth1480 481	# 4. (ns2) redirect veth2's ingress to lo's ingress482	ip netns exec $ns2 tc qdisc add dev veth2 ingress483	ip netns exec $ns2 tc filter add dev veth2 ingress protocol arp basic \484		action mirred ingress redirect dev lo485	ip netns exec $ns2 tc filter add dev veth2 ingress protocol ip basic \486		action mirred ingress redirect dev lo487 488	$NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1489	$NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1490	$NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1491	ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1492	ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.accept_local=1493	ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1494	set +e495 496	run_cmd "ip netns exec $ns2 ping -w1 -c1 192.0.2.1"497	log_test $? 0 "rp_filter passes local packets"498 499	run_cmd "ip netns exec $ns2 ping -w1 -c1 127.0.0.1"500	log_test $? 0 "rp_filter passes loopback packets"501 502	cleanup503}504 505################################################################################506# Tests on nexthop spec507 508# run 'ip route add' with given spec509add_rt()510{511	local desc="$1"512	local erc=$2513	local vrf=$3514	local pfx=$4515	local gw=$5516	local dev=$6517	local cmd out rc518 519	[ "$vrf" = "-" ] && vrf="default"520	[ -n "$gw" ] && gw="via $gw"521	[ -n "$dev" ] && dev="dev $dev"522 523	cmd="$IP route add vrf $vrf $pfx $gw $dev"524	if [ "$VERBOSE" = "1" ]; then525		printf "\n    COMMAND: $cmd\n"526	fi527 528	out=$(eval $cmd 2>&1)529	rc=$?530	if [ "$VERBOSE" = "1" -a -n "$out" ]; then531		echo "    $out"532	fi533	log_test $rc $erc "$desc"534}535 536fib4_nexthop()537{538	echo539	echo "IPv4 nexthop tests"540 541	echo "<<< write me >>>"542}543 544fib6_nexthop()545{546	local lldummy=$(get_linklocal dummy0)547	local llv1=$(get_linklocal dummy0)548 549	if [ -z "$lldummy" ]; then550		echo "Failed to get linklocal address for dummy0"551		return 1552	fi553	if [ -z "$llv1" ]; then554		echo "Failed to get linklocal address for veth1"555		return 1556	fi557 558	echo559	echo "IPv6 nexthop tests"560 561	add_rt "Directly connected nexthop, unicast address" 0 \562		- 2001:db8:101::/64 2001:db8:1::2563	add_rt "Directly connected nexthop, unicast address with device" 0 \564		- 2001:db8:102::/64 2001:db8:1::2 "dummy0"565	add_rt "Gateway is linklocal address" 0 \566		- 2001:db8:103::1/64 $llv1 "veth0"567 568	# fails because LL address requires a device569	add_rt "Gateway is linklocal address, no device" 2 \570		- 2001:db8:104::1/64 $llv1571 572	# local address can not be a gateway573	add_rt "Gateway can not be local unicast address" 2 \574		- 2001:db8:105::/64 2001:db8:1::1575	add_rt "Gateway can not be local unicast address, with device" 2 \576		- 2001:db8:106::/64 2001:db8:1::1 "dummy0"577	add_rt "Gateway can not be a local linklocal address" 2 \578		- 2001:db8:107::1/64 $lldummy "dummy0"579 580	# VRF tests581	add_rt "Gateway can be local address in a VRF" 0 \582		- 2001:db8:108::/64 2001:db8:51::2583	add_rt "Gateway can be local address in a VRF, with device" 0 \584		- 2001:db8:109::/64 2001:db8:51::2 "veth0"585	add_rt "Gateway can be local linklocal address in a VRF" 0 \586		- 2001:db8:110::1/64 $llv1 "veth0"587 588	add_rt "Redirect to VRF lookup" 0 \589		- 2001:db8:111::/64 "" "red"590 591	add_rt "VRF route, gateway can be local address in default VRF" 0 \592		red 2001:db8:112::/64 2001:db8:51::1593 594	# local address in same VRF fails595	add_rt "VRF route, gateway can not be a local address" 2 \596		red 2001:db8:113::1/64 2001:db8:2::1597	add_rt "VRF route, gateway can not be a local addr with device" 2 \598		red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"599}600 601# Default VRF:602#   dummy0 - 198.51.100.1/24 2001:db8:1::1/64603#   veth0  - 192.0.2.1/24    2001:db8:51::1/64604#605# VRF red:606#   dummy1 - 192.168.2.1/24 2001:db8:2::1/64607#   veth1  - 192.0.2.2/24   2001:db8:51::2/64608#609#  [ dummy0   veth0 ]--[ veth1   dummy1 ]610 611fib_nexthop_test()612{613	setup614 615	set -e616 617	$IP -4 rule add pref 32765 table local618	$IP -4 rule del pref 0619	$IP -6 rule add pref 32765 table local620	$IP -6 rule del pref 0621 622	$IP link add red type vrf table 1623	$IP link set red up624	$IP -4 route add vrf red unreachable default metric 4278198272625	$IP -6 route add vrf red unreachable default metric 4278198272626 627	$IP link add veth0 type veth peer name veth1628	$IP link set dev veth0 up629	$IP address add 192.0.2.1/24 dev veth0630	$IP -6 address add 2001:db8:51::1/64 dev veth0631 632	$IP link set dev veth1 vrf red up633	$IP address add 192.0.2.2/24 dev veth1634	$IP -6 address add 2001:db8:51::2/64 dev veth1635 636	$IP link add dummy1 type dummy637	$IP link set dev dummy1 vrf red up638	$IP address add 192.168.2.1/24 dev dummy1639	$IP -6 address add 2001:db8:2::1/64 dev dummy1640	set +e641 642	sleep 1643	fib4_nexthop644	fib6_nexthop645 646	(647	$IP link del dev dummy1648	$IP link del veth0649	$IP link del red650	) 2>/dev/null651	cleanup652}653 654fib6_notify_test()655{656	setup657 658	echo659	echo "Fib6 info length calculation in route notify test"660	set -e661 662	for i in 10 20 30 40 50 60 70;663	do664		$IP link add dummy_$i type dummy665		$IP link set dev dummy_$i up666		$IP -6 address add 2001:$i::1/64 dev dummy_$i667	done668 669	$NS_EXEC ip monitor route &> errors.txt &670	sleep 2671 672	$IP -6 route add 2001::/64 \673                nexthop via 2001:10::2 dev dummy_10 \674                nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \675                nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \676                nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \677                nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \678                nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \679                nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70680 681	set +e682 683	err=`cat errors.txt |grep "Message too long"`684	if [ -z "$err" ];then685		ret=0686	else687		ret=1688	fi689 690	log_test $ret 0 "ipv6 route add notify"691 692	{ kill %% && wait %%; } 2>/dev/null693 694	#rm errors.txt695 696	cleanup &> /dev/null697}698 699 700fib_notify_test()701{702	setup703 704	echo705	echo "Fib4 info length calculation in route notify test"706 707	set -e708 709	for i in 10 20 30 40 50 60 70;710	do711		$IP link add dummy_$i type dummy712		$IP link set dev dummy_$i up713		$IP address add 20.20.$i.2/24 dev dummy_$i714	done715 716	$NS_EXEC ip monitor route &> errors.txt &717	sleep 2718 719        $IP route add 10.0.0.0/24 \720                nexthop via 20.20.10.1 dev dummy_10 \721                nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \722                nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \723                nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \724                nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \725                nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \726                nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70727 728	set +e729 730	err=`cat errors.txt |grep "Message too long"`731	if [ -z "$err" ];then732		ret=0733	else734		ret=1735	fi736 737	log_test $ret 0 "ipv4 route add notify"738 739	{ kill %% && wait %%; } 2>/dev/null740 741	rm  errors.txt742 743	cleanup &> /dev/null744}745 746# Create a new dummy_10 to remove all associated routes.747reset_dummy_10()748{749	$IP link del dev dummy_10750 751	$IP link add dummy_10 type dummy752	$IP link set dev dummy_10 up753	$IP -6 address add 2001:10::1/64 dev dummy_10754}755 756check_rt_num()757{758    local expected=$1759    local num=$2760 761    if [ $num -ne $expected ]; then762	echo "FAIL: Expected $expected routes, got $num"763	ret=1764    else765	ret=0766    fi767}768 769check_rt_num_clean()770{771    local expected=$1772    local num=$2773 774    if [ $num -ne $expected ]; then775	log_test 1 0 "expected $expected routes, got $num"776	set +e777	cleanup &> /dev/null778	return 1779    fi780    return 0781}782 783fib6_gc_test()784{785	setup786 787	echo788	echo "Fib6 garbage collection test"789	set -e790 791	EXPIRE=5792	GC_WAIT_TIME=$((EXPIRE * 2 + 2))793 794	# Check expiration of routes every $EXPIRE seconds (GC)795	$NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE796 797	$IP link add dummy_10 type dummy798	$IP link set dev dummy_10 up799	$IP -6 address add 2001:10::1/64 dev dummy_10800 801	$NS_EXEC sysctl -wq net.ipv6.route.flush=1802 803	# Temporary routes804	for i in $(seq 1 5); do805	    # Expire route after $EXPIRE seconds806	    $IP -6 route add 2001:20::$i \807		via 2001:10::2 dev dummy_10 expires $EXPIRE808	done809	sleep $GC_WAIT_TIME810	$NS_EXEC sysctl -wq net.ipv6.route.flush=1811	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)812	log_test $ret 0 "ipv6 route garbage collection"813 814	reset_dummy_10815 816	# Permanent routes817	for i in $(seq 1 5); do818	    $IP -6 route add 2001:30::$i \819		via 2001:10::2 dev dummy_10820	done821	# Temporary routes822	for i in $(seq 1 5); do823	    # Expire route after $EXPIRE seconds824	    $IP -6 route add 2001:20::$i \825		via 2001:10::2 dev dummy_10 expires $EXPIRE826	done827	# Wait for GC828	sleep $GC_WAIT_TIME829	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)830	log_test $ret 0 "ipv6 route garbage collection (with permanent routes)"831 832	reset_dummy_10833 834	# Permanent routes835	for i in $(seq 1 5); do836	    $IP -6 route add 2001:20::$i \837		via 2001:10::2 dev dummy_10838	done839	# Replace with temporary routes840	for i in $(seq 1 5); do841	    # Expire route after $EXPIRE seconds842	    $IP -6 route replace 2001:20::$i \843		via 2001:10::2 dev dummy_10 expires $EXPIRE844	done845	# Wait for GC846	sleep $GC_WAIT_TIME847	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)848	log_test $ret 0 "ipv6 route garbage collection (replace with expires)"849 850	reset_dummy_10851 852	# Temporary routes853	for i in $(seq 1 5); do854	    # Expire route after $EXPIRE seconds855	    $IP -6 route add 2001:20::$i \856		via 2001:10::2 dev dummy_10 expires $EXPIRE857	done858	# Replace with permanent routes859	for i in $(seq 1 5); do860	    $IP -6 route replace 2001:20::$i \861		via 2001:10::2 dev dummy_10862	done863	check_rt_num_clean 0 $($IP -6 route list |grep expires|wc -l) || return864 865	# Wait for GC866	sleep $GC_WAIT_TIME867	check_rt_num 5 $($IP -6 route list |grep -v expires|grep 2001:20::|wc -l)868	log_test $ret 0 "ipv6 route garbage collection (replace with permanent)"869 870	# ra6 is required for the next test. (ipv6toolkit)871	if [ ! -x "$(command -v ra6)" ]; then872	    echo "SKIP: ra6 not found."873	    set +e874	    cleanup &> /dev/null875	    return876	fi877 878	# Delete dummy_10 and remove all routes879	$IP link del dev dummy_10880 881	# Create a pair of veth devices to send a RA message from one882	# device to another.883	$IP link add veth1 type veth peer name veth2884	$IP link set dev veth1 up885	$IP link set dev veth2 up886	$IP -6 address add 2001:10::1/64 dev veth1 nodad887	$IP -6 address add 2001:10::2/64 dev veth2 nodad888 889	# Make veth1 ready to receive RA messages.890	$NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2891 892	# Send a RA message with a route from veth2 to veth1.893	$NS_EXEC ra6 -i veth2 -d 2001:10::1 -t $EXPIRE894 895	# Wait for the RA message.896	sleep 1897 898	# systemd may mess up the test.  You syould make sure that899	# systemd-networkd.service and systemd-networkd.socket are stopped.900	check_rt_num_clean 1 $($IP -6 route list|grep expires|wc -l) || return901 902	# Wait for GC903	sleep $GC_WAIT_TIME904	check_rt_num 0 $($IP -6 route list |grep expires|wc -l)905	log_test $ret 0 "ipv6 route garbage collection (RA message)"906 907	set +e908 909	cleanup &> /dev/null910}911 912fib_suppress_test()913{914	echo915	echo "FIB rule with suppress_prefixlength"916	setup917 918	$IP link add dummy1 type dummy919	$IP link set dummy1 up920	$IP -6 route add default dev dummy1921	$IP -6 rule add table main suppress_prefixlength 0922	ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1923	$IP -6 rule del table main suppress_prefixlength 0924	$IP link del dummy1925 926	# If we got here without crashing, we're good.927	log_test 0 0 "FIB rule suppress test"928 929	cleanup930}931 932################################################################################933# Tests on route add and replace934 935run_cmd()936{937	local cmd="$1"938	local out939	local stderr="2>/dev/null"940 941	if [ "$VERBOSE" = "1" ]; then942		printf "    COMMAND: $cmd\n"943		stderr=944	fi945 946	out=$(eval $cmd $stderr)947	rc=$?948	if [ "$VERBOSE" = "1" -a -n "$out" ]; then949		echo "    $out"950	fi951 952	[ "$VERBOSE" = "1" ] && echo953 954	return $rc955}956 957check_expected()958{959	local out="$1"960	local expected="$2"961	local rc=0962 963	[ "${out}" = "${expected}" ] && return 0964 965	if [ -z "${out}" ]; then966		if [ "$VERBOSE" = "1" ]; then967			printf "\nNo route entry found\n"968			printf "Expected:\n"969			printf "    ${expected}\n"970		fi971		return 1972	fi973 974	# tricky way to convert output to 1-line without ip's975	# messy '\'; this drops all extra white space976	out=$(echo ${out})977	if [ "${out}" != "${expected}" ]; then978		rc=1979		if [ "${VERBOSE}" = "1" ]; then980			printf "    Unexpected route entry. Have:\n"981			printf "        ${out}\n"982			printf "    Expected:\n"983			printf "        ${expected}\n\n"984		fi985	fi986 987	return $rc988}989 990# add route for a prefix, flushing any existing routes first991# expected to be the first step of a test992add_route6()993{994	local pfx="$1"995	local nh="$2"996	local out997 998	if [ "$VERBOSE" = "1" ]; then999		echo1000		echo "    ##################################################"1001		echo1002	fi1003 1004	run_cmd "$IP -6 ro flush ${pfx}"1005	[ $? -ne 0 ] && exit 11006 1007	out=$($IP -6 ro ls match ${pfx})1008	if [ -n "$out" ]; then1009		echo "Failed to flush routes for prefix used for tests."1010		exit 11011	fi1012 1013	run_cmd "$IP -6 ro add ${pfx} ${nh}"1014	if [ $? -ne 0 ]; then1015		echo "Failed to add initial route for test."1016		exit 11017	fi1018}1019 1020# add initial route - used in replace route tests1021add_initial_route6()1022{1023	add_route6 "2001:db8:104::/64" "$1"1024}1025 1026check_route6()1027{1028	local pfx1029	local expected="$1"1030	local out1031	local rc=01032 1033	set -- $expected1034	pfx=$11035 1036	out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')1037	check_expected "${out}" "${expected}"1038}1039 1040route_cleanup()1041{1042	$IP li del red 2>/dev/null1043	$IP li del dummy1 2>/dev/null1044	$IP li del veth1 2>/dev/null1045	$IP li del veth3 2>/dev/null1046 1047	cleanup &> /dev/null1048}1049 1050route_setup()1051{1052	route_cleanup1053	setup1054 1055	[ "${VERBOSE}" = "1" ] && set -x1056	set -e1057 1058	setup_ns ns21059	ip netns exec $ns2 sysctl -qw net.ipv4.ip_forward=11060	ip netns exec $ns2 sysctl -qw net.ipv6.conf.all.forwarding=11061 1062	$IP li add veth1 type veth peer name veth21063	$IP li add veth3 type veth peer name veth41064 1065	$IP li set veth1 up1066	$IP li set veth3 up1067	$IP li set veth2 netns $ns2 up1068	$IP li set veth4 netns $ns2 up1069	ip -netns $ns2 li add dummy1 type dummy1070	ip -netns $ns2 li set dummy1 up1071 1072	$IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad1073	$IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad1074	$IP addr add 172.16.101.1/24 dev veth11075	$IP addr add 172.16.103.1/24 dev veth31076 1077	ip -netns $ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad1078	ip -netns $ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad1079	ip -netns $ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad1080 1081	ip -netns $ns2 addr add 172.16.101.2/24 dev veth21082	ip -netns $ns2 addr add 172.16.103.2/24 dev veth41083	ip -netns $ns2 addr add 172.16.104.1/24 dev dummy11084 1085	set +e1086}1087 1088# assumption is that basic add of a single path route works1089# otherwise just adding an address on an interface is broken1090ipv6_rt_add()1091{1092	local rc1093 1094	echo1095	echo "IPv6 route add / append tests"1096 1097	# route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1098	add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1099	run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"1100	log_test $? 2 "Attempt to add duplicate route - gw"1101 1102	# route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1103	add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1104	run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"1105	log_test $? 2 "Attempt to add duplicate route - dev only"1106 1107	# route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1108	add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1109	run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"1110	log_test $? 2 "Attempt to add duplicate route - reject route"1111 1112	# route append with same prefix adds a new route1113	# - iproute2 sets NLM_F_CREATE | NLM_F_APPEND1114	add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1115	run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"1116	check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1117	log_test $? 0 "Append nexthop to existing route - gw"1118 1119	# insert mpath directly1120	add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1121	check_route6  "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1122	log_test $? 0 "Add multipath route"1123 1124	add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1125	run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1126	log_test $? 2 "Attempt to add duplicate multipath route"1127 1128	# insert of a second route without append but different metric1129	add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"1130	run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"1131	rc=$?1132	if [ $rc -eq 0 ]; then1133		run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"1134		rc=$?1135	fi1136	log_test $rc 0 "Route add with different metrics"1137 1138	run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"1139	rc=$?1140	if [ $rc -eq 0 ]; then1141		check_route6 "2001:db8:104::/64 via 2001:db8:103::3 dev veth3 metric 256 2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"1142		rc=$?1143	fi1144	log_test $rc 0 "Route delete with metric"1145}1146 1147ipv6_rt_replace_single()1148{1149	# single path with single path1150	#1151	add_initial_route6 "via 2001:db8:101::2"1152	run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"1153	check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"1154	log_test $? 0 "Single path with single path"1155 1156	# single path with multipath1157	#1158	add_initial_route6 "nexthop via 2001:db8:101::2"1159	run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"1160	check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1161	log_test $? 0 "Single path with multipath"1162 1163	# single path with single path using MULTIPATH attribute1164	#1165	add_initial_route6 "via 2001:db8:101::2"1166	run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"1167	check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"1168	log_test $? 0 "Single path with single path via multipath attribute"1169 1170	# route replace fails - invalid nexthop1171	add_initial_route6 "via 2001:db8:101::2"1172	run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"1173	if [ $? -eq 0 ]; then1174		# previous command is expected to fail so if it returns 01175		# that means the test failed.1176		log_test 0 1 "Invalid nexthop"1177	else1178		check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"1179		log_test $? 0 "Invalid nexthop"1180	fi1181 1182	# replace non-existent route1183	# - note use of change versus replace since ip adds NLM_F_CREATE1184	#   for replace1185	add_initial_route6 "via 2001:db8:101::2"1186	run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"1187	log_test $? 2 "Single path - replace of non-existent route"1188}1189 1190ipv6_rt_replace_mpath()1191{1192	# multipath with multipath1193	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1194	run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"1195	check_route6  "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::3 dev veth3 weight 1"1196	log_test $? 0 "Multipath with multipath"1197 1198	# multipath with single1199	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1200	run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"1201	check_route6  "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"1202	log_test $? 0 "Multipath with single path"1203 1204	# multipath with single1205	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1206	run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"1207	check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"1208	log_test $? 0 "Multipath with single path via multipath attribute"1209 1210	# multipath with dev-only1211	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1212	run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"1213	check_route6 "2001:db8:104::/64 dev veth1 metric 1024"1214	log_test $? 0 "Multipath with dev-only"1215 1216	# route replace fails - invalid nexthop 11217	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1218	run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"1219	check_route6  "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1220	log_test $? 0 "Multipath - invalid first nexthop"1221 1222	# route replace fails - invalid nexthop 21223	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1224	run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"1225	check_route6  "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1226	log_test $? 0 "Multipath - invalid second nexthop"1227 1228	# multipath non-existent route1229	add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1230	run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"1231	log_test $? 2 "Multipath - replace of non-existent route"1232}1233 1234ipv6_rt_replace()1235{1236	echo1237	echo "IPv6 route replace tests"1238 1239	ipv6_rt_replace_single1240	ipv6_rt_replace_mpath1241}1242 1243ipv6_rt_dsfield()1244{1245	echo1246	echo "IPv6 route with dsfield tests"1247 1248	run_cmd "$IP -6 route flush 2001:db8:102::/64"1249 1250	# IPv6 doesn't support routing based on dsfield1251	run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"1252	log_test $? 2 "Reject route with dsfield"1253}1254 1255ipv6_route_test()1256{1257	route_setup1258 1259	ipv6_rt_add1260	ipv6_rt_replace1261	ipv6_rt_dsfield1262 1263	route_cleanup1264}1265 1266ip_addr_metric_check()1267{1268	ip addr help 2>&1 | grep -q metric1269	if [ $? -ne 0 ]; then1270		echo "iproute2 command does not support metric for addresses. Skipping test"1271		return 11272	fi1273 1274	return 01275}1276 1277ipv6_addr_metric_test()1278{1279	local rc1280 1281	echo1282	echo "IPv6 prefix route tests"1283 1284	ip_addr_metric_check || return 11285 1286	setup1287 1288	set -e1289	$IP li add dummy1 type dummy1290	$IP li add dummy2 type dummy1291	$IP li set dummy1 up1292	$IP li set dummy2 up1293 1294	# default entry is metric 2561295	run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"1296	run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"1297	set +e1298 1299	check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"1300	log_test $? 0 "Default metric"1301 1302	set -e1303	run_cmd "$IP -6 addr flush dev dummy1"1304	run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"1305	set +e1306 1307	check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"1308	log_test $? 0 "User specified metric on first device"1309 1310	set -e1311	run_cmd "$IP -6 addr flush dev dummy2"1312	run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"1313	set +e1314 1315	check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"1316	log_test $? 0 "User specified metric on second device"1317 1318	run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"1319	rc=$?1320	if [ $rc -eq 0 ]; then1321		check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"1322		rc=$?1323	fi1324	log_test $rc 0 "Delete of address on first device"1325 1326	run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"1327	rc=$?1328	if [ $rc -eq 0 ]; then1329		check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"1330		rc=$?1331	fi1332	log_test $rc 0 "Modify metric of address"1333 1334	# verify prefix route removed on down1335	run_cmd "ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"1336	run_cmd "$IP li set dev dummy2 down"1337	rc=$?1338	if [ $rc -eq 0 ]; then1339		out=$($IP -6 ro ls match 2001:db8:104::/64)1340		check_expected "${out}" ""1341		rc=$?1342	fi1343	log_test $rc 0 "Prefix route removed on link down"1344 1345	# verify prefix route re-inserted with assigned metric1346	run_cmd "$IP li set dev dummy2 up"1347	rc=$?1348	if [ $rc -eq 0 ]; then1349		check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"1350		rc=$?1351	fi1352	log_test $rc 0 "Prefix route with metric on link up"1353 1354	# verify peer metric added correctly1355	set -e1356	run_cmd "$IP -6 addr flush dev dummy2"1357	run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"1358	set +e1359 1360	check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"1361	log_test $? 0 "Set metric with peer route on local side"1362	check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"1363	log_test $? 0 "Set metric with peer route on peer side"1364 1365	set -e1366	run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"1367	set +e1368 1369	check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"1370	log_test $? 0 "Modify metric and peer address on local side"1371	check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"1372	log_test $? 0 "Modify metric and peer address on peer side"1373 1374	$IP li del dummy11375	$IP li del dummy21376	cleanup1377}1378 1379ipv6_route_metrics_test()1380{1381	local rc1382 1383	echo1384	echo "IPv6 routes with metrics"1385 1386	route_setup1387 1388	#1389	# single path with metrics1390	#1391	run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"1392	rc=$?1393	if [ $rc -eq 0 ]; then1394		check_route6  "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"1395		rc=$?1396	fi1397	log_test $rc 0 "Single path route with mtu metric"1398 1399 1400	#1401	# multipath via separate routes with metrics1402	#1403	run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"1404	run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"1405	rc=$?1406	if [ $rc -eq 0 ]; then1407		check_route6 "2001:db8:112::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1408		rc=$?1409	fi1410	log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"1411 1412	# second route is coalesced to first to make a multipath route.1413	# MTU of the second path is hidden from display!1414	run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"1415	run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"1416	rc=$?1417	if [ $rc -eq 0 ]; then1418		check_route6 "2001:db8:113::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1419		rc=$?1420	fi1421	log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"1422 1423	run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"1424	if [ $? -eq 0 ]; then1425		check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"1426		log_test $? 0 "    MTU of second leg"1427	fi1428 1429	#1430	# multipath with metrics1431	#1432	run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"1433	rc=$?1434	if [ $rc -eq 0 ]; then1435		check_route6  "2001:db8:115::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"1436		rc=$?1437	fi1438	log_test $rc 0 "Multipath route with mtu metric"1439 1440	$IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 13001441	run_cmd "ip netns exec $ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"1442	log_test $? 0 "Using route with mtu metric"1443 1444	run_cmd "$IP -6 ro add 2001:db8:114::/64 via  2001:db8:101::2  congctl lock foo"1445	log_test $? 2 "Invalid metric (fails metric_convert)"1446 1447	route_cleanup1448}1449 1450# add route for a prefix, flushing any existing routes first1451# expected to be the first step of a test1452add_route()1453{1454	local pfx="$1"1455	local nh="$2"1456	local out1457 1458	if [ "$VERBOSE" = "1" ]; then1459		echo1460		echo "    ##################################################"1461		echo1462	fi1463 1464	run_cmd "$IP ro flush ${pfx}"1465	[ $? -ne 0 ] && exit 11466 1467	out=$($IP ro ls match ${pfx})1468	if [ -n "$out" ]; then1469		echo "Failed to flush routes for prefix used for tests."1470		exit 11471	fi1472 1473	run_cmd "$IP ro add ${pfx} ${nh}"1474	if [ $? -ne 0 ]; then1475		echo "Failed to add initial route for test."1476		exit 11477	fi1478}1479 1480# add initial route - used in replace route tests1481add_initial_route()1482{1483	add_route "172.16.104.0/24" "$1"1484}1485 1486check_route()1487{1488	local pfx1489	local expected="$1"1490	local out1491 1492	set -- $expected1493	pfx=$11494	[ "${pfx}" = "unreachable" ] && pfx=$21495 1496	out=$($IP ro ls match ${pfx})1497	check_expected "${out}" "${expected}"1498}1499 1500# assumption is that basic add of a single path route works1501# otherwise just adding an address on an interface is broken1502ipv4_rt_add()1503{1504	local rc1505 1506	echo1507	echo "IPv4 route add / append tests"1508 1509	# route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1510	add_route "172.16.104.0/24" "via 172.16.101.2"1511	run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"1512	log_test $? 2 "Attempt to add duplicate route - gw"1513 1514	# route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1515	add_route "172.16.104.0/24" "via 172.16.101.2"1516	run_cmd "$IP ro add 172.16.104.0/24 dev veth3"1517	log_test $? 2 "Attempt to add duplicate route - dev only"1518 1519	# route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL1520	add_route "172.16.104.0/24" "via 172.16.101.2"1521	run_cmd "$IP ro add unreachable 172.16.104.0/24"1522	log_test $? 2 "Attempt to add duplicate route - reject route"1523 1524	# iproute2 prepend only sets NLM_F_CREATE1525	# - adds a new route; does NOT convert existing route to ECMP1526	add_route "172.16.104.0/24" "via 172.16.101.2"1527	run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"1528	check_route "172.16.104.0/24 via 172.16.103.2 dev veth3 172.16.104.0/24 via 172.16.101.2 dev veth1"1529	log_test $? 0 "Add new nexthop for existing prefix"1530 1531	# route append with same prefix adds a new route1532	# - iproute2 sets NLM_F_CREATE | NLM_F_APPEND1533	add_route "172.16.104.0/24" "via 172.16.101.2"1534	run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"1535	check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.2 dev veth3"1536	log_test $? 0 "Append nexthop to existing route - gw"1537 1538	add_route "172.16.104.0/24" "via 172.16.101.2"1539	run_cmd "$IP ro append 172.16.104.0/24 dev veth3"1540	check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"1541	log_test $? 0 "Append nexthop to existing route - dev only"1542 1543	add_route "172.16.104.0/24" "via 172.16.101.2"1544	run_cmd "$IP ro append unreachable 172.16.104.0/24"1545	check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"1546	log_test $? 0 "Append nexthop to existing route - reject route"1547 1548	run_cmd "$IP ro flush 172.16.104.0/24"1549	run_cmd "$IP ro add unreachable 172.16.104.0/24"1550	run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"1551	check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"1552	log_test $? 0 "Append nexthop to existing reject route - gw"1553 1554	run_cmd "$IP ro flush 172.16.104.0/24"1555	run_cmd "$IP ro add unreachable 172.16.104.0/24"1556	run_cmd "$IP ro append 172.16.104.0/24 dev veth3"1557	check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"1558	log_test $? 0 "Append nexthop to existing reject route - dev only"1559 1560	# insert mpath directly1561	add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1562	check_route  "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"1563	log_test $? 0 "add multipath route"1564 1565	add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1566	run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"1567	log_test $? 2 "Attempt to add duplicate multipath route"1568 1569	# insert of a second route without append but different metric1570	add_route "172.16.104.0/24" "via 172.16.101.2"1571	run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"1572	rc=$?1573	if [ $rc -eq 0 ]; then1574		run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"1575		rc=$?1576	fi1577	log_test $rc 0 "Route add with different metrics"1578 1579	run_cmd "$IP ro del 172.16.104.0/24 metric 512"1580	rc=$?1581	if [ $rc -eq 0 ]; then1582		check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.3 dev veth3 metric 256"1583		rc=$?1584	fi1585	log_test $rc 0 "Route delete with metric"1586}1587 1588ipv4_rt_replace_single()1589{1590	# single path with single path1591	#1592	add_initial_route "via 172.16.101.2"1593	run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"1594	check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"1595	log_test $? 0 "Single path with single path"1596 1597	# single path with multipath1598	#1599	add_initial_route "nexthop via 172.16.101.2"1600	run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"1601	check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"1602	log_test $? 0 "Single path with multipath"1603 1604	# single path with reject1605	#1606	add_initial_route "nexthop via 172.16.101.2"1607	run_cmd "$IP ro replace unreachable 172.16.104.0/24"1608	check_route "unreachable 172.16.104.0/24"1609	log_test $? 0 "Single path with reject route"1610 1611	# single path with single path using MULTIPATH attribute1612	#1613	add_initial_route "via 172.16.101.2"1614	run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"1615	check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"1616	log_test $? 0 "Single path with single path via multipath attribute"1617 1618	# route replace fails - invalid nexthop1619	add_initial_route "via 172.16.101.2"1620	run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"1621	if [ $? -eq 0 ]; then1622		# previous command is expected to fail so if it returns 01623		# that means the test failed.1624		log_test 0 1 "Invalid nexthop"1625	else1626		check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"1627		log_test $? 0 "Invalid nexthop"1628	fi1629 1630	# replace non-existent route1631	# - note use of change versus replace since ip adds NLM_F_CREATE1632	#   for replace1633	add_initial_route "via 172.16.101.2"1634	run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"1635	log_test $? 2 "Single path - replace of non-existent route"1636}1637 1638ipv4_rt_replace_mpath()1639{1640	# multipath with multipath1641	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1642	run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"1643	check_route  "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.3 dev veth3 weight 1"1644	log_test $? 0 "Multipath with multipath"1645 1646	# multipath with single1647	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1648	run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"1649	check_route  "172.16.104.0/24 via 172.16.101.3 dev veth1"1650	log_test $? 0 "Multipath with single path"1651 1652	# multipath with single1653	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1654	run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"1655	check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"1656	log_test $? 0 "Multipath with single path via multipath attribute"1657 1658	# multipath with reject1659	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1660	run_cmd "$IP ro replace unreachable 172.16.104.0/24"1661	check_route "unreachable 172.16.104.0/24"1662	log_test $? 0 "Multipath with reject route"1663 1664	# route replace fails - invalid nexthop 11665	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1666	run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"1667	check_route  "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"1668	log_test $? 0 "Multipath - invalid first nexthop"1669 1670	# route replace fails - invalid nexthop 21671	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1672	run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"1673	check_route  "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"1674	log_test $? 0 "Multipath - invalid second nexthop"1675 1676	# multipath non-existent route1677	add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"1678	run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"1679	log_test $? 2 "Multipath - replace of non-existent route"1680}1681 1682ipv4_rt_replace()1683{1684	echo1685	echo "IPv4 route replace tests"1686 1687	ipv4_rt_replace_single1688	ipv4_rt_replace_mpath1689}1690 1691# checks that cached input route on VRF port is deleted1692# when VRF is deleted1693ipv4_local_rt_cache()1694{1695	run_cmd "ip addr add 10.0.0.1/32 dev lo"1696	run_cmd "setup_ns test-ns"1697	run_cmd "ip link add veth-outside type veth peer name veth-inside"1698	run_cmd "ip link add vrf-100 type vrf table 1100"1699	run_cmd "ip link set veth-outside master vrf-100"1700	run_cmd "ip link set veth-inside netns $test-ns"1701	run_cmd "ip link set veth-outside up"1702	run_cmd "ip link set vrf-100 up"1703	run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"1704	run_cmd "ip netns exec $test-ns ip link set veth-inside up"1705	run_cmd "ip netns exec $test-ns ip addr add 10.1.1.1/32 dev veth-inside"1706	run_cmd "ip netns exec $test-ns ip route add 10.0.0.1/32 dev veth-inside"1707	run_cmd "ip netns exec $test-ns ip route add default via 10.0.0.1"1708	run_cmd "ip netns exec $test-ns ping 10.0.0.1 -c 1 -i 1"1709	run_cmd "ip link delete vrf-100"1710 1711	# if we do not hang test is a success1712	log_test $? 0 "Cached route removed from VRF port device"1713}1714 1715ipv4_rt_dsfield()1716{1717	echo1718	echo "IPv4 route with dsfield tests"1719 1720	run_cmd "$IP route flush 172.16.102.0/24"1721 1722	# New routes should reject dsfield options that interfere with ECN1723	run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"1724	log_test $? 2 "Reject route with dsfield 0x01"1725 1726	run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"1727	log_test $? 2 "Reject route with dsfield 0x02"1728 1729	run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"1730	log_test $? 2 "Reject route with dsfield 0x03"1731 1732	# A generic route that doesn't take DSCP into account1733	run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"1734 1735	# A more specific route for DSCP 0x101736	run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"1737 1738	# DSCP 0x10 should match the specific route, no matter the ECN bits1739	$IP route get fibmatch 172.16.102.1 dsfield 0x10 | \1740		grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1741	log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"1742 1743	$IP route get fibmatch 172.16.102.1 dsfield 0x11 | \1744		grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1745	log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"1746 1747	$IP route get fibmatch 172.16.102.1 dsfield 0x12 | \1748		grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1749	log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"1750 1751	$IP route get fibmatch 172.16.102.1 dsfield 0x13 | \1752		grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"1753	log_test $? 0 "IPv4 route with DSCP and ECN:CE"1754 1755	# Unknown DSCP should match the generic route, no matter the ECN bits1756	$IP route get fibmatch 172.16.102.1 dsfield 0x14 | \1757		grep -q "172.16.102.0/24 via 172.16.101.2"1758	log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"1759 1760	$IP route get fibmatch 172.16.102.1 dsfield 0x15 | \1761		grep -q "172.16.102.0/24 via 172.16.101.2"1762	log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"1763 1764	$IP route get fibmatch 172.16.102.1 dsfield 0x16 | \1765		grep -q "172.16.102.0/24 via 172.16.101.2"1766	log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"1767 1768	$IP route get fibmatch 172.16.102.1 dsfield 0x17 | \1769		grep -q "172.16.102.0/24 via 172.16.101.2"1770	log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"1771 1772	# Null DSCP should match the generic route, no matter the ECN bits1773	$IP route get fibmatch 172.16.102.1 dsfield 0x00 | \1774		grep -q "172.16.102.0/24 via 172.16.101.2"1775	log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"1776 1777	$IP route get fibmatch 172.16.102.1 dsfield 0x01 | \1778		grep -q "172.16.102.0/24 via 172.16.101.2"1779	log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"1780 1781	$IP route get fibmatch 172.16.102.1 dsfield 0x02 | \1782		grep -q "172.16.102.0/24 via 172.16.101.2"1783	log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"1784 1785	$IP route get fibmatch 172.16.102.1 dsfield 0x03 | \1786		grep -q "172.16.102.0/24 via 172.16.101.2"1787	log_test $? 0 "IPv4 route with no DSCP and ECN:CE"1788}1789 1790ipv4_route_test()1791{1792	route_setup1793 1794	ipv4_rt_add1795	ipv4_rt_replace1796	ipv4_local_rt_cache1797	ipv4_rt_dsfield1798 1799	route_cleanup1800}1801 1802ipv4_addr_metric_test()1803{1804	local rc1805 1806	echo1807	echo "IPv4 prefix route tests"1808 1809	ip_addr_metric_check || return 11810 1811	setup1812 1813	set -e1814	$IP li add dummy1 type dummy1815	$IP li add dummy2 type dummy1816	$IP li set dummy1 up1817	$IP li set dummy2 up1818 1819	# default entry is metric 2561820	run_cmd "$IP addr add dev dummy1 172.16.104.1/24"1821	run_cmd "$IP addr add dev dummy2 172.16.104.2/24"1822	set +e1823 1824	check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2"1825	log_test $? 0 "Default metric"1826 1827	set -e1828	run_cmd "$IP addr flush dev dummy1"1829	run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"1830	set +e1831 1832	check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257"1833	log_test $? 0 "User specified metric on first device"1834 1835	set -e1836	run_cmd "$IP addr flush dev dummy2"1837	run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"1838	set +e1839 1840	check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"1841	log_test $? 0 "User specified metric on second device"1842 1843	run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"1844	rc=$?1845	if [ $rc -eq 0 ]; then1846		check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"1847		rc=$?1848	fi1849	log_test $rc 0 "Delete of address on first device"1850 1851	run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"1852	rc=$?1853	if [ $rc -eq 0 ]; then1854		check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"1855		rc=$?1856	fi1857	log_test $rc 0 "Modify metric of address"1858 1859	# verify prefix route removed on down1860	run_cmd "$IP li set dev dummy2 down"1861	rc=$?1862	if [ $rc -eq 0 ]; then1863		out=$($IP ro ls match 172.16.104.0/24)1864		check_expected "${out}" ""1865		rc=$?1866	fi1867	log_test $rc 0 "Prefix route removed on link down"1868 1869	# verify prefix route re-inserted with assigned metric1870	run_cmd "$IP li set dev dummy2 up"1871	rc=$?1872	if [ $rc -eq 0 ]; then1873		check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"1874		rc=$?1875	fi1876	log_test $rc 0 "Prefix route with metric on link up"1877 1878	# explicitly check for metric changes on edge scenarios1879	run_cmd "$IP addr flush dev dummy2"1880	run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"1881	run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"1882	rc=$?1883	if [ $rc -eq 0 ]; then1884		check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"1885		rc=$?1886	fi1887	log_test $rc 0 "Modify metric of .0/24 address"1888 1889	run_cmd "$IP addr flush dev dummy2"1890	run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"1891	rc=$?1892	if [ $rc -eq 0 ]; then1893		check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"1894		rc=$?1895	fi1896	log_test $rc 0 "Set metric of address with peer route"1897 1898	run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"1899	rc=$?1900	if [ $rc -eq 0 ]; then1901		check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"1902		rc=$?1903	fi1904	log_test $rc 0 "Modify metric and peer address for peer route"1905 1906	$IP li del dummy11907	$IP li del dummy21908	cleanup1909}1910 1911ipv4_route_metrics_test()1912{1913	local rc1914 1915	echo1916	echo "IPv4 route add / append tests"1917 1918	route_setup1919 1920	run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"1921	rc=$?1922	if [ $rc -eq 0 ]; then1923		check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"1924		rc=$?1925	fi1926	log_test $rc 0 "Single path route with mtu metric"1927 1928 1929	run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"1930	rc=$?1931	if [ $rc -eq 0 ]; then1932		check_route "172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"1933		rc=$?1934	fi1935	log_test $rc 0 "Multipath route with mtu metric"1936 1937	$IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 13001938	run_cmd "ip netns exec $ns1 ping -w1 -c1 -s 1500 172.16.104.1"1939	log_test $? 0 "Using route with mtu metric"1940 1941	run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"1942	log_test $? 2 "Invalid metric (fails metric_convert)"1943 1944	route_cleanup1945}1946 1947ipv4_del_addr_test()1948{1949	echo1950	echo "IPv4 delete address route tests"1951 1952	setup1953 1954	set -e1955	$IP li add dummy1 type dummy1956	$IP li set dummy1 up1957	$IP li add dummy2 type dummy1958	$IP li set dummy2 up1959	$IP li add red type vrf table 11111960	$IP li set red up1961	$IP ro add vrf red unreachable default1962	$IP li set dummy2 vrf red1963 1964	$IP addr add dev dummy1 172.16.104.1/241965	$IP addr add dev dummy1 172.16.104.11/241966	$IP addr add dev dummy1 172.16.104.12/241967	$IP addr add dev dummy1 172.16.104.13/241968	$IP addr add dev dummy2 172.16.104.1/241969	$IP addr add dev dummy2 172.16.104.11/241970	$IP addr add dev dummy2 172.16.104.12/241971	$IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.111972	$IP route add 172.16.106.0/24 dev lo src 172.16.104.121973	$IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.131974	$IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.111975	$IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.121976	set +e1977 1978	# removing address from device in vrf should only remove route from vrf table1979	echo "    Regular FIB info"1980 1981	$IP addr del dev dummy2 172.16.104.11/241982	$IP ro ls vrf red | grep -q 172.16.105.0/241983	log_test $? 1 "Route removed from VRF when source address deleted"1984 1985	$IP ro ls | grep -q 172.16.105.0/241986	log_test $? 0 "Route in default VRF not removed"1987 1988	$IP addr add dev dummy2 172.16.104.11/241989	$IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.111990 1991	$IP addr del dev dummy1 172.16.104.11/241992	$IP ro ls | grep -q 172.16.105.0/241993	log_test $? 1 "Route removed in default VRF when source address deleted"1994 1995	$IP ro ls vrf red | grep -q 172.16.105.0/241996	log_test $? 0 "Route in VRF is not removed by address delete"1997 1998	# removing address from device in vrf should only remove route from vrf1999	# table even when the associated fib info only differs in table ID2000	echo "    Identical FIB info with different table ID"2001 2002	$IP addr del dev dummy2 172.16.104.12/242003	$IP ro ls vrf red | grep -q 172.16.106.0/242004	log_test $? 1 "Route removed from VRF when source address deleted"2005 2006	$IP ro ls | grep -q 172.16.106.0/242007	log_test $? 0 "Route in default VRF not removed"2008 2009	$IP addr add dev dummy2 172.16.104.12/242010	$IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.122011 2012	$IP addr del dev dummy1 172.16.104.12/242013	$IP ro ls | grep -q 172.16.106.0/242014	log_test $? 1 "Route removed in default VRF when source address deleted"2015 2016	$IP ro ls vrf red | grep -q 172.16.106.0/242017	log_test $? 0 "Route in VRF is not removed by address delete"2018 2019	# removing address from device in default vrf should remove route from2020	# the default vrf even when route was inserted with a table ID of 0.2021	echo "    Table ID 0"2022 2023	$IP addr del dev dummy1 172.16.104.13/242024	$IP ro ls | grep -q 172.16.107.0/242025	log_test $? 1 "Route removed in default VRF when source address deleted"2026 2027	$IP li del dummy12028	$IP li del dummy22029	cleanup2030}2031 2032ipv6_del_addr_test()2033{2034	echo2035	echo "IPv6 delete address route tests"2036 2037	setup2038 2039	set -e2040	for i in $(seq 6); do2041		$IP li add dummy${i} up type dummy2042	done2043 2044	$IP li add red up type vrf table 11112045	$IP ro add vrf red unreachable default2046	for i in $(seq 4 6); do2047		$IP li set dummy${i} vrf red2048	done2049 2050	$IP addr add dev dummy1 fe80::1/1282051	$IP addr add dev dummy1 2001:db8:101::1/642052	$IP addr add dev dummy1 2001:db8:101::10/642053	$IP addr add dev dummy1 2001:db8:101::11/642054	$IP addr add dev dummy1 2001:db8:101::12/642055	$IP addr add dev dummy1 2001:db8:101::13/642056	$IP addr add dev dummy1 2001:db8:101::14/642057	$IP addr add dev dummy1 2001:db8:101::15/642058	$IP addr add dev dummy2 fe80::1/1282059	$IP addr add dev dummy2 2001:db8:101::1/642060	$IP addr add dev dummy2 2001:db8:101::11/642061	$IP addr add dev dummy3 fe80::1/1282062 2063	$IP addr add dev dummy4 2001:db8:101::1/642064	$IP addr add dev dummy4 2001:db8:101::10/642065	$IP addr add dev dummy4 2001:db8:101::11/642066	$IP addr add dev dummy4 2001:db8:101::12/642067	$IP addr add dev dummy4 2001:db8:101::13/642068	$IP addr add dev dummy4 2001:db8:101::14/642069	$IP addr add dev dummy5 2001:db8:101::1/642070	$IP addr add dev dummy5 2001:db8:101::11/642071 2072	# Single device using src address2073	$IP route add 2001:db8:110::/64 dev dummy3 src 2001:db8:101::102074	# Two devices with the same source address2075	$IP route add 2001:db8:111::/64 dev dummy3 src 2001:db8:101::112076	# VRF with single device using src address2077	$IP route add vrf red 2001:db8:110::/64 dev dummy6 src 2001:db8:101::102078	# VRF with two devices using src address2079	$IP route add vrf red 2001:db8:111::/64 dev dummy6 src 2001:db8:101::112080	# src address and nexthop dev in same VRF2081	$IP route add 2001:db8:112::/64 dev dummy3 src 2001:db8:101::122082	$IP route add vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::122083	# src address and nexthop device in different VRF2084	$IP route add 2001:db8:113::/64 dev lo src 2001:db8:101::132085	$IP route add vrf red 2001:db8:113::/64 dev lo src 2001:db8:101::132086	# table ID 02087	$IP route add table 0 2001:db8:115::/64 via 2001:db8:101::2 src 2001:db8:101::152088	# Link local source route2089	$IP route add 2001:db8:116::/64 dev dummy2 src fe80::12090	$IP route add 2001:db8:117::/64 dev dummy3 src fe80::12091	set +e2092 2093	echo "    Single device using src address"2094 2095	$IP addr del dev dummy1 2001:db8:101::10/642096	$IP -6 route show | grep -q "src 2001:db8:101::10 "2097	log_test $? 1 "Prefsrc removed when src address removed on other device"2098 2099	echo "    Two devices with the same source address"2100 2101	$IP addr del dev dummy1 2001:db8:101::11/642102	$IP -6 route show | grep -q "src 2001:db8:101::11 "2103	log_test $? 0 "Prefsrc not removed when src address exist on other device"2104 2105	$IP addr del dev dummy2 2001:db8:101::11/642106	$IP -6 route show | grep -q "src 2001:db8:101::11 "2107	log_test $? 1 "Prefsrc removed when src address removed on all devices"2108 2109	echo "    VRF with single device using src address"2110 2111	$IP addr del dev dummy4 2001:db8:101::10/642112	$IP -6 route show vrf red | grep -q "src 2001:db8:101::10 "2113	log_test $? 1 "Prefsrc removed when src address removed on other device"2114 2115	echo "    VRF with two devices using src address"2116 2117	$IP addr del dev dummy4 2001:db8:101::11/642118	$IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "2119	log_test $? 0 "Prefsrc not removed when src address exist on other device"2120 2121	$IP addr del dev dummy5 2001:db8:101::11/642122	$IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "2123	log_test $? 1 "Prefsrc removed when src address removed on all devices"2124 2125	echo "    src address and nexthop dev in same VRF"2126 2127	$IP addr del dev dummy4 2001:db8:101::12/642128	$IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "2129	log_test $? 1 "Prefsrc removed from VRF when source address deleted"2130	$IP -6 route show | grep -q " src 2001:db8:101::12 "2131	log_test $? 0 "Prefsrc in default VRF not removed"2132 2133	$IP addr add dev dummy4 2001:db8:101::12/642134	$IP route replace vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::122135	$IP addr del dev dummy1 2001:db8:101::12/642136	$IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "2137	log_test $? 0 "Prefsrc not removed from VRF when source address exist"2138	$IP -6 route show | grep -q " src 2001:db8:101::12 "2139	log_test $? 1 "Prefsrc in default VRF removed"2140 2141	echo "    src address and nexthop device in different VRF"2142 2143	$IP addr del dev dummy4 2001:db8:101::13/642144	$IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "2145	log_test $? 0 "Prefsrc not removed from VRF when nexthop dev in diff VRF"2146	$IP -6 route show | grep -q "src 2001:db8:101::13 "2147	log_test $? 0 "Prefsrc not removed in default VRF"2148 2149	$IP addr add dev dummy4 2001:db8:101::13/642150	$IP addr del dev dummy1 2001:db8:101::13/642151	$IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "2152	log_test $? 1 "Prefsrc removed from VRF when nexthop dev in diff VRF"2153	$IP -6 route show | grep -q "src 2001:db8:101::13 "2154	log_test $? 1 "Prefsrc removed in default VRF"2155 2156	echo "    Table ID 0"2157 2158	$IP addr del dev dummy1 2001:db8:101::15/642159	$IP -6 route show | grep -q "src 2001:db8:101::15"2160	log_test $? 1 "Prefsrc removed from default VRF when source address deleted"2161 2162	echo "    Link local source route"2163	$IP addr del dev dummy1 fe80::1/1282164	$IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"2165	log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"2166	$IP addr del dev dummy2 fe80::1/1282167	$IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"2168	log_test $? 1 "Prefsrc removed when delete ll addr"2169	$IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"2170	log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"2171	$IP addr add dev dummy1 fe80::1/1282172	$IP addr del dev dummy3 fe80::1/1282173	$IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"2174	log_test $? 1 "Prefsrc removed even ll addr still exist on other dev"2175 2176	for i in $(seq 6); do2177		$IP li del dummy${i}2178	done2179	cleanup2180}2181 2182ipv4_route_v6_gw_test()2183{2184	local rc2185 2186	echo2187	echo "IPv4 route with IPv6 gateway tests"2188 2189	route_setup2190	sleep 22191 2192	#2193	# single path route2194	#2195	run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"2196	rc=$?2197	log_test $rc 0 "Single path route with IPv6 gateway"2198	if [ $rc -eq 0 ]; then2199		check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"2200	fi2201 2202	run_cmd "ip netns exec $ns1 ping -w1 -c1 172.16.104.1"2203	log_test $rc 0 "Single path route with IPv6 gateway - ping"2204 2205	run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"2206	rc=$?2207	log_test $rc 0 "Single path route delete"2208	if [ $rc -eq 0 ]; then2209		check_route "172.16.112.0/24"2210	fi2211 2212	#2213	# multipath - v6 then v42214	#2215	run_cmd "$IP ro add 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"2216	rc=$?2217	log_test $rc 0 "Multipath route add - v6 nexthop then v4"2218	if [ $rc -eq 0 ]; then2219		check_route "172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"2220	fi2221 2222	run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"2223	log_test $? 2 "    Multipath route delete - nexthops in wrong order"2224 2225	run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"2226	log_test $? 0 "    Multipath route delete exact match"2227 2228	#2229	# multipath - v4 then v62230	#2231	run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"2232	rc=$?2233	log_test $rc 0 "Multipath route add - v4 nexthop then v6"2234	if [ $rc -eq 0 ]; then2235		check_route "172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 weight 1 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1"2236	fi2237 2238	run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"2239	log_test $? 2 "    Multipath route delete - nexthops in wrong order"2240 2241	run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"2242	log_test $? 0 "    Multipath route delete exact match"2243 2244	route_cleanup2245}2246 2247socat_check()2248{2249	if [ ! -x "$(command -v socat)" ]; then2250		echo "socat command not found. Skipping test"2251		return 12252	fi2253 2254	return 02255}2256 2257iptables_check()2258{2259	iptables -t mangle -L OUTPUT &> /dev/null2260	if [ $? -ne 0 ]; then2261		echo "iptables configuration not supported. Skipping test"2262		return 12263	fi2264 2265	return 02266}2267 2268ip6tables_check()2269{2270	ip6tables -t mangle -L OUTPUT &> /dev/null2271	if [ $? -ne 0 ]; then2272		echo "ip6tables configuration not supported. Skipping test"2273		return 12274	fi2275 2276	return 02277}2278 2279ipv4_mangle_test()2280{2281	local rc2282 2283	echo2284	echo "IPv4 mangling tests"2285 2286	socat_check || return 12287	iptables_check || return 12288 2289	route_setup2290	sleep 22291 2292	local tmp_file=$(mktemp)2293	ip netns exec $ns2 socat UDP4-LISTEN:54321,fork $tmp_file &2294 2295	# Add a FIB rule and a route that will direct our connection to the2296	# listening server.2297	$IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 1232298	$IP route add table 123 172.16.101.0/24 dev veth12299 2300	# Add an unreachable route to the main table that will block our2301	# connection in case the FIB rule is not hit.2302	$IP route add unreachable 172.16.101.2/322303 2304	run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"2305	log_test $? 0 "    Connection with correct parameters"2306 2307	run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"2308	log_test $? 1 "    Connection with incorrect parameters"2309 2310	# Add a mangling rule and make sure connection is still successful.2311	$NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 12312 2313	run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"2314	log_test $? 0 "    Connection with correct parameters - mangling"2315 2316	# Delete the mangling rule and make sure connection is still2317	# successful.2318	$NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 12319 2320	run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"2321	log_test $? 0 "    Connection with correct parameters - no mangling"2322 2323	# Verify connections were indeed successful on server side.2324	[[ $(cat $tmp_file | wc -l) -eq 3 ]]2325	log_test $? 0 "    Connection check - server side"2326 2327	$IP route del unreachable 172.16.101.2/322328	$IP route del table 123 172.16.101.0/24 dev veth12329	$IP rule del pref 1002330 2331	{ kill %% && wait %%; } 2>/dev/null2332	rm $tmp_file2333 2334	route_cleanup2335}2336 2337ipv6_mangle_test()2338{2339	local rc2340 2341	echo2342	echo "IPv6 mangling tests"2343 2344	socat_check || return 12345	ip6tables_check || return 12346 2347	route_setup2348	sleep 22349 2350	local tmp_file=$(mktemp)2351	ip netns exec $ns2 socat UDP6-LISTEN:54321,fork $tmp_file &2352 2353	# Add a FIB rule and a route that will direct our connection to the2354	# listening server.2355	$IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 1232356	$IP -6 route add table 123 2001:db8:101::/64 dev veth12357 2358	# Add an unreachable route to the main table that will block our2359	# connection in case the FIB rule is not hit.2360	$IP -6 route add unreachable 2001:db8:101::2/1282361 2362	run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"2363	log_test $? 0 "    Connection with correct parameters"2364 2365	run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"2366	log_test $? 1 "    Connection with incorrect parameters"2367 2368	# Add a mangling rule and make sure connection is still successful.2369	$NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 12370 2371	run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"2372	log_test $? 0 "    Connection with correct parameters - mangling"2373 2374	# Delete the mangling rule and make sure connection is still2375	# successful.2376	$NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 12377 2378	run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"2379	log_test $? 0 "    Connection with correct parameters - no mangling"2380 2381	# Verify connections were indeed successful on server side.2382	[[ $(cat $tmp_file | wc -l) -eq 3 ]]2383	log_test $? 0 "    Connection check - server side"2384 2385	$IP -6 route del unreachable 2001:db8:101::2/1282386	$IP -6 route del table 123 2001:db8:101::/64 dev veth12387	$IP -6 rule del pref 1002388 2389	{ kill %% && wait %%; } 2>/dev/null2390	rm $tmp_file2391 2392	route_cleanup2393}2394 2395ip_neigh_get_check()2396{2397	ip neigh help 2>&1 | grep -q 'ip neigh get'2398	if [ $? -ne 0 ]; then2399		echo "iproute2 command does not support neigh get. Skipping test"2400		return 12401	fi2402 2403	return 02404}2405 2406ipv4_bcast_neigh_test()2407{2408	local rc2409 2410	echo2411	echo "IPv4 broadcast neighbour tests"2412 2413	ip_neigh_get_check || return 12414 2415	setup2416 2417	set -e2418	run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"2419	run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"2420 2421	run_cmd "$IP neigh get 192.0.2.111 dev dummy0"2422	run_cmd "$IP neigh get 192.0.2.255 dev dummy0"2423 2424	run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"2425 2426	run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"2427	run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"2428 2429	run_cmd "$IP neigh get 203.0.113.111 dev dummy0"2430	run_cmd "$IP neigh get 203.0.113.255 dev dummy0"2431 2432	run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"2433	set +e2434 2435	run_cmd "$IP neigh get 192.0.2.111 dev dummy0"2436	log_test $? 0 "Resolved neighbour for broadcast address"2437 2438	run_cmd "$IP neigh get 192.0.2.255 dev dummy0"2439	log_test $? 0 "Resolved neighbour for network broadcast address"2440 2441	run_cmd "$IP neigh get 203.0.113.111 dev dummy0"2442	log_test $? 2 "Unresolved neighbour for broadcast address"2443 2444	run_cmd "$IP neigh get 203.0.113.255 dev dummy0"2445	log_test $? 2 "Unresolved neighbour for network broadcast address"2446 2447	cleanup2448}2449 2450mpath_dep_check()2451{2452	if [ ! -x "$(command -v mausezahn)" ]; then2453		echo "mausezahn command not found. Skipping test"2454		return 12455	fi2456 2457	if [ ! -x "$(command -v jq)" ]; then2458		echo "jq command not found. Skipping test"2459		return 12460	fi2461 2462	if [ ! -x "$(command -v bc)" ]; then2463		echo "bc command not found. Skipping test"2464		return 12465	fi2466 2467	if [ ! -x "$(command -v perf)" ]; then2468		echo "perf command not found. Skipping test"2469		return 12470	fi2471 2472	perf list fib:* | grep -q fib_table_lookup2473	if [ $? -ne 0 ]; then2474		echo "IPv4 FIB tracepoint not found. Skipping test"2475		return 12476	fi2477 2478	perf list fib6:* | grep -q fib6_table_lookup2479	if [ $? -ne 0 ]; then2480		echo "IPv6 FIB tracepoint not found. Skipping test"2481		return 12482	fi2483 2484	return 02485}2486 2487link_stats_get()2488{2489	local ns=$1; shift2490	local dev=$1; shift2491	local dir=$1; shift2492	local stat=$1; shift2493 2494	ip -n $ns -j -s link show dev $dev \2495		| jq '.[]["stats64"]["'$dir'"]["'$stat'"]'2496}2497 2498list_rcv_eval()2499{2500	local file=$1; shift2501	local expected=$1; shift2502 2503	local count=$(tail -n 1 $file | jq '.["counter-value"] | tonumber | floor')2504	local ratio=$(echo "scale=2; $count / $expected" | bc -l)2505	local res=$(echo "$ratio >= 0.95" | bc)2506	[[ $res -eq 1 ]]2507	log_test $? 0 "Multipath route hit ratio ($ratio)"2508}2509 2510ipv4_mpath_list_test()2511{2512	echo2513	echo "IPv4 multipath list receive tests"2514 2515	mpath_dep_check || return 12516 2517	route_setup2518 2519	set -e2520	run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"2521 2522	run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""2523	run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""2524	run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"2525	run_cmd "ip -n $ns2 link add name nh1 up type dummy"2526	run_cmd "ip -n $ns2 link add name nh2 up type dummy"2527	run_cmd "ip -n $ns2 address add 172.16.201.1/24 dev nh1"2528	run_cmd "ip -n $ns2 address add 172.16.202.1/24 dev nh2"2529	run_cmd "ip -n $ns2 neigh add 172.16.201.2 lladdr 00:11:22:33:44:55 nud perm dev nh1"2530	run_cmd "ip -n $ns2 neigh add 172.16.202.2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"2531	run_cmd "ip -n $ns2 route add 203.0.113.0/242532		nexthop via 172.16.201.2 nexthop via 172.16.202.2"2533	run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.fib_multipath_hash_policy=1"2534	run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.conf.veth2.rp_filter=0"2535	run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.rp_filter=0"2536	run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.conf.default.rp_filter=0"2537	set +e2538 2539	local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')2540	local tmp_file=$(mktemp)2541	local cmd="ip netns exec $ns1 mausezahn veth1 -a own -b $dmac2542		-A 172.16.101.1 -B 203.0.113.1 -t udp 'sp=12345,dp=0-65535' -q"2543 2544	# Packets forwarded in a list using a multipath route must not reuse a2545	# cached result so that a flow always hits the same nexthop. In other2546	# words, the FIB lookup tracepoint needs to be triggered for every2547	# packet.2548	local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2549	run_cmd "perf stat -a -e fib:fib_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"2550	local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2551	local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)2552	list_rcv_eval $tmp_file $diff2553 2554	rm $tmp_file2555	route_cleanup2556}2557 2558ipv6_mpath_list_test()2559{2560	echo2561	echo "IPv6 multipath list receive tests"2562 2563	mpath_dep_check || return 12564 2565	route_setup2566 2567	set -e2568	run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"2569 2570	run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""2571	run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""2572	run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"2573	run_cmd "ip -n $ns2 link add name nh1 up type dummy"2574	run_cmd "ip -n $ns2 link add name nh2 up type dummy"2575	run_cmd "ip -n $ns2 -6 address add 2001:db8:201::1/64 dev nh1"2576	run_cmd "ip -n $ns2 -6 address add 2001:db8:202::1/64 dev nh2"2577	run_cmd "ip -n $ns2 -6 neigh add 2001:db8:201::2 lladdr 00:11:22:33:44:55 nud perm dev nh1"2578	run_cmd "ip -n $ns2 -6 neigh add 2001:db8:202::2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"2579	run_cmd "ip -n $ns2 -6 route add 2001:db8:301::/642580		nexthop via 2001:db8:201::2 nexthop via 2001:db8:202::2"2581	run_cmd "ip netns exec $ns2 sysctl -qw net.ipv6.fib_multipath_hash_policy=1"2582	set +e2583 2584	local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')2585	local tmp_file=$(mktemp)2586	local cmd="ip netns exec $ns1 mausezahn -6 veth1 -a own -b $dmac2587		-A 2001:db8:101::1 -B 2001:db8:301::1 -t udp 'sp=12345,dp=0-65535' -q"2588 2589	# Packets forwarded in a list using a multipath route must not reuse a2590	# cached result so that a flow always hits the same nexthop. In other2591	# words, the FIB lookup tracepoint needs to be triggered for every2592	# packet.2593	local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2594	run_cmd "perf stat -a -e fib6:fib6_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"2595	local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)2596	local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)2597	list_rcv_eval $tmp_file $diff2598 2599	rm $tmp_file2600	route_cleanup2601}2602 2603################################################################################2604# usage2605 2606usage()2607{2608	cat <<EOF2609usage: ${0##*/} OPTS2610 2611        -t <test>   Test(s) to run (default: all)2612                    (options: $TESTS)2613        -p          Pause on fail2614        -P          Pause after each test before cleanup2615        -v          verbose mode (show commands and output)2616EOF2617}2618 2619################################################################################2620# main2621 2622trap cleanup EXIT2623 2624while getopts :t:pPhv o2625do2626	case $o in2627		t) TESTS=$OPTARG;;2628		p) PAUSE_ON_FAIL=yes;;2629		P) PAUSE=yes;;2630		v) VERBOSE=$(($VERBOSE + 1));;2631		h) usage; exit 0;;2632		*) usage; exit 1;;2633	esac2634done2635 2636PEER_CMD="ip netns exec ${PEER_NS}"2637 2638# make sure we don't pause twice2639[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no2640 2641if [ "$(id -u)" -ne 0 ];then2642	echo "SKIP: Need root privileges"2643	exit $ksft_skip;2644fi2645 2646if [ ! -x "$(command -v ip)" ]; then2647	echo "SKIP: Could not run test without ip tool"2648	exit $ksft_skip2649fi2650 2651ip route help 2>&1 | grep -q fibmatch2652if [ $? -ne 0 ]; then2653	echo "SKIP: iproute2 too old, missing fibmatch"2654	exit $ksft_skip2655fi2656 2657# start clean2658cleanup &> /dev/null2659 2660for t in $TESTS2661do2662	case $t in2663	fib_unreg_test|unregister)	fib_unreg_test;;2664	fib_down_test|down)		fib_down_test;;2665	fib_carrier_test|carrier)	fib_carrier_test;;2666	fib_rp_filter_test|rp_filter)	fib_rp_filter_test;;2667	fib_nexthop_test|nexthop)	fib_nexthop_test;;2668	fib_notify_test|ipv4_notify)	fib_notify_test;;2669	fib6_notify_test|ipv6_notify)	fib6_notify_test;;2670	fib_suppress_test|suppress)	fib_suppress_test;;2671	ipv6_route_test|ipv6_rt)	ipv6_route_test;;2672	ipv4_route_test|ipv4_rt)	ipv4_route_test;;2673	ipv6_addr_metric)		ipv6_addr_metric_test;;2674	ipv4_addr_metric)		ipv4_addr_metric_test;;2675	ipv4_del_addr)			ipv4_del_addr_test;;2676	ipv6_del_addr)			ipv6_del_addr_test;;2677	ipv6_route_metrics)		ipv6_route_metrics_test;;2678	ipv4_route_metrics)		ipv4_route_metrics_test;;2679	ipv4_route_v6_gw)		ipv4_route_v6_gw_test;;2680	ipv4_mangle)			ipv4_mangle_test;;2681	ipv6_mangle)			ipv6_mangle_test;;2682	ipv4_bcast_neigh)		ipv4_bcast_neigh_test;;2683	fib6_gc_test|ipv6_gc)		fib6_gc_test;;2684	ipv4_mpath_list)		ipv4_mpath_list_test;;2685	ipv6_mpath_list)		ipv6_mpath_list_test;;2686 2687	help) echo "Test names: $TESTS"; exit 0;;2688	esac2689done2690 2691if [ "$TESTS" != "none" ]; then2692	printf "\nTests passed: %3d\n" ${nsuccess}2693	printf "Tests failed: %3d\n"   ${nfail}2694fi2695 2696exit $ret2697