brintos

brintos / linux-shallow public Read only

0
0
Text · 16.5 KiB · 1d58b3b Raw
669 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# This test is for checking IPv4 and IPv6 FIB rules API5 6source lib.sh7ret=08PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}9 10RTABLE=10011RTABLE_PEER=10112RTABLE_VRF=10213GW_IP4=192.51.100.214SRC_IP=192.51.100.315GW_IP6=2001:db8:1::216SRC_IP6=2001:db8:1::317 18DEV_ADDR=192.51.100.119DEV_ADDR6=2001:db8:1::120DEV=dummy021TESTS="22	fib_rule623	fib_rule424	fib_rule6_connect25	fib_rule4_connect26	fib_rule6_vrf27	fib_rule4_vrf28"29 30SELFTEST_PATH=""31 32log_test()33{34	local rc=$135	local expected=$236	local msg="$3"37 38	if [ ${rc} -eq ${expected} ]; then39		nsuccess=$((nsuccess+1))40		printf "    TEST: %-60s  [ OK ]\n" "${msg}"41	else42		ret=143		nfail=$((nfail+1))44		printf "    TEST: %-60s  [FAIL]\n" "${msg}"45		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then46			echo47			echo "hit enter to continue, 'q' to quit"48			read a49			[ "$a" = "q" ] && exit 150		fi51	fi52}53 54setup()55{56	set -e57	setup_ns testns58	IP="ip -netns $testns"59 60	$IP link add dummy0 type dummy61	$IP link set dev dummy0 up62	$IP address add $DEV_ADDR/24 dev dummy063	$IP -6 address add $DEV_ADDR6/64 dev dummy064 65	set +e66}67 68cleanup()69{70	$IP link del dev dummy0 &> /dev/null71	cleanup_ns $testns72}73 74setup_peer()75{76	set -e77 78	setup_ns peerns79	IP_PEER="ip -netns $peerns"80	$IP_PEER link set dev lo up81 82	ip link add name veth0 netns $testns type veth \83		peer name veth1 netns $peerns84	$IP link set dev veth0 up85	$IP_PEER link set dev veth1 up86 87	$IP address add 192.0.2.10 peer 192.0.2.11/32 dev veth088	$IP_PEER address add 192.0.2.11 peer 192.0.2.10/32 dev veth189 90	$IP address add 2001:db8::10 peer 2001:db8::11/128 dev veth0 nodad91	$IP_PEER address add 2001:db8::11 peer 2001:db8::10/128 dev veth1 nodad92 93	$IP_PEER address add 198.51.100.11/32 dev lo94	$IP route add table $RTABLE_PEER 198.51.100.11/32 via 192.0.2.1195 96	$IP_PEER address add 2001:db8::1:11/128 dev lo97	$IP route add table $RTABLE_PEER 2001:db8::1:11/128 via 2001:db8::1198 99	set +e100}101 102cleanup_peer()103{104	$IP link del dev veth0105	ip netns del $peerns106}107 108setup_vrf()109{110	$IP link add name vrf0 up type vrf table $RTABLE_VRF111	$IP link set dev $DEV master vrf0112}113 114cleanup_vrf()115{116	$IP link del dev vrf0117}118 119fib_check_iproute_support()120{121	ip rule help 2>&1 | grep -q $1122	if [ $? -ne 0 ]; then123		echo "SKIP: iproute2 iprule too old, missing $1 match"124		return 1125	fi126 127	ip route get help 2>&1 | grep -q $2128	if [ $? -ne 0 ]; then129		echo "SKIP: iproute2 get route too old, missing $2 match"130		return 1131	fi132 133	return 0134}135 136fib_rule6_del()137{138	$IP -6 rule del $1139	log_test $? 0 "rule6 del $1"140}141 142fib_rule6_del_by_pref()143{144	pref=$($IP -6 rule show $1 table $RTABLE | cut -d ":" -f 1)145	$IP -6 rule del pref $pref146}147 148fib_rule6_test_match_n_redirect()149{150	local match="$1"151	local getmatch="$2"152	local getnomatch="$3"153	local description="$4"154	local nomatch_description="$5"155 156	$IP -6 rule add $match table $RTABLE157	$IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE"158	log_test $? 0 "rule6 check: $description"159 160	$IP -6 route get $GW_IP6 $getnomatch 2>&1 | grep -q "table $RTABLE"161	log_test $? 1 "rule6 check: $nomatch_description"162 163	fib_rule6_del_by_pref "$match"164	log_test $? 0 "rule6 del by pref: $description"165}166 167fib_rule6_test_reject()168{169	local match="$1"170	local rc171 172	$IP -6 rule add $match table $RTABLE 2>/dev/null173	rc=$?174	log_test $rc 2 "rule6 check: $match"175 176	if [ $rc -eq 0 ]; then177		$IP -6 rule del $match table $RTABLE178	fi179}180 181fib_rule6_test()182{183	local ext_name=$1; shift184	local getnomatch185	local getmatch186	local match187	local cnt188 189	echo190	echo "IPv6 FIB rule tests $ext_name"191 192	# setup the fib rule redirect route193	$IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink194 195	match="oif $DEV"196	getnomatch="oif lo"197	fib_rule6_test_match_n_redirect "$match" "$match" "$getnomatch" \198		"oif redirect to table" "oif no redirect to table"199 200	match="from $SRC_IP6 iif $DEV"201	getnomatch="from $SRC_IP6 iif lo"202	fib_rule6_test_match_n_redirect "$match" "$match" "$getnomatch" \203		"iif redirect to table" "iif no redirect to table"204 205	# Reject dsfield (tos) options which have ECN bits set206	for cnt in $(seq 1 3); do207		match="dsfield $cnt"208		fib_rule6_test_reject "$match"209	done210 211	# Don't take ECN bits into account when matching on dsfield212	match="tos 0x10"213	for cnt in "0x10" "0x11" "0x12" "0x13"; do214		# Using option 'tos' instead of 'dsfield' as old iproute2215		# versions don't support 'dsfield' in ip rule show.216		getmatch="tos $cnt"217		getnomatch="tos 0x20"218		fib_rule6_test_match_n_redirect "$match" "$getmatch" \219			"$getnomatch" "$getmatch redirect to table" \220			"$getnomatch no redirect to table"221	done222 223	# Re-test TOS matching, but with input routes since they are handled224	# differently from output routes.225	match="tos 0x10"226	for cnt in "0x10" "0x11" "0x12" "0x13"; do227		getmatch="tos $cnt"228		getnomatch="tos 0x20"229		fib_rule6_test_match_n_redirect "$match" \230			"from $SRC_IP6 iif $DEV $getmatch" \231			"from $SRC_IP6 iif $DEV $getnomatch" \232			"iif $getmatch redirect to table" \233			"iif $getnomatch no redirect to table"234	done235 236	match="fwmark 0x64"237	getmatch="mark 0x64"238	getnomatch="mark 0x63"239	fib_rule6_test_match_n_redirect "$match" "$getmatch" "$getnomatch" \240		"fwmark redirect to table" "fwmark no redirect to table"241 242	fib_check_iproute_support "uidrange" "uid"243	if [ $? -eq 0 ]; then244		match="uidrange 100-100"245		getmatch="uid 100"246		getnomatch="uid 101"247		fib_rule6_test_match_n_redirect "$match" "$getmatch" \248			"$getnomatch" "uid redirect to table" \249			"uid no redirect to table"250	fi251 252	fib_check_iproute_support "sport" "sport"253	if [ $? -eq 0 ]; then254		match="sport 666 dport 777"255		getnomatch="sport 667 dport 778"256		fib_rule6_test_match_n_redirect "$match" "$match" \257			"$getnomatch" "sport and dport redirect to table" \258			"sport and dport no redirect to table"259	fi260 261	fib_check_iproute_support "ipproto" "ipproto"262	if [ $? -eq 0 ]; then263		match="ipproto tcp"264		getnomatch="ipproto udp"265		fib_rule6_test_match_n_redirect "$match" "$match" \266			"$getnomatch" "ipproto tcp match" "ipproto udp no match"267	fi268 269	fib_check_iproute_support "ipproto" "ipproto"270	if [ $? -eq 0 ]; then271		match="ipproto ipv6-icmp"272		getnomatch="ipproto tcp"273		fib_rule6_test_match_n_redirect "$match" "$match" \274			"$getnomatch" "ipproto ipv6-icmp match" \275			"ipproto ipv6-tcp no match"276	fi277 278	fib_check_iproute_support "dscp" "tos"279	if [ $? -eq 0 ]; then280		match="dscp 0x3f"281		getmatch="tos 0xfc"282		getnomatch="tos 0xf4"283		fib_rule6_test_match_n_redirect "$match" "$getmatch" \284			"$getnomatch" "dscp redirect to table" \285			"dscp no redirect to table"286 287		match="dscp 0x3f"288		getmatch="from $SRC_IP6 iif $DEV tos 0xfc"289		getnomatch="from $SRC_IP6 iif $DEV tos 0xf4"290		fib_rule6_test_match_n_redirect "$match" "$getmatch" \291			"$getnomatch" "iif dscp redirect to table" \292			"iif dscp no redirect to table"293	fi294}295 296fib_rule6_vrf_test()297{298	setup_vrf299	fib_rule6_test "- with VRF"300	cleanup_vrf301}302 303# Verify that the IPV6_TCLASS option of UDPv6 and TCPv6 sockets is properly304# taken into account when connecting the socket and when sending packets.305fib_rule6_connect_test()306{307	local dsfield308 309	echo310	echo "IPv6 FIB rule connect tests"311 312	setup_peer313	$IP -6 rule add dsfield 0x04 table $RTABLE_PEER314 315	# Combine the base DS Field value (0x04) with all possible ECN values316	# (Not-ECT: 0, ECT(1): 1, ECT(0): 2, CE: 3).317	# The ECN bits shouldn't influence the result of the test.318	for dsfield in 0x04 0x05 0x06 0x07; do319		nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D \320			-Q "${dsfield}" -l 2001:db8::1:11 -r 2001:db8::1:11321		log_test $? 0 "rule6 dsfield udp connect (dsfield ${dsfield})"322 323		nettest -q -6 -B -t 5 -N $testns -O $peerns -Q "${dsfield}" \324			-l 2001:db8::1:11 -r 2001:db8::1:11325		log_test $? 0 "rule6 dsfield tcp connect (dsfield ${dsfield})"326	done327 328	# Check that UDP and TCP connections fail when using a DS Field that329	# does not match the previously configured FIB rule.330	nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D \331		-Q 0x20 -l 2001:db8::1:11 -r 2001:db8::1:11332	log_test $? 1 "rule6 dsfield udp no connect (dsfield 0x20)"333 334	nettest -q -6 -B -t 5 -N $testns -O $peerns -Q 0x20 \335		-l 2001:db8::1:11 -r 2001:db8::1:11336	log_test $? 1 "rule6 dsfield tcp no connect (dsfield 0x20)"337 338	$IP -6 rule del dsfield 0x04 table $RTABLE_PEER339 340	ip rule help 2>&1 | grep -q dscp341	if [ $? -ne 0 ]; then342		echo "SKIP: iproute2 iprule too old, missing dscp match"343		cleanup_peer344		return345	fi346 347	$IP -6 rule add dscp 0x3f table $RTABLE_PEER348 349	nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D -Q 0xfc \350		-l 2001:db8::1:11 -r 2001:db8::1:11351	log_test $? 0 "rule6 dscp udp connect"352 353	nettest -q -6 -B -t 5 -N $testns -O $peerns -Q 0xfc \354		-l 2001:db8::1:11 -r 2001:db8::1:11355	log_test $? 0 "rule6 dscp tcp connect"356 357	nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D -Q 0xf4 \358		-l 2001:db8::1:11 -r 2001:db8::1:11359	log_test $? 1 "rule6 dscp udp no connect"360 361	nettest -q -6 -B -t 5 -N $testns -O $peerns -Q 0xf4 \362		-l 2001:db8::1:11 -r 2001:db8::1:11363	log_test $? 1 "rule6 dscp tcp no connect"364 365	$IP -6 rule del dscp 0x3f table $RTABLE_PEER366 367	cleanup_peer368}369 370fib_rule4_del()371{372	$IP rule del $1373	log_test $? 0 "del $1"374}375 376fib_rule4_del_by_pref()377{378	pref=$($IP rule show $1 table $RTABLE | cut -d ":" -f 1)379	$IP rule del pref $pref380}381 382fib_rule4_test_match_n_redirect()383{384	local match="$1"385	local getmatch="$2"386	local getnomatch="$3"387	local description="$4"388	local nomatch_description="$5"389 390	$IP rule add $match table $RTABLE391	$IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE"392	log_test $? 0 "rule4 check: $description"393 394	$IP route get $GW_IP4 $getnomatch 2>&1 | grep -q "table $RTABLE"395	log_test $? 1 "rule4 check: $nomatch_description"396 397	fib_rule4_del_by_pref "$match"398	log_test $? 0 "rule4 del by pref: $description"399}400 401fib_rule4_test_reject()402{403	local match="$1"404	local rc405 406	$IP rule add $match table $RTABLE 2>/dev/null407	rc=$?408	log_test $rc 2 "rule4 check: $match"409 410	if [ $rc -eq 0 ]; then411		$IP rule del $match table $RTABLE412	fi413}414 415fib_rule4_test()416{417	local ext_name=$1; shift418	local getnomatch419	local getmatch420	local match421	local cnt422 423	echo424	echo "IPv4 FIB rule tests $ext_name"425 426	# setup the fib rule redirect route427	$IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink428 429	match="oif $DEV"430	getnomatch="oif lo"431	fib_rule4_test_match_n_redirect "$match" "$match" "$getnomatch" \432		"oif redirect to table" "oif no redirect to table"433 434	# Enable forwarding and disable rp_filter as all the addresses are in435	# the same subnet and egress device == ingress device.436	ip netns exec $testns sysctl -qw net.ipv4.ip_forward=1437	ip netns exec $testns sysctl -qw net.ipv4.conf.$DEV.rp_filter=0438	match="from $SRC_IP iif $DEV"439	getnomatch="from $SRC_IP iif lo"440	fib_rule4_test_match_n_redirect "$match" "$match" "$getnomatch" \441		"iif redirect to table" "iif no redirect to table"442 443	# Reject dsfield (tos) options which have ECN bits set444	for cnt in $(seq 1 3); do445		match="dsfield $cnt"446		fib_rule4_test_reject "$match"447	done448 449	# Don't take ECN bits into account when matching on dsfield450	match="tos 0x10"451	for cnt in "0x10" "0x11" "0x12" "0x13"; do452		# Using option 'tos' instead of 'dsfield' as old iproute2453		# versions don't support 'dsfield' in ip rule show.454		getmatch="tos $cnt"455		getnomatch="tos 0x20"456		fib_rule4_test_match_n_redirect "$match" "$getmatch" \457			"$getnomatch" "$getmatch redirect to table" \458			"$getnomatch no redirect to table"459	done460 461	# Re-test TOS matching, but with input routes since they are handled462	# differently from output routes.463	match="tos 0x10"464	for cnt in "0x10" "0x11" "0x12" "0x13"; do465		getmatch="tos $cnt"466		getnomatch="tos 0x20"467		fib_rule4_test_match_n_redirect "$match" \468			"from $SRC_IP iif $DEV $getmatch" \469			"from $SRC_IP iif $DEV $getnomatch" \470			"iif $getmatch redirect to table" \471			"iif $getnomatch no redirect to table"472	done473 474	match="fwmark 0x64"475	getmatch="mark 0x64"476	getnomatch="mark 0x63"477	fib_rule4_test_match_n_redirect "$match" "$getmatch" "$getnomatch" \478		"fwmark redirect to table" "fwmark no redirect to table"479 480	fib_check_iproute_support "uidrange" "uid"481	if [ $? -eq 0 ]; then482		match="uidrange 100-100"483		getmatch="uid 100"484		getnomatch="uid 101"485		fib_rule4_test_match_n_redirect "$match" "$getmatch" \486			"$getnomatch" "uid redirect to table" \487			"uid no redirect to table"488	fi489 490	fib_check_iproute_support "sport" "sport"491	if [ $? -eq 0 ]; then492		match="sport 666 dport 777"493		getnomatch="sport 667 dport 778"494		fib_rule4_test_match_n_redirect "$match" "$match" \495			"$getnomatch" "sport and dport redirect to table" \496			"sport and dport no redirect to table"497	fi498 499	fib_check_iproute_support "ipproto" "ipproto"500	if [ $? -eq 0 ]; then501		match="ipproto tcp"502		getnomatch="ipproto udp"503		fib_rule4_test_match_n_redirect "$match" "$match" \504			"$getnomatch" "ipproto tcp match" \505			"ipproto udp no match"506	fi507 508	fib_check_iproute_support "ipproto" "ipproto"509	if [ $? -eq 0 ]; then510		match="ipproto icmp"511		getnomatch="ipproto tcp"512		fib_rule4_test_match_n_redirect "$match" "$match" \513			"$getnomatch" "ipproto icmp match" \514			"ipproto tcp no match"515	fi516 517	fib_check_iproute_support "dscp" "tos"518	if [ $? -eq 0 ]; then519		match="dscp 0x3f"520		getmatch="tos 0xfc"521		getnomatch="tos 0xf4"522		fib_rule4_test_match_n_redirect "$match" "$getmatch" \523			"$getnomatch" "dscp redirect to table" \524			"dscp no redirect to table"525 526		match="dscp 0x3f"527		getmatch="from $SRC_IP iif $DEV tos 0xfc"528		getnomatch="from $SRC_IP iif $DEV tos 0xf4"529		fib_rule4_test_match_n_redirect "$match" "$getmatch" \530			"$getnomatch" "iif dscp redirect to table" \531			"iif dscp no redirect to table"532	fi533}534 535fib_rule4_vrf_test()536{537	setup_vrf538	fib_rule4_test "- with VRF"539	cleanup_vrf540}541 542# Verify that the IP_TOS option of UDPv4 and TCPv4 sockets is properly taken543# into account when connecting the socket and when sending packets.544fib_rule4_connect_test()545{546	local dsfield547 548	echo549	echo "IPv4 FIB rule connect tests"550 551	setup_peer552	$IP -4 rule add dsfield 0x04 table $RTABLE_PEER553 554	# Combine the base DS Field value (0x04) with all possible ECN values555	# (Not-ECT: 0, ECT(1): 1, ECT(0): 2, CE: 3).556	# The ECN bits shouldn't influence the result of the test.557	for dsfield in 0x04 0x05 0x06 0x07; do558		nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q "${dsfield}" \559			-l 198.51.100.11 -r 198.51.100.11560		log_test $? 0 "rule4 dsfield udp connect (dsfield ${dsfield})"561 562		nettest -q -B -t 5 -N $testns -O $peerns -Q "${dsfield}" \563			-l 198.51.100.11 -r 198.51.100.11564		log_test $? 0 "rule4 dsfield tcp connect (dsfield ${dsfield})"565	done566 567	# Check that UDP and TCP connections fail when using a DS Field that568	# does not match the previously configured FIB rule.569	nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q 0x20 \570		-l 198.51.100.11 -r 198.51.100.11571	log_test $? 1 "rule4 dsfield udp no connect (dsfield 0x20)"572 573	nettest -q -B -t 5 -N $testns -O $peerns -Q 0x20 \574		-l 198.51.100.11 -r 198.51.100.11575	log_test $? 1 "rule4 dsfield tcp no connect (dsfield 0x20)"576 577	$IP -4 rule del dsfield 0x04 table $RTABLE_PEER578 579	ip rule help 2>&1 | grep -q dscp580	if [ $? -ne 0 ]; then581		echo "SKIP: iproute2 iprule too old, missing dscp match"582		cleanup_peer583		return584	fi585 586	$IP -4 rule add dscp 0x3f table $RTABLE_PEER587 588	nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q 0xfc \589		-l 198.51.100.11 -r 198.51.100.11590	log_test $? 0 "rule4 dscp udp connect"591 592	nettest -q -B -t 5 -N $testns -O $peerns -Q 0xfc \593		-l 198.51.100.11 -r 198.51.100.11594	log_test $? 0 "rule4 dscp tcp connect"595 596	nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q 0xf4 \597		-l 198.51.100.11 -r 198.51.100.11598	log_test $? 1 "rule4 dscp udp no connect"599 600	nettest -q -B -t 5 -N $testns -O $peerns -Q 0xf4 \601		-l 198.51.100.11 -r 198.51.100.11602	log_test $? 1 "rule4 dscp tcp no connect"603 604	$IP -4 rule del dscp 0x3f table $RTABLE_PEER605 606	cleanup_peer607}608################################################################################609# usage610 611usage()612{613	cat <<EOF614usage: ${0##*/} OPTS615 616        -t <test>   Test(s) to run (default: all)617                    (options: $TESTS)618EOF619}620 621################################################################################622# main623 624while getopts ":t:h" opt; do625	case $opt in626		t) TESTS=$OPTARG;;627		h) usage; exit 0;;628		*) usage; exit 1;;629	esac630done631 632if [ "$(id -u)" -ne 0 ];then633	echo "SKIP: Need root privileges"634	exit $ksft_skip635fi636 637if [ ! -x "$(command -v ip)" ]; then638	echo "SKIP: Could not run test without ip tool"639	exit $ksft_skip640fi641 642check_gen_prog "nettest"643 644# start clean645cleanup &> /dev/null646setup647for t in $TESTS648do649	case $t in650	fib_rule6_test|fib_rule6)		fib_rule6_test;;651	fib_rule4_test|fib_rule4)		fib_rule4_test;;652	fib_rule6_connect_test|fib_rule6_connect)	fib_rule6_connect_test;;653	fib_rule4_connect_test|fib_rule4_connect)	fib_rule4_connect_test;;654	fib_rule6_vrf_test|fib_rule6_vrf)	fib_rule6_vrf_test;;655	fib_rule4_vrf_test|fib_rule4_vrf)	fib_rule4_vrf_test;;656 657	help) echo "Test names: $TESTS"; exit 0;;658 659	esac660done661cleanup662 663if [ "$TESTS" != "none" ]; then664	printf "\nTests passed: %3d\n" ${nsuccess}665	printf "Tests failed: %3d\n"   ${nfail}666fi667 668exit $ret669