brintos

brintos / linux-shallow public Read only

0
0
Text · 23.2 KiB · 28a7756 Raw
880 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03#4# author: Andrea Mayer <andrea.mayer@uniroma2.it>5#6# This script is designed for testing the SRv6 H.Encaps.Red behavior.7#8# Below is depicted the IPv6 network of an operator which offers advanced9# IPv4/IPv6 VPN services to hosts, enabling them to communicate with each10# other.11# In this example, hosts hs-1 and hs-2 are connected through an IPv4/IPv6 VPN12# service, while hs-3 and hs-4 are connected using an IPv6 only VPN.13#14# Routers rt-1,rt-2,rt-3 and rt-4 implement IPv4/IPv6 L3 VPN services15# leveraging the SRv6 architecture. The key components for such VPNs are:16#17#   i) The SRv6 H.Encaps.Red behavior applies SRv6 Policies on traffic received18#      by connected hosts, initiating the VPN tunnel. Such a behavior is an19#      optimization of the SRv6 H.Encap aiming to reduce the length of the SID20#      List carried in the pushed SRH. Specifically, the H.Encaps.Red removes21#      the first SID contained in the SID List (i.e. SRv6 Policy) by storing it22#      into the IPv6 Destination Address. When a SRv6 Policy is made of only one23#      SID, the SRv6 H.Encaps.Red behavior omits the SRH at all and pushes that24#      SID directly into the IPv6 DA;25#26#  ii) The SRv6 End behavior advances the active SID in the SID List carried by27#      the SRH;28#29# iii) The SRv6 End.DT46 behavior is used for removing the SRv6 Policy and,30#      thus, it terminates the VPN tunnel. Such a behavior is capable of31#      handling, at the same time, both tunneled IPv4 and IPv6 traffic.32#33#34#               cafe::1                      cafe::235#              10.0.0.1                     10.0.0.236#             +--------+                   +--------+37#             |        |                   |        |38#             |  hs-1  |                   |  hs-2  |39#             |        |                   |        |40#             +---+----+                   +--- +---+41#    cafe::/64    |                             |      cafe::/6442#  10.0.0.0/24    |                             |    10.0.0.0/2443#             +---+----+                   +----+---+44#             |        |  fcf0:0:1:2::/64  |        |45#             |  rt-1  +-------------------+  rt-2  |46#             |        |                   |        |47#             +---+----+                   +----+---+48#                 |      .               .      |49#                 |  fcf0:0:1:3::/64   .        |50#                 |          .       .          |51#                 |            .   .            |52# fcf0:0:1:4::/64 |              .              | fcf0:0:2:3::/6453#                 |            .   .            |54#                 |          .       .          |55#                 |  fcf0:0:2:4::/64   .        |56#                 |      .               .      |57#             +---+----+                   +----+---+58#             |        |                   |        |59#             |  rt-4  +-------------------+  rt-3  |60#             |        |  fcf0:0:3:4::/64  |        |61#             +---+----+                   +----+---+62#    cafe::/64    |                             |      cafe::/6463#  10.0.0.0/24    |                             |    10.0.0.0/2464#             +---+----+                   +--- +---+65#             |        |                   |        |66#             |  hs-4  |                   |  hs-3  |67#             |        |                   |        |68#             +--------+                   +--------+69#               cafe::4                      cafe::370#              10.0.0.4                     10.0.0.371#72#73# Every fcf0:0:x:y::/64 network interconnects the SRv6 routers rt-x with rt-y74# in the IPv6 operator network.75#76# Local SID table77# ===============78#79# Each SRv6 router is configured with a Local SID table in which SIDs are80# stored. Considering the given SRv6 router rt-x, at least two SIDs are81# configured in the Local SID table:82#83#   Local SID table for SRv6 router rt-x84#   +----------------------------------------------------------+85#   |fcff:x::e is associated with the SRv6 End behavior        |86#   |fcff:x::d46 is associated with the SRv6 End.DT46 behavior |87#   +----------------------------------------------------------+88#89# The fcff::/16 prefix is reserved by the operator for implementing SRv6 VPN90# services. Reachability of SIDs is ensured by proper configuration of the IPv691# operator's network and SRv6 routers.92#93# # SRv6 Policies94# ===============95#96# An SRv6 ingress router applies SRv6 policies to the traffic received from a97# connected host. SRv6 policy enforcement consists of encapsulating the98# received traffic into a new IPv6 packet with a given SID List contained in99# the SRH.100#101# IPv4/IPv6 VPN between hs-1 and hs-2102# -----------------------------------103#104# Hosts hs-1 and hs-2 are connected using dedicated IPv4/IPv6 VPNs.105# Specifically, packets generated from hs-1 and directed towards hs-2 are106# handled by rt-1 which applies the following SRv6 Policies:107#108#   i.a) IPv6 traffic, SID List=fcff:3::e,fcff:4::e,fcff:2::d46109#  ii.a) IPv4 traffic, SID List=fcff:2::d46110#111# Policy (i.a) steers tunneled IPv6 traffic through SRv6 routers112# rt-3,rt-4,rt-2. Instead, Policy (ii.a) steers tunneled IPv4 traffic through113# rt-2.114# The H.Encaps.Red reduces the SID List (i.a) carried in SRH by removing the115# first SID (fcff:3::e) and pushing it into the IPv6 DA. In case of IPv4116# traffic, the H.Encaps.Red omits the presence of SRH at all, since the SID117# List (ii.a) consists of only one SID that can be stored directly in the IPv6118# DA.119#120# On the reverse path (i.e. from hs-2 to hs-1), rt-2 applies the following121# policies:122#123#   i.b) IPv6 traffic, SID List=fcff:1::d46124#  ii.b) IPv4 traffic, SID List=fcff:4::e,fcff:3::e,fcff:1::d46125#126# Policy (i.b) steers tunneled IPv6 traffic through the SRv6 router rt-1.127# Conversely, Policy (ii.b) steers tunneled IPv4 traffic through SRv6 routers128# rt-4,rt-3,rt-1.129# The H.Encaps.Red omits the SRH at all in case of (i.b) by pushing the single130# SID (fcff::1::d46) inside the IPv6 DA.131# The H.Encaps.Red reduces the SID List (ii.b) in the SRH by removing the first132# SID (fcff:4::e) and pushing it into the IPv6 DA.133#134# In summary:135#  hs-1->hs-2 |IPv6 DA=fcff:3::e|SRH SIDs=fcff:4::e,fcff:2::d46|IPv6|...| (i.a)136#  hs-1->hs-2 |IPv6 DA=fcff:2::d46|IPv4|...|                              (ii.a)137#138#  hs-2->hs-1 |IPv6 DA=fcff:1::d46|IPv6|...|                              (i.b)139#  hs-2->hs-1 |IPv6 DA=fcff:4::e|SRH SIDs=fcff:3::e,fcff:1::d46|IPv4|...| (ii.b)140#141#142# IPv6 VPN between hs-3 and hs-4143# ------------------------------144#145# Hosts hs-3 and hs-4 are connected using a dedicated IPv6 only VPN.146# Specifically, packets generated from hs-3 and directed towards hs-4 are147# handled by rt-3 which applies the following SRv6 Policy:148#149#  i.c) IPv6 traffic, SID List=fcff:2::e,fcff:4::d46150#151# Policy (i.c) steers tunneled IPv6 traffic through SRv6 routers rt-2,rt-4.152# The H.Encaps.Red reduces the SID List (i.c) carried in SRH by pushing the153# first SID (fcff:2::e) in the IPv6 DA.154#155# On the reverse path (i.e. from hs-4 to hs-3) the router rt-4 applies the156# following SRv6 Policy:157#158#  i.d) IPv6 traffic, SID List=fcff:1::e,fcff:3::d46.159#160# Policy (i.d) steers tunneled IPv6 traffic through SRv6 routers rt-1,rt-3.161# The H.Encaps.Red reduces the SID List (i.d) carried in SRH by pushing the162# first SID (fcff:1::e) in the IPv6 DA.163#164# In summary:165#  hs-3->hs-4 |IPv6 DA=fcff:2::e|SRH SIDs=fcff:4::d46|IPv6|...| (i.c)166#  hs-4->hs-3 |IPv6 DA=fcff:1::e|SRH SIDs=fcff:3::d46|IPv6|...| (i.d)167#168 169# Kselftest framework requirement - SKIP code is 4.170readonly ksft_skip=4171 172readonly RDMSUFF="$(mktemp -u XXXXXXXX)"173readonly VRF_TID=100174readonly VRF_DEVNAME="vrf-${VRF_TID}"175readonly RT2HS_DEVNAME="veth-t${VRF_TID}"176readonly LOCALSID_TABLE_ID=90177readonly IPv6_RT_NETWORK=fcf0:0178readonly IPv6_HS_NETWORK=cafe179readonly IPv4_HS_NETWORK=10.0.0180readonly VPN_LOCATOR_SERVICE=fcff181readonly END_FUNC=000e182readonly DT46_FUNC=0d46183 184PING_TIMEOUT_SEC=4185PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}186 187# IDs of routers and hosts are initialized during the setup of the testing188# network189ROUTERS=''190HOSTS=''191 192SETUP_ERR=1193 194ret=${ksft_skip}195nsuccess=0196nfail=0197 198log_test()199{200	local rc="$1"201	local expected="$2"202	local msg="$3"203 204	if [ "${rc}" -eq "${expected}" ]; then205		nsuccess=$((nsuccess+1))206		printf "\n    TEST: %-60s  [ OK ]\n" "${msg}"207	else208		ret=1209		nfail=$((nfail+1))210		printf "\n    TEST: %-60s  [FAIL]\n" "${msg}"211		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then212			echo213			echo "hit enter to continue, 'q' to quit"214			read a215			[ "$a" = "q" ] && exit 1216		fi217	fi218}219 220print_log_test_results()221{222	printf "\nTests passed: %3d\n" "${nsuccess}"223	printf "Tests failed: %3d\n"   "${nfail}"224 225	# when a test fails, the value of 'ret' is set to 1 (error code).226	# Conversely, when all tests are passed successfully, the 'ret' value227	# is set to 0 (success code).228	if [ "${ret}" -ne 1 ]; then229		ret=0230	fi231}232 233log_section()234{235	echo236	echo "################################################################################"237	echo "TEST SECTION: $*"238	echo "################################################################################"239}240 241test_command_or_ksft_skip()242{243	local cmd="$1"244 245	if [ ! -x "$(command -v "${cmd}")" ]; then246		echo "SKIP: Could not run test without \"${cmd}\" tool";247		exit "${ksft_skip}"248	fi249}250 251get_nodename()252{253	local name="$1"254 255	echo "${name}-${RDMSUFF}"256}257 258get_rtname()259{260	local rtid="$1"261 262	get_nodename "rt-${rtid}"263}264 265get_hsname()266{267	local hsid="$1"268 269	get_nodename "hs-${hsid}"270}271 272__create_namespace()273{274	local name="$1"275 276	ip netns add "${name}"277}278 279create_router()280{281	local rtid="$1"282	local nsname283 284	nsname="$(get_rtname "${rtid}")"285 286	__create_namespace "${nsname}"287}288 289create_host()290{291	local hsid="$1"292	local nsname293 294	nsname="$(get_hsname "${hsid}")"295 296	__create_namespace "${nsname}"297}298 299cleanup()300{301	local nsname302	local i303 304	# destroy routers305	for i in ${ROUTERS}; do306		nsname="$(get_rtname "${i}")"307 308		ip netns del "${nsname}" &>/dev/null || true309	done310 311	# destroy hosts312	for i in ${HOSTS}; do313		nsname="$(get_hsname "${i}")"314 315		ip netns del "${nsname}" &>/dev/null || true316	done317 318	# check whether the setup phase was completed successfully or not. In319	# case of an error during the setup phase of the testing environment,320	# the selftest is considered as "skipped".321	if [ "${SETUP_ERR}" -ne 0 ]; then322		echo "SKIP: Setting up the testing environment failed"323		exit "${ksft_skip}"324	fi325 326	exit "${ret}"327}328 329add_link_rt_pairs()330{331	local rt="$1"332	local rt_neighs="$2"333	local neigh334	local nsname335	local neigh_nsname336 337	nsname="$(get_rtname "${rt}")"338 339	for neigh in ${rt_neighs}; do340		neigh_nsname="$(get_rtname "${neigh}")"341 342		ip link add "veth-rt-${rt}-${neigh}" netns "${nsname}" \343			type veth peer name "veth-rt-${neigh}-${rt}" \344			netns "${neigh_nsname}"345	done346}347 348get_network_prefix()349{350	local rt="$1"351	local neigh="$2"352	local p="${rt}"353	local q="${neigh}"354 355	if [ "${p}" -gt "${q}" ]; then356		p="${q}"; q="${rt}"357	fi358 359	echo "${IPv6_RT_NETWORK}:${p}:${q}"360}361 362# Setup the basic networking for the routers363setup_rt_networking()364{365	local rt="$1"366	local rt_neighs="$2"367	local nsname368	local net_prefix369	local devname370	local neigh371 372	nsname="$(get_rtname "${rt}")"373 374	for neigh in ${rt_neighs}; do375		devname="veth-rt-${rt}-${neigh}"376 377		net_prefix="$(get_network_prefix "${rt}" "${neigh}")"378 379		ip -netns "${nsname}" addr \380			add "${net_prefix}::${rt}/64" dev "${devname}" nodad381 382		ip -netns "${nsname}" link set "${devname}" up383	done384 385	ip -netns "${nsname}" link set lo up386 387	ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.all.accept_dad=0388	ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.default.accept_dad=0389	ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.all.forwarding=1390 391	ip netns exec "${nsname}" sysctl -wq net.ipv4.conf.all.rp_filter=0392	ip netns exec "${nsname}" sysctl -wq net.ipv4.conf.default.rp_filter=0393	ip netns exec "${nsname}" sysctl -wq net.ipv4.ip_forward=1394}395 396# Setup local SIDs for an SRv6 router397setup_rt_local_sids()398{399	local rt="$1"400	local rt_neighs="$2"401	local net_prefix402	local devname403	local nsname404	local neigh405 406	nsname="$(get_rtname "${rt}")"407 408	for neigh in ${rt_neighs}; do409		devname="veth-rt-${rt}-${neigh}"410 411		net_prefix="$(get_network_prefix "${rt}" "${neigh}")"412 413		# set underlay network routes for SIDs reachability414		ip -netns "${nsname}" -6 route \415			add "${VPN_LOCATOR_SERVICE}:${neigh}::/32" \416			table "${LOCALSID_TABLE_ID}" \417			via "${net_prefix}::${neigh}" dev "${devname}"418	done419 420	# Local End behavior (note that "dev" is dummy and the VRF is chosen421	# for the sake of simplicity).422	ip -netns "${nsname}" -6 route \423		add "${VPN_LOCATOR_SERVICE}:${rt}::${END_FUNC}" \424		table "${LOCALSID_TABLE_ID}" \425		encap seg6local action End dev "${VRF_DEVNAME}"426 427	# Local End.DT46 behavior428	ip -netns "${nsname}" -6 route \429		add "${VPN_LOCATOR_SERVICE}:${rt}::${DT46_FUNC}" \430		table "${LOCALSID_TABLE_ID}" \431		encap seg6local action End.DT46 vrftable "${VRF_TID}" \432		dev "${VRF_DEVNAME}"433 434	# all SIDs for VPNs start with a common locator. Routes and SRv6435	# Endpoint behavior instaces are grouped together in the 'localsid'436	# table.437	ip -netns "${nsname}" -6 rule \438		add to "${VPN_LOCATOR_SERVICE}::/16" \439		lookup "${LOCALSID_TABLE_ID}" prio 999440 441	# set default routes to unreachable for both ipv4 and ipv6442	ip -netns "${nsname}" -6 route \443		add unreachable default metric 4278198272 \444		vrf "${VRF_DEVNAME}"445 446	ip -netns "${nsname}" -4 route \447		add unreachable default metric 4278198272 \448		vrf "${VRF_DEVNAME}"449}450 451# build and install the SRv6 policy into the ingress SRv6 router.452# args:453#  $1 - destination host (i.e. cafe::x host)454#  $2 - SRv6 router configured for enforcing the SRv6 Policy455#  $3 - SRv6 routers configured for steering traffic (End behaviors)456#  $4 - SRv6 router configured for removing the SRv6 Policy (router connected457#       to the destination host)458#  $5 - encap mode (full or red)459#  $6 - traffic type (IPv6 or IPv4)460__setup_rt_policy()461{462	local dst="$1"463	local encap_rt="$2"464	local end_rts="$3"465	local dec_rt="$4"466	local mode="$5"467	local traffic="$6"468	local nsname469	local policy=''470	local n471 472	nsname="$(get_rtname "${encap_rt}")"473 474	for n in ${end_rts}; do475		policy="${policy}${VPN_LOCATOR_SERVICE}:${n}::${END_FUNC},"476	done477 478	policy="${policy}${VPN_LOCATOR_SERVICE}:${dec_rt}::${DT46_FUNC}"479 480	# add SRv6 policy to incoming traffic sent by connected hosts481	if [ "${traffic}" -eq 6 ]; then482		ip -netns "${nsname}" -6 route \483			add "${IPv6_HS_NETWORK}::${dst}" vrf "${VRF_DEVNAME}" \484			encap seg6 mode "${mode}" segs "${policy}" \485			dev "${VRF_DEVNAME}"486 487		ip -netns "${nsname}" -6 neigh \488			add proxy "${IPv6_HS_NETWORK}::${dst}" \489			dev "${RT2HS_DEVNAME}"490	else491		# "dev" must be different from the one where the packet is492		# received, otherwise the proxy arp does not work.493		ip -netns "${nsname}" -4 route \494			add "${IPv4_HS_NETWORK}.${dst}" vrf "${VRF_DEVNAME}" \495			encap seg6 mode "${mode}" segs "${policy}" \496			dev "${VRF_DEVNAME}"497	fi498}499 500# see __setup_rt_policy501setup_rt_policy_ipv6()502{503	__setup_rt_policy "$1" "$2" "$3" "$4" "$5" 6504}505 506#see __setup_rt_policy507setup_rt_policy_ipv4()508{509	__setup_rt_policy "$1" "$2" "$3" "$4" "$5" 4510}511 512setup_hs()513{514	local hs="$1"515	local rt="$2"516	local hsname517	local rtname518 519	hsname="$(get_hsname "${hs}")"520	rtname="$(get_rtname "${rt}")"521 522	ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.all.accept_dad=0523	ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.default.accept_dad=0524 525	ip -netns "${hsname}" link add veth0 type veth \526		peer name "${RT2HS_DEVNAME}" netns "${rtname}"527 528	ip -netns "${hsname}" addr \529		add "${IPv6_HS_NETWORK}::${hs}/64" dev veth0 nodad530	ip -netns "${hsname}" addr add "${IPv4_HS_NETWORK}.${hs}/24" dev veth0531 532	ip -netns "${hsname}" link set veth0 up533	ip -netns "${hsname}" link set lo up534 535	# configure the VRF on the router which is directly connected to the536	# source host.537	ip -netns "${rtname}" link \538		add "${VRF_DEVNAME}" type vrf table "${VRF_TID}"539	ip -netns "${rtname}" link set "${VRF_DEVNAME}" up540 541	# enslave the veth interface connecting the router with the host to the542	# VRF in the access router543	ip -netns "${rtname}" link \544		set "${RT2HS_DEVNAME}" master "${VRF_DEVNAME}"545 546	ip -netns "${rtname}" addr \547		add "${IPv6_HS_NETWORK}::254/64" dev "${RT2HS_DEVNAME}" nodad548	ip -netns "${rtname}" addr \549		add "${IPv4_HS_NETWORK}.254/24" dev "${RT2HS_DEVNAME}"550 551	ip -netns "${rtname}" link set "${RT2HS_DEVNAME}" up552 553	ip netns exec "${rtname}" \554		sysctl -wq net.ipv6.conf."${RT2HS_DEVNAME}".proxy_ndp=1555	ip netns exec "${rtname}" \556		sysctl -wq net.ipv4.conf."${RT2HS_DEVNAME}".proxy_arp=1557 558	# disable the rp_filter otherwise the kernel gets confused about how559	# to route decap ipv4 packets.560	ip netns exec "${rtname}" \561		sysctl -wq net.ipv4.conf."${RT2HS_DEVNAME}".rp_filter=0562 563	ip netns exec "${rtname}" sh -c "echo 1 > /proc/sys/net/vrf/strict_mode"564}565 566setup()567{568	local i569 570	# create routers571	ROUTERS="1 2 3 4"; readonly ROUTERS572	for i in ${ROUTERS}; do573		create_router "${i}"574	done575 576	# create hosts577	HOSTS="1 2 3 4"; readonly HOSTS578	for i in ${HOSTS}; do579		create_host "${i}"580	done581 582	# set up the links for connecting routers583	add_link_rt_pairs 1 "2 3 4"584	add_link_rt_pairs 2 "3 4"585	add_link_rt_pairs 3 "4"586 587	# set up the basic connectivity of routers and routes required for588	# reachability of SIDs.589	setup_rt_networking 1 "2 3 4"590	setup_rt_networking 2 "1 3 4"591	setup_rt_networking 3 "1 2 4"592	setup_rt_networking 4 "1 2 3"593 594	# set up the hosts connected to routers595	setup_hs 1 1596	setup_hs 2 2597	setup_hs 3 3598	setup_hs 4 4599 600	# set up default SRv6 Endpoints (i.e. SRv6 End and SRv6 End.DT46)601	setup_rt_local_sids 1 "2 3 4"602	setup_rt_local_sids 2 "1 3 4"603	setup_rt_local_sids 3 "1 2 4"604	setup_rt_local_sids 4 "1 2 3"605 606	# set up SRv6 policies607 608	# create an IPv6 VPN between hosts hs-1 and hs-2.609	# the network path between hs-1 and hs-2 traverses several routers610	# depending on the direction of traffic.611	#612	# Direction hs-1 -> hs-2 (H.Encaps.Red)613	#  - rt-3,rt-4 (SRv6 End behaviors)614	#  - rt-2 (SRv6 End.DT46 behavior)615	#616	# Direction hs-2 -> hs-1 (H.Encaps.Red)617	#  - rt-1 (SRv6 End.DT46 behavior)618	setup_rt_policy_ipv6 2 1 "3 4" 2 encap.red619	setup_rt_policy_ipv6 1 2 "" 1 encap.red620 621	# create an IPv4 VPN between hosts hs-1 and hs-2622	# the network path between hs-1 and hs-2 traverses several routers623	# depending on the direction of traffic.624	#625	# Direction hs-1 -> hs-2 (H.Encaps.Red)626	# - rt-2 (SRv6 End.DT46 behavior)627	#628	# Direction hs-2 -> hs-1 (H.Encaps.Red)629	#  - rt-4,rt-3 (SRv6 End behaviors)630	#  - rt-1 (SRv6 End.DT46 behavior)631	setup_rt_policy_ipv4 2 1 "" 2 encap.red632	setup_rt_policy_ipv4 1 2 "4 3" 1 encap.red633 634	# create an IPv6 VPN between hosts hs-3 and hs-4635	# the network path between hs-3 and hs-4 traverses several routers636	# depending on the direction of traffic.637	#638	# Direction hs-3 -> hs-4 (H.Encaps.Red)639	# - rt-2 (SRv6 End Behavior)640	# - rt-4 (SRv6 End.DT46 behavior)641	#642	# Direction hs-4 -> hs-3 (H.Encaps.Red)643	#  - rt-1 (SRv6 End behavior)644	#  - rt-3 (SRv6 End.DT46 behavior)645	setup_rt_policy_ipv6 4 3 "2" 4 encap.red646	setup_rt_policy_ipv6 3 4 "1" 3 encap.red647 648	# testing environment was set up successfully649	SETUP_ERR=0650}651 652check_rt_connectivity()653{654	local rtsrc="$1"655	local rtdst="$2"656	local prefix657	local rtsrc_nsname658 659	rtsrc_nsname="$(get_rtname "${rtsrc}")"660 661	prefix="$(get_network_prefix "${rtsrc}" "${rtdst}")"662 663	ip netns exec "${rtsrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \664		"${prefix}::${rtdst}" >/dev/null 2>&1665}666 667check_and_log_rt_connectivity()668{669	local rtsrc="$1"670	local rtdst="$2"671 672	check_rt_connectivity "${rtsrc}" "${rtdst}"673	log_test $? 0 "Routers connectivity: rt-${rtsrc} -> rt-${rtdst}"674}675 676check_hs_ipv6_connectivity()677{678	local hssrc="$1"679	local hsdst="$2"680	local hssrc_nsname681 682	hssrc_nsname="$(get_hsname "${hssrc}")"683 684	ip netns exec "${hssrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \685		"${IPv6_HS_NETWORK}::${hsdst}" >/dev/null 2>&1686}687 688check_hs_ipv4_connectivity()689{690	local hssrc="$1"691	local hsdst="$2"692	local hssrc_nsname693 694	hssrc_nsname="$(get_hsname "${hssrc}")"695 696	ip netns exec "${hssrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \697		"${IPv4_HS_NETWORK}.${hsdst}" >/dev/null 2>&1698}699 700check_and_log_hs2gw_connectivity()701{702	local hssrc="$1"703 704	check_hs_ipv6_connectivity "${hssrc}" 254705	log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> gw"706 707	check_hs_ipv4_connectivity "${hssrc}" 254708	log_test $? 0 "IPv4 Hosts connectivity: hs-${hssrc} -> gw"709}710 711check_and_log_hs_ipv6_connectivity()712{713	local hssrc="$1"714	local hsdst="$2"715 716	check_hs_ipv6_connectivity "${hssrc}" "${hsdst}"717	log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}"718}719 720check_and_log_hs_ipv4_connectivity()721{722	local hssrc="$1"723	local hsdst="$2"724 725	check_hs_ipv4_connectivity "${hssrc}" "${hsdst}"726	log_test $? 0 "IPv4 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}"727}728 729check_and_log_hs_connectivity()730{731	local hssrc="$1"732	local hsdst="$2"733 734	check_and_log_hs_ipv4_connectivity "${hssrc}" "${hsdst}"735	check_and_log_hs_ipv6_connectivity "${hssrc}" "${hsdst}"736}737 738check_and_log_hs_ipv6_isolation()739{740	local hssrc="$1"741	local hsdst="$2"742 743	# in this case, the connectivity test must fail744	check_hs_ipv6_connectivity "${hssrc}" "${hsdst}"745	log_test $? 1 "IPv6 Hosts isolation: hs-${hssrc} -X-> hs-${hsdst}"746}747 748check_and_log_hs_ipv4_isolation()749{750	local hssrc="$1"751	local hsdst="$2"752 753	# in this case, the connectivity test must fail754	check_hs_ipv4_connectivity "${hssrc}" "${hsdst}"755	log_test $? 1 "IPv4 Hosts isolation: hs-${hssrc} -X-> hs-${hsdst}"756}757 758check_and_log_hs_isolation()759{760	local hssrc="$1"761	local hsdst="$2"762 763	check_and_log_hs_ipv6_isolation "${hssrc}" "${hsdst}"764	check_and_log_hs_ipv4_isolation "${hssrc}" "${hsdst}"765}766 767router_tests()768{769	local i770	local j771 772	log_section "IPv6 routers connectivity test"773 774	for i in ${ROUTERS}; do775		for j in ${ROUTERS}; do776			if [ "${i}" -eq "${j}" ]; then777				continue778			fi779 780			check_and_log_rt_connectivity "${i}" "${j}"781		done782	done783}784 785host2gateway_tests()786{787	local hs788 789	log_section "IPv4/IPv6 connectivity test among hosts and gateways"790 791	for hs in ${HOSTS}; do792		check_and_log_hs2gw_connectivity "${hs}"793	done794}795 796host_vpn_tests()797{798	log_section "SRv6 VPN connectivity test hosts (h1 <-> h2, IPv4/IPv6)"799 800	check_and_log_hs_connectivity 1 2801	check_and_log_hs_connectivity 2 1802 803	log_section "SRv6 VPN connectivity test hosts (h3 <-> h4, IPv6 only)"804 805	check_and_log_hs_ipv6_connectivity 3 4806	check_and_log_hs_ipv6_connectivity 4 3807}808 809host_vpn_isolation_tests()810{811	local l1="1 2"812	local l2="3 4"813	local tmp814	local i815	local j816	local k817 818	log_section "SRv6 VPN isolation test among hosts"819 820	for k in 0 1; do821		for i in ${l1}; do822			for j in ${l2}; do823				check_and_log_hs_isolation "${i}" "${j}"824			done825		done826 827		# let us test the reverse path828		tmp="${l1}"; l1="${l2}"; l2="${tmp}"829	done830 831	log_section "SRv6 VPN isolation test among hosts (h2 <-> h4, IPv4 only)"832 833	check_and_log_hs_ipv4_isolation 2 4834	check_and_log_hs_ipv4_isolation 4 2835}836 837test_iproute2_supp_or_ksft_skip()838{839	if ! ip route help 2>&1 | grep -qo "encap.red"; then840		echo "SKIP: Missing SRv6 encap.red support in iproute2"841		exit "${ksft_skip}"842	fi843}844 845test_vrf_or_ksft_skip()846{847	modprobe vrf &>/dev/null || true848	if [ ! -e /proc/sys/net/vrf/strict_mode ]; then849		echo "SKIP: vrf sysctl does not exist"850		exit "${ksft_skip}"851	fi852}853 854if [ "$(id -u)" -ne 0 ]; then855	echo "SKIP: Need root privileges"856	exit "${ksft_skip}"857fi858 859# required programs to carry out this selftest860test_command_or_ksft_skip ip861test_command_or_ksft_skip ping862test_command_or_ksft_skip sysctl863test_command_or_ksft_skip grep864 865test_iproute2_supp_or_ksft_skip866test_vrf_or_ksft_skip867 868set -e869trap cleanup EXIT870 871setup872set +e873 874router_tests875host2gateway_tests876host_vpn_tests877host_vpn_isolation_tests878 879print_log_test_results880