xref: /linux/tools/testing/selftests/net/srv6_hencap_red_l3vpn_test.sh (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*6ab4eb5aSAndrea Mayer#!/bin/bash
2*6ab4eb5aSAndrea Mayer# SPDX-License-Identifier: GPL-2.0
3*6ab4eb5aSAndrea Mayer#
4*6ab4eb5aSAndrea Mayer# author: Andrea Mayer <andrea.mayer@uniroma2.it>
5*6ab4eb5aSAndrea Mayer#
6*6ab4eb5aSAndrea Mayer# This script is designed for testing the SRv6 H.Encaps.Red behavior.
7*6ab4eb5aSAndrea Mayer#
8*6ab4eb5aSAndrea Mayer# Below is depicted the IPv6 network of an operator which offers advanced
9*6ab4eb5aSAndrea Mayer# IPv4/IPv6 VPN services to hosts, enabling them to communicate with each
10*6ab4eb5aSAndrea Mayer# other.
11*6ab4eb5aSAndrea Mayer# In this example, hosts hs-1 and hs-2 are connected through an IPv4/IPv6 VPN
12*6ab4eb5aSAndrea Mayer# service, while hs-3 and hs-4 are connected using an IPv6 only VPN.
13*6ab4eb5aSAndrea Mayer#
14*6ab4eb5aSAndrea Mayer# Routers rt-1,rt-2,rt-3 and rt-4 implement IPv4/IPv6 L3 VPN services
15*6ab4eb5aSAndrea Mayer# leveraging the SRv6 architecture. The key components for such VPNs are:
16*6ab4eb5aSAndrea Mayer#
17*6ab4eb5aSAndrea Mayer#   i) The SRv6 H.Encaps.Red behavior applies SRv6 Policies on traffic received
18*6ab4eb5aSAndrea Mayer#      by connected hosts, initiating the VPN tunnel. Such a behavior is an
19*6ab4eb5aSAndrea Mayer#      optimization of the SRv6 H.Encap aiming to reduce the length of the SID
20*6ab4eb5aSAndrea Mayer#      List carried in the pushed SRH. Specifically, the H.Encaps.Red removes
21*6ab4eb5aSAndrea Mayer#      the first SID contained in the SID List (i.e. SRv6 Policy) by storing it
22*6ab4eb5aSAndrea Mayer#      into the IPv6 Destination Address. When a SRv6 Policy is made of only one
23*6ab4eb5aSAndrea Mayer#      SID, the SRv6 H.Encaps.Red behavior omits the SRH at all and pushes that
24*6ab4eb5aSAndrea Mayer#      SID directly into the IPv6 DA;
25*6ab4eb5aSAndrea Mayer#
26*6ab4eb5aSAndrea Mayer#  ii) The SRv6 End behavior advances the active SID in the SID List carried by
27*6ab4eb5aSAndrea Mayer#      the SRH;
28*6ab4eb5aSAndrea Mayer#
29*6ab4eb5aSAndrea Mayer# iii) The SRv6 End.DT46 behavior is used for removing the SRv6 Policy and,
30*6ab4eb5aSAndrea Mayer#      thus, it terminates the VPN tunnel. Such a behavior is capable of
31*6ab4eb5aSAndrea Mayer#      handling, at the same time, both tunneled IPv4 and IPv6 traffic.
32*6ab4eb5aSAndrea Mayer#
33*6ab4eb5aSAndrea Mayer#
34*6ab4eb5aSAndrea Mayer#               cafe::1                      cafe::2
35*6ab4eb5aSAndrea Mayer#              10.0.0.1                     10.0.0.2
36*6ab4eb5aSAndrea Mayer#             +--------+                   +--------+
37*6ab4eb5aSAndrea Mayer#             |        |                   |        |
38*6ab4eb5aSAndrea Mayer#             |  hs-1  |                   |  hs-2  |
39*6ab4eb5aSAndrea Mayer#             |        |                   |        |
40*6ab4eb5aSAndrea Mayer#             +---+----+                   +--- +---+
41*6ab4eb5aSAndrea Mayer#    cafe::/64    |                             |      cafe::/64
42*6ab4eb5aSAndrea Mayer#  10.0.0.0/24    |                             |    10.0.0.0/24
43*6ab4eb5aSAndrea Mayer#             +---+----+                   +----+---+
44*6ab4eb5aSAndrea Mayer#             |        |  fcf0:0:1:2::/64  |        |
45*6ab4eb5aSAndrea Mayer#             |  rt-1  +-------------------+  rt-2  |
46*6ab4eb5aSAndrea Mayer#             |        |                   |        |
47*6ab4eb5aSAndrea Mayer#             +---+----+                   +----+---+
48*6ab4eb5aSAndrea Mayer#                 |      .               .      |
49*6ab4eb5aSAndrea Mayer#                 |  fcf0:0:1:3::/64   .        |
50*6ab4eb5aSAndrea Mayer#                 |          .       .          |
51*6ab4eb5aSAndrea Mayer#                 |            .   .            |
52*6ab4eb5aSAndrea Mayer# fcf0:0:1:4::/64 |              .              | fcf0:0:2:3::/64
53*6ab4eb5aSAndrea Mayer#                 |            .   .            |
54*6ab4eb5aSAndrea Mayer#                 |          .       .          |
55*6ab4eb5aSAndrea Mayer#                 |  fcf0:0:2:4::/64   .        |
56*6ab4eb5aSAndrea Mayer#                 |      .               .      |
57*6ab4eb5aSAndrea Mayer#             +---+----+                   +----+---+
58*6ab4eb5aSAndrea Mayer#             |        |                   |        |
59*6ab4eb5aSAndrea Mayer#             |  rt-4  +-------------------+  rt-3  |
60*6ab4eb5aSAndrea Mayer#             |        |  fcf0:0:3:4::/64  |        |
61*6ab4eb5aSAndrea Mayer#             +---+----+                   +----+---+
62*6ab4eb5aSAndrea Mayer#    cafe::/64    |                             |      cafe::/64
63*6ab4eb5aSAndrea Mayer#  10.0.0.0/24    |                             |    10.0.0.0/24
64*6ab4eb5aSAndrea Mayer#             +---+----+                   +--- +---+
65*6ab4eb5aSAndrea Mayer#             |        |                   |        |
66*6ab4eb5aSAndrea Mayer#             |  hs-4  |                   |  hs-3  |
67*6ab4eb5aSAndrea Mayer#             |        |                   |        |
68*6ab4eb5aSAndrea Mayer#             +--------+                   +--------+
69*6ab4eb5aSAndrea Mayer#               cafe::4                      cafe::3
70*6ab4eb5aSAndrea Mayer#              10.0.0.4                     10.0.0.3
71*6ab4eb5aSAndrea Mayer#
72*6ab4eb5aSAndrea Mayer#
73*6ab4eb5aSAndrea Mayer# Every fcf0:0:x:y::/64 network interconnects the SRv6 routers rt-x with rt-y
74*6ab4eb5aSAndrea Mayer# in the IPv6 operator network.
75*6ab4eb5aSAndrea Mayer#
76*6ab4eb5aSAndrea Mayer# Local SID table
77*6ab4eb5aSAndrea Mayer# ===============
78*6ab4eb5aSAndrea Mayer#
79*6ab4eb5aSAndrea Mayer# Each SRv6 router is configured with a Local SID table in which SIDs are
80*6ab4eb5aSAndrea Mayer# stored. Considering the given SRv6 router rt-x, at least two SIDs are
81*6ab4eb5aSAndrea Mayer# configured in the Local SID table:
82*6ab4eb5aSAndrea Mayer#
83*6ab4eb5aSAndrea Mayer#   Local SID table for SRv6 router rt-x
84*6ab4eb5aSAndrea Mayer#   +----------------------------------------------------------+
85*6ab4eb5aSAndrea Mayer#   |fcff:x::e is associated with the SRv6 End behavior        |
86*6ab4eb5aSAndrea Mayer#   |fcff:x::d46 is associated with the SRv6 End.DT46 behavior |
87*6ab4eb5aSAndrea Mayer#   +----------------------------------------------------------+
88*6ab4eb5aSAndrea Mayer#
89*6ab4eb5aSAndrea Mayer# The fcff::/16 prefix is reserved by the operator for implementing SRv6 VPN
90*6ab4eb5aSAndrea Mayer# services. Reachability of SIDs is ensured by proper configuration of the IPv6
91*6ab4eb5aSAndrea Mayer# operator's network and SRv6 routers.
92*6ab4eb5aSAndrea Mayer#
93*6ab4eb5aSAndrea Mayer# # SRv6 Policies
94*6ab4eb5aSAndrea Mayer# ===============
95*6ab4eb5aSAndrea Mayer#
96*6ab4eb5aSAndrea Mayer# An SRv6 ingress router applies SRv6 policies to the traffic received from a
97*6ab4eb5aSAndrea Mayer# connected host. SRv6 policy enforcement consists of encapsulating the
98*6ab4eb5aSAndrea Mayer# received traffic into a new IPv6 packet with a given SID List contained in
99*6ab4eb5aSAndrea Mayer# the SRH.
100*6ab4eb5aSAndrea Mayer#
101*6ab4eb5aSAndrea Mayer# IPv4/IPv6 VPN between hs-1 and hs-2
102*6ab4eb5aSAndrea Mayer# -----------------------------------
103*6ab4eb5aSAndrea Mayer#
104*6ab4eb5aSAndrea Mayer# Hosts hs-1 and hs-2 are connected using dedicated IPv4/IPv6 VPNs.
105*6ab4eb5aSAndrea Mayer# Specifically, packets generated from hs-1 and directed towards hs-2 are
106*6ab4eb5aSAndrea Mayer# handled by rt-1 which applies the following SRv6 Policies:
107*6ab4eb5aSAndrea Mayer#
108*6ab4eb5aSAndrea Mayer#   i.a) IPv6 traffic, SID List=fcff:3::e,fcff:4::e,fcff:2::d46
109*6ab4eb5aSAndrea Mayer#  ii.a) IPv4 traffic, SID List=fcff:2::d46
110*6ab4eb5aSAndrea Mayer#
111*6ab4eb5aSAndrea Mayer# Policy (i.a) steers tunneled IPv6 traffic through SRv6 routers
112*6ab4eb5aSAndrea Mayer# rt-3,rt-4,rt-2. Instead, Policy (ii.a) steers tunneled IPv4 traffic through
113*6ab4eb5aSAndrea Mayer# rt-2.
114*6ab4eb5aSAndrea Mayer# The H.Encaps.Red reduces the SID List (i.a) carried in SRH by removing the
115*6ab4eb5aSAndrea Mayer# first SID (fcff:3::e) and pushing it into the IPv6 DA. In case of IPv4
116*6ab4eb5aSAndrea Mayer# traffic, the H.Encaps.Red omits the presence of SRH at all, since the SID
117*6ab4eb5aSAndrea Mayer# List (ii.a) consists of only one SID that can be stored directly in the IPv6
118*6ab4eb5aSAndrea Mayer# DA.
119*6ab4eb5aSAndrea Mayer#
120*6ab4eb5aSAndrea Mayer# On the reverse path (i.e. from hs-2 to hs-1), rt-2 applies the following
121*6ab4eb5aSAndrea Mayer# policies:
122*6ab4eb5aSAndrea Mayer#
123*6ab4eb5aSAndrea Mayer#   i.b) IPv6 traffic, SID List=fcff:1::d46
124*6ab4eb5aSAndrea Mayer#  ii.b) IPv4 traffic, SID List=fcff:4::e,fcff:3::e,fcff:1::d46
125*6ab4eb5aSAndrea Mayer#
126*6ab4eb5aSAndrea Mayer# Policy (i.b) steers tunneled IPv6 traffic through the SRv6 router rt-1.
127*6ab4eb5aSAndrea Mayer# Conversely, Policy (ii.b) steers tunneled IPv4 traffic through SRv6 routers
128*6ab4eb5aSAndrea Mayer# rt-4,rt-3,rt-1.
129*6ab4eb5aSAndrea Mayer# The H.Encaps.Red omits the SRH at all in case of (i.b) by pushing the single
130*6ab4eb5aSAndrea Mayer# SID (fcff::1::d46) inside the IPv6 DA.
131*6ab4eb5aSAndrea Mayer# The H.Encaps.Red reduces the SID List (ii.b) in the SRH by removing the first
132*6ab4eb5aSAndrea Mayer# SID (fcff:4::e) and pushing it into the IPv6 DA.
133*6ab4eb5aSAndrea Mayer#
134*6ab4eb5aSAndrea Mayer# In summary:
135*6ab4eb5aSAndrea Mayer#  hs-1->hs-2 |IPv6 DA=fcff:3::e|SRH SIDs=fcff:4::e,fcff:2::d46|IPv6|...| (i.a)
136*6ab4eb5aSAndrea Mayer#  hs-1->hs-2 |IPv6 DA=fcff:2::d46|IPv4|...|                              (ii.a)
137*6ab4eb5aSAndrea Mayer#
138*6ab4eb5aSAndrea Mayer#  hs-2->hs-1 |IPv6 DA=fcff:1::d46|IPv6|...|                              (i.b)
139*6ab4eb5aSAndrea Mayer#  hs-2->hs-1 |IPv6 DA=fcff:4::e|SRH SIDs=fcff:3::e,fcff:1::d46|IPv4|...| (ii.b)
140*6ab4eb5aSAndrea Mayer#
141*6ab4eb5aSAndrea Mayer#
142*6ab4eb5aSAndrea Mayer# IPv6 VPN between hs-3 and hs-4
143*6ab4eb5aSAndrea Mayer# ------------------------------
144*6ab4eb5aSAndrea Mayer#
145*6ab4eb5aSAndrea Mayer# Hosts hs-3 and hs-4 are connected using a dedicated IPv6 only VPN.
146*6ab4eb5aSAndrea Mayer# Specifically, packets generated from hs-3 and directed towards hs-4 are
147*6ab4eb5aSAndrea Mayer# handled by rt-3 which applies the following SRv6 Policy:
148*6ab4eb5aSAndrea Mayer#
149*6ab4eb5aSAndrea Mayer#  i.c) IPv6 traffic, SID List=fcff:2::e,fcff:4::d46
150*6ab4eb5aSAndrea Mayer#
151*6ab4eb5aSAndrea Mayer# Policy (i.c) steers tunneled IPv6 traffic through SRv6 routers rt-2,rt-4.
152*6ab4eb5aSAndrea Mayer# The H.Encaps.Red reduces the SID List (i.c) carried in SRH by pushing the
153*6ab4eb5aSAndrea Mayer# first SID (fcff:2::e) in the IPv6 DA.
154*6ab4eb5aSAndrea Mayer#
155*6ab4eb5aSAndrea Mayer# On the reverse path (i.e. from hs-4 to hs-3) the router rt-4 applies the
156*6ab4eb5aSAndrea Mayer# following SRv6 Policy:
157*6ab4eb5aSAndrea Mayer#
158*6ab4eb5aSAndrea Mayer#  i.d) IPv6 traffic, SID List=fcff:1::e,fcff:3::d46.
159*6ab4eb5aSAndrea Mayer#
160*6ab4eb5aSAndrea Mayer# Policy (i.d) steers tunneled IPv6 traffic through SRv6 routers rt-1,rt-3.
161*6ab4eb5aSAndrea Mayer# The H.Encaps.Red reduces the SID List (i.d) carried in SRH by pushing the
162*6ab4eb5aSAndrea Mayer# first SID (fcff:1::e) in the IPv6 DA.
163*6ab4eb5aSAndrea Mayer#
164*6ab4eb5aSAndrea Mayer# In summary:
165*6ab4eb5aSAndrea Mayer#  hs-3->hs-4 |IPv6 DA=fcff:2::e|SRH SIDs=fcff:4::d46|IPv6|...| (i.c)
166*6ab4eb5aSAndrea Mayer#  hs-4->hs-3 |IPv6 DA=fcff:1::e|SRH SIDs=fcff:3::d46|IPv6|...| (i.d)
167*6ab4eb5aSAndrea Mayer#
168*6ab4eb5aSAndrea Mayer
169*6ab4eb5aSAndrea Mayer# Kselftest framework requirement - SKIP code is 4.
170*6ab4eb5aSAndrea Mayerreadonly ksft_skip=4
171*6ab4eb5aSAndrea Mayer
172*6ab4eb5aSAndrea Mayerreadonly RDMSUFF="$(mktemp -u XXXXXXXX)"
173*6ab4eb5aSAndrea Mayerreadonly VRF_TID=100
174*6ab4eb5aSAndrea Mayerreadonly VRF_DEVNAME="vrf-${VRF_TID}"
175*6ab4eb5aSAndrea Mayerreadonly RT2HS_DEVNAME="veth-t${VRF_TID}"
176*6ab4eb5aSAndrea Mayerreadonly LOCALSID_TABLE_ID=90
177*6ab4eb5aSAndrea Mayerreadonly IPv6_RT_NETWORK=fcf0:0
178*6ab4eb5aSAndrea Mayerreadonly IPv6_HS_NETWORK=cafe
179*6ab4eb5aSAndrea Mayerreadonly IPv4_HS_NETWORK=10.0.0
180*6ab4eb5aSAndrea Mayerreadonly VPN_LOCATOR_SERVICE=fcff
181*6ab4eb5aSAndrea Mayerreadonly END_FUNC=000e
182*6ab4eb5aSAndrea Mayerreadonly DT46_FUNC=0d46
183*6ab4eb5aSAndrea Mayer
184*6ab4eb5aSAndrea MayerPING_TIMEOUT_SEC=4
185*6ab4eb5aSAndrea MayerPAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
186*6ab4eb5aSAndrea Mayer
187*6ab4eb5aSAndrea Mayer# IDs of routers and hosts are initialized during the setup of the testing
188*6ab4eb5aSAndrea Mayer# network
189*6ab4eb5aSAndrea MayerROUTERS=''
190*6ab4eb5aSAndrea MayerHOSTS=''
191*6ab4eb5aSAndrea Mayer
192*6ab4eb5aSAndrea MayerSETUP_ERR=1
193*6ab4eb5aSAndrea Mayer
194*6ab4eb5aSAndrea Mayerret=${ksft_skip}
195*6ab4eb5aSAndrea Mayernsuccess=0
196*6ab4eb5aSAndrea Mayernfail=0
197*6ab4eb5aSAndrea Mayer
198*6ab4eb5aSAndrea Mayerlog_test()
199*6ab4eb5aSAndrea Mayer{
200*6ab4eb5aSAndrea Mayer	local rc="$1"
201*6ab4eb5aSAndrea Mayer	local expected="$2"
202*6ab4eb5aSAndrea Mayer	local msg="$3"
203*6ab4eb5aSAndrea Mayer
204*6ab4eb5aSAndrea Mayer	if [ "${rc}" -eq "${expected}" ]; then
205*6ab4eb5aSAndrea Mayer		nsuccess=$((nsuccess+1))
206*6ab4eb5aSAndrea Mayer		printf "\n    TEST: %-60s  [ OK ]\n" "${msg}"
207*6ab4eb5aSAndrea Mayer	else
208*6ab4eb5aSAndrea Mayer		ret=1
209*6ab4eb5aSAndrea Mayer		nfail=$((nfail+1))
210*6ab4eb5aSAndrea Mayer		printf "\n    TEST: %-60s  [FAIL]\n" "${msg}"
211*6ab4eb5aSAndrea Mayer		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
212*6ab4eb5aSAndrea Mayer			echo
213*6ab4eb5aSAndrea Mayer			echo "hit enter to continue, 'q' to quit"
214*6ab4eb5aSAndrea Mayer			read a
215*6ab4eb5aSAndrea Mayer			[ "$a" = "q" ] && exit 1
216*6ab4eb5aSAndrea Mayer		fi
217*6ab4eb5aSAndrea Mayer	fi
218*6ab4eb5aSAndrea Mayer}
219*6ab4eb5aSAndrea Mayer
220*6ab4eb5aSAndrea Mayerprint_log_test_results()
221*6ab4eb5aSAndrea Mayer{
222*6ab4eb5aSAndrea Mayer	printf "\nTests passed: %3d\n" "${nsuccess}"
223*6ab4eb5aSAndrea Mayer	printf "Tests failed: %3d\n"   "${nfail}"
224*6ab4eb5aSAndrea Mayer
225*6ab4eb5aSAndrea Mayer	# when a test fails, the value of 'ret' is set to 1 (error code).
226*6ab4eb5aSAndrea Mayer	# Conversely, when all tests are passed successfully, the 'ret' value
227*6ab4eb5aSAndrea Mayer	# is set to 0 (success code).
228*6ab4eb5aSAndrea Mayer	if [ "${ret}" -ne 1 ]; then
229*6ab4eb5aSAndrea Mayer		ret=0
230*6ab4eb5aSAndrea Mayer	fi
231*6ab4eb5aSAndrea Mayer}
232*6ab4eb5aSAndrea Mayer
233*6ab4eb5aSAndrea Mayerlog_section()
234*6ab4eb5aSAndrea Mayer{
235*6ab4eb5aSAndrea Mayer	echo
236*6ab4eb5aSAndrea Mayer	echo "################################################################################"
237*6ab4eb5aSAndrea Mayer	echo "TEST SECTION: $*"
238*6ab4eb5aSAndrea Mayer	echo "################################################################################"
239*6ab4eb5aSAndrea Mayer}
240*6ab4eb5aSAndrea Mayer
241*6ab4eb5aSAndrea Mayertest_command_or_ksft_skip()
242*6ab4eb5aSAndrea Mayer{
243*6ab4eb5aSAndrea Mayer	local cmd="$1"
244*6ab4eb5aSAndrea Mayer
245*6ab4eb5aSAndrea Mayer	if [ ! -x "$(command -v "${cmd}")" ]; then
246*6ab4eb5aSAndrea Mayer		echo "SKIP: Could not run test without \"${cmd}\" tool";
247*6ab4eb5aSAndrea Mayer		exit "${ksft_skip}"
248*6ab4eb5aSAndrea Mayer	fi
249*6ab4eb5aSAndrea Mayer}
250*6ab4eb5aSAndrea Mayer
251*6ab4eb5aSAndrea Mayerget_nodename()
252*6ab4eb5aSAndrea Mayer{
253*6ab4eb5aSAndrea Mayer	local name="$1"
254*6ab4eb5aSAndrea Mayer
255*6ab4eb5aSAndrea Mayer	echo "${name}-${RDMSUFF}"
256*6ab4eb5aSAndrea Mayer}
257*6ab4eb5aSAndrea Mayer
258*6ab4eb5aSAndrea Mayerget_rtname()
259*6ab4eb5aSAndrea Mayer{
260*6ab4eb5aSAndrea Mayer	local rtid="$1"
261*6ab4eb5aSAndrea Mayer
262*6ab4eb5aSAndrea Mayer	get_nodename "rt-${rtid}"
263*6ab4eb5aSAndrea Mayer}
264*6ab4eb5aSAndrea Mayer
265*6ab4eb5aSAndrea Mayerget_hsname()
266*6ab4eb5aSAndrea Mayer{
267*6ab4eb5aSAndrea Mayer	local hsid="$1"
268*6ab4eb5aSAndrea Mayer
269*6ab4eb5aSAndrea Mayer	get_nodename "hs-${hsid}"
270*6ab4eb5aSAndrea Mayer}
271*6ab4eb5aSAndrea Mayer
272*6ab4eb5aSAndrea Mayer__create_namespace()
273*6ab4eb5aSAndrea Mayer{
274*6ab4eb5aSAndrea Mayer	local name="$1"
275*6ab4eb5aSAndrea Mayer
276*6ab4eb5aSAndrea Mayer	ip netns add "${name}"
277*6ab4eb5aSAndrea Mayer}
278*6ab4eb5aSAndrea Mayer
279*6ab4eb5aSAndrea Mayercreate_router()
280*6ab4eb5aSAndrea Mayer{
281*6ab4eb5aSAndrea Mayer	local rtid="$1"
282*6ab4eb5aSAndrea Mayer	local nsname
283*6ab4eb5aSAndrea Mayer
284*6ab4eb5aSAndrea Mayer	nsname="$(get_rtname "${rtid}")"
285*6ab4eb5aSAndrea Mayer
286*6ab4eb5aSAndrea Mayer	__create_namespace "${nsname}"
287*6ab4eb5aSAndrea Mayer}
288*6ab4eb5aSAndrea Mayer
289*6ab4eb5aSAndrea Mayercreate_host()
290*6ab4eb5aSAndrea Mayer{
291*6ab4eb5aSAndrea Mayer	local hsid="$1"
292*6ab4eb5aSAndrea Mayer	local nsname
293*6ab4eb5aSAndrea Mayer
294*6ab4eb5aSAndrea Mayer	nsname="$(get_hsname "${hsid}")"
295*6ab4eb5aSAndrea Mayer
296*6ab4eb5aSAndrea Mayer	__create_namespace "${nsname}"
297*6ab4eb5aSAndrea Mayer}
298*6ab4eb5aSAndrea Mayer
299*6ab4eb5aSAndrea Mayercleanup()
300*6ab4eb5aSAndrea Mayer{
301*6ab4eb5aSAndrea Mayer	local nsname
302*6ab4eb5aSAndrea Mayer	local i
303*6ab4eb5aSAndrea Mayer
304*6ab4eb5aSAndrea Mayer	# destroy routers
305*6ab4eb5aSAndrea Mayer	for i in ${ROUTERS}; do
306*6ab4eb5aSAndrea Mayer		nsname="$(get_rtname "${i}")"
307*6ab4eb5aSAndrea Mayer
308*6ab4eb5aSAndrea Mayer		ip netns del "${nsname}" &>/dev/null || true
309*6ab4eb5aSAndrea Mayer	done
310*6ab4eb5aSAndrea Mayer
311*6ab4eb5aSAndrea Mayer	# destroy hosts
312*6ab4eb5aSAndrea Mayer	for i in ${HOSTS}; do
313*6ab4eb5aSAndrea Mayer		nsname="$(get_hsname "${i}")"
314*6ab4eb5aSAndrea Mayer
315*6ab4eb5aSAndrea Mayer		ip netns del "${nsname}" &>/dev/null || true
316*6ab4eb5aSAndrea Mayer	done
317*6ab4eb5aSAndrea Mayer
318*6ab4eb5aSAndrea Mayer	# check whether the setup phase was completed successfully or not. In
319*6ab4eb5aSAndrea Mayer	# case of an error during the setup phase of the testing environment,
320*6ab4eb5aSAndrea Mayer	# the selftest is considered as "skipped".
321*6ab4eb5aSAndrea Mayer	if [ "${SETUP_ERR}" -ne 0 ]; then
322*6ab4eb5aSAndrea Mayer		echo "SKIP: Setting up the testing environment failed"
323*6ab4eb5aSAndrea Mayer		exit "${ksft_skip}"
324*6ab4eb5aSAndrea Mayer	fi
325*6ab4eb5aSAndrea Mayer
326*6ab4eb5aSAndrea Mayer	exit "${ret}"
327*6ab4eb5aSAndrea Mayer}
328*6ab4eb5aSAndrea Mayer
329*6ab4eb5aSAndrea Mayeradd_link_rt_pairs()
330*6ab4eb5aSAndrea Mayer{
331*6ab4eb5aSAndrea Mayer	local rt="$1"
332*6ab4eb5aSAndrea Mayer	local rt_neighs="$2"
333*6ab4eb5aSAndrea Mayer	local neigh
334*6ab4eb5aSAndrea Mayer	local nsname
335*6ab4eb5aSAndrea Mayer	local neigh_nsname
336*6ab4eb5aSAndrea Mayer
337*6ab4eb5aSAndrea Mayer	nsname="$(get_rtname "${rt}")"
338*6ab4eb5aSAndrea Mayer
339*6ab4eb5aSAndrea Mayer	for neigh in ${rt_neighs}; do
340*6ab4eb5aSAndrea Mayer		neigh_nsname="$(get_rtname "${neigh}")"
341*6ab4eb5aSAndrea Mayer
342*6ab4eb5aSAndrea Mayer		ip link add "veth-rt-${rt}-${neigh}" netns "${nsname}" \
343*6ab4eb5aSAndrea Mayer			type veth peer name "veth-rt-${neigh}-${rt}" \
344*6ab4eb5aSAndrea Mayer			netns "${neigh_nsname}"
345*6ab4eb5aSAndrea Mayer	done
346*6ab4eb5aSAndrea Mayer}
347*6ab4eb5aSAndrea Mayer
348*6ab4eb5aSAndrea Mayerget_network_prefix()
349*6ab4eb5aSAndrea Mayer{
350*6ab4eb5aSAndrea Mayer	local rt="$1"
351*6ab4eb5aSAndrea Mayer	local neigh="$2"
352*6ab4eb5aSAndrea Mayer	local p="${rt}"
353*6ab4eb5aSAndrea Mayer	local q="${neigh}"
354*6ab4eb5aSAndrea Mayer
355*6ab4eb5aSAndrea Mayer	if [ "${p}" -gt "${q}" ]; then
356*6ab4eb5aSAndrea Mayer		p="${q}"; q="${rt}"
357*6ab4eb5aSAndrea Mayer	fi
358*6ab4eb5aSAndrea Mayer
359*6ab4eb5aSAndrea Mayer	echo "${IPv6_RT_NETWORK}:${p}:${q}"
360*6ab4eb5aSAndrea Mayer}
361*6ab4eb5aSAndrea Mayer
362*6ab4eb5aSAndrea Mayer# Setup the basic networking for the routers
363*6ab4eb5aSAndrea Mayersetup_rt_networking()
364*6ab4eb5aSAndrea Mayer{
365*6ab4eb5aSAndrea Mayer	local rt="$1"
366*6ab4eb5aSAndrea Mayer	local rt_neighs="$2"
367*6ab4eb5aSAndrea Mayer	local nsname
368*6ab4eb5aSAndrea Mayer	local net_prefix
369*6ab4eb5aSAndrea Mayer	local devname
370*6ab4eb5aSAndrea Mayer	local neigh
371*6ab4eb5aSAndrea Mayer
372*6ab4eb5aSAndrea Mayer	nsname="$(get_rtname "${rt}")"
373*6ab4eb5aSAndrea Mayer
374*6ab4eb5aSAndrea Mayer	for neigh in ${rt_neighs}; do
375*6ab4eb5aSAndrea Mayer		devname="veth-rt-${rt}-${neigh}"
376*6ab4eb5aSAndrea Mayer
377*6ab4eb5aSAndrea Mayer		net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
378*6ab4eb5aSAndrea Mayer
379*6ab4eb5aSAndrea Mayer		ip -netns "${nsname}" addr \
380*6ab4eb5aSAndrea Mayer			add "${net_prefix}::${rt}/64" dev "${devname}" nodad
381*6ab4eb5aSAndrea Mayer
382*6ab4eb5aSAndrea Mayer		ip -netns "${nsname}" link set "${devname}" up
383*6ab4eb5aSAndrea Mayer	done
384*6ab4eb5aSAndrea Mayer
385*6ab4eb5aSAndrea Mayer	ip -netns "${nsname}" link set lo up
386*6ab4eb5aSAndrea Mayer
387*6ab4eb5aSAndrea Mayer	ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.all.accept_dad=0
388*6ab4eb5aSAndrea Mayer	ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.default.accept_dad=0
389*6ab4eb5aSAndrea Mayer	ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.all.forwarding=1
390*6ab4eb5aSAndrea Mayer
391*6ab4eb5aSAndrea Mayer	ip netns exec "${nsname}" sysctl -wq net.ipv4.conf.all.rp_filter=0
392*6ab4eb5aSAndrea Mayer	ip netns exec "${nsname}" sysctl -wq net.ipv4.conf.default.rp_filter=0
393*6ab4eb5aSAndrea Mayer	ip netns exec "${nsname}" sysctl -wq net.ipv4.ip_forward=1
394*6ab4eb5aSAndrea Mayer}
395*6ab4eb5aSAndrea Mayer
396*6ab4eb5aSAndrea Mayer# Setup local SIDs for an SRv6 router
397*6ab4eb5aSAndrea Mayersetup_rt_local_sids()
398*6ab4eb5aSAndrea Mayer{
399*6ab4eb5aSAndrea Mayer	local rt="$1"
400*6ab4eb5aSAndrea Mayer	local rt_neighs="$2"
401*6ab4eb5aSAndrea Mayer	local net_prefix
402*6ab4eb5aSAndrea Mayer	local devname
403*6ab4eb5aSAndrea Mayer	local nsname
404*6ab4eb5aSAndrea Mayer	local neigh
405*6ab4eb5aSAndrea Mayer
406*6ab4eb5aSAndrea Mayer	nsname="$(get_rtname "${rt}")"
407*6ab4eb5aSAndrea Mayer
408*6ab4eb5aSAndrea Mayer	for neigh in ${rt_neighs}; do
409*6ab4eb5aSAndrea Mayer		devname="veth-rt-${rt}-${neigh}"
410*6ab4eb5aSAndrea Mayer
411*6ab4eb5aSAndrea Mayer		net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
412*6ab4eb5aSAndrea Mayer
413*6ab4eb5aSAndrea Mayer		# set underlay network routes for SIDs reachability
414*6ab4eb5aSAndrea Mayer		ip -netns "${nsname}" -6 route \
415*6ab4eb5aSAndrea Mayer			add "${VPN_LOCATOR_SERVICE}:${neigh}::/32" \
416*6ab4eb5aSAndrea Mayer			table "${LOCALSID_TABLE_ID}" \
417*6ab4eb5aSAndrea Mayer			via "${net_prefix}::${neigh}" dev "${devname}"
418*6ab4eb5aSAndrea Mayer	done
419*6ab4eb5aSAndrea Mayer
420*6ab4eb5aSAndrea Mayer	# Local End behavior (note that "dev" is dummy and the VRF is chosen
421*6ab4eb5aSAndrea Mayer	# for the sake of simplicity).
422*6ab4eb5aSAndrea Mayer	ip -netns "${nsname}" -6 route \
423*6ab4eb5aSAndrea Mayer		add "${VPN_LOCATOR_SERVICE}:${rt}::${END_FUNC}" \
424*6ab4eb5aSAndrea Mayer		table "${LOCALSID_TABLE_ID}" \
425*6ab4eb5aSAndrea Mayer		encap seg6local action End dev "${VRF_DEVNAME}"
426*6ab4eb5aSAndrea Mayer
427*6ab4eb5aSAndrea Mayer	# Local End.DT46 behavior
428*6ab4eb5aSAndrea Mayer	ip -netns "${nsname}" -6 route \
429*6ab4eb5aSAndrea Mayer		add "${VPN_LOCATOR_SERVICE}:${rt}::${DT46_FUNC}" \
430*6ab4eb5aSAndrea Mayer		table "${LOCALSID_TABLE_ID}" \
431*6ab4eb5aSAndrea Mayer		encap seg6local action End.DT46 vrftable "${VRF_TID}" \
432*6ab4eb5aSAndrea Mayer		dev "${VRF_DEVNAME}"
433*6ab4eb5aSAndrea Mayer
434*6ab4eb5aSAndrea Mayer	# all SIDs for VPNs start with a common locator. Routes and SRv6
435*6ab4eb5aSAndrea Mayer	# Endpoint behavior instaces are grouped together in the 'localsid'
436*6ab4eb5aSAndrea Mayer	# table.
437*6ab4eb5aSAndrea Mayer	ip -netns "${nsname}" -6 rule \
438*6ab4eb5aSAndrea Mayer		add to "${VPN_LOCATOR_SERVICE}::/16" \
439*6ab4eb5aSAndrea Mayer		lookup "${LOCALSID_TABLE_ID}" prio 999
440*6ab4eb5aSAndrea Mayer
441*6ab4eb5aSAndrea Mayer	# set default routes to unreachable for both ipv4 and ipv6
442*6ab4eb5aSAndrea Mayer	ip -netns "${nsname}" -6 route \
443*6ab4eb5aSAndrea Mayer		add unreachable default metric 4278198272 \
444*6ab4eb5aSAndrea Mayer		vrf "${VRF_DEVNAME}"
445*6ab4eb5aSAndrea Mayer
446*6ab4eb5aSAndrea Mayer	ip -netns "${nsname}" -4 route \
447*6ab4eb5aSAndrea Mayer		add unreachable default metric 4278198272 \
448*6ab4eb5aSAndrea Mayer		vrf "${VRF_DEVNAME}"
449*6ab4eb5aSAndrea Mayer}
450*6ab4eb5aSAndrea Mayer
451*6ab4eb5aSAndrea Mayer# build and install the SRv6 policy into the ingress SRv6 router.
452*6ab4eb5aSAndrea Mayer# args:
453*6ab4eb5aSAndrea Mayer#  $1 - destination host (i.e. cafe::x host)
454*6ab4eb5aSAndrea Mayer#  $2 - SRv6 router configured for enforcing the SRv6 Policy
455*6ab4eb5aSAndrea Mayer#  $3 - SRv6 routers configured for steering traffic (End behaviors)
456*6ab4eb5aSAndrea Mayer#  $4 - SRv6 router configured for removing the SRv6 Policy (router connected
457*6ab4eb5aSAndrea Mayer#       to the destination host)
458*6ab4eb5aSAndrea Mayer#  $5 - encap mode (full or red)
459*6ab4eb5aSAndrea Mayer#  $6 - traffic type (IPv6 or IPv4)
460*6ab4eb5aSAndrea Mayer__setup_rt_policy()
461*6ab4eb5aSAndrea Mayer{
462*6ab4eb5aSAndrea Mayer	local dst="$1"
463*6ab4eb5aSAndrea Mayer	local encap_rt="$2"
464*6ab4eb5aSAndrea Mayer	local end_rts="$3"
465*6ab4eb5aSAndrea Mayer	local dec_rt="$4"
466*6ab4eb5aSAndrea Mayer	local mode="$5"
467*6ab4eb5aSAndrea Mayer	local traffic="$6"
468*6ab4eb5aSAndrea Mayer	local nsname
469*6ab4eb5aSAndrea Mayer	local policy=''
470*6ab4eb5aSAndrea Mayer	local n
471*6ab4eb5aSAndrea Mayer
472*6ab4eb5aSAndrea Mayer	nsname="$(get_rtname "${encap_rt}")"
473*6ab4eb5aSAndrea Mayer
474*6ab4eb5aSAndrea Mayer	for n in ${end_rts}; do
475*6ab4eb5aSAndrea Mayer		policy="${policy}${VPN_LOCATOR_SERVICE}:${n}::${END_FUNC},"
476*6ab4eb5aSAndrea Mayer	done
477*6ab4eb5aSAndrea Mayer
478*6ab4eb5aSAndrea Mayer	policy="${policy}${VPN_LOCATOR_SERVICE}:${dec_rt}::${DT46_FUNC}"
479*6ab4eb5aSAndrea Mayer
480*6ab4eb5aSAndrea Mayer	# add SRv6 policy to incoming traffic sent by connected hosts
481*6ab4eb5aSAndrea Mayer	if [ "${traffic}" -eq 6 ]; then
482*6ab4eb5aSAndrea Mayer		ip -netns "${nsname}" -6 route \
483*6ab4eb5aSAndrea Mayer			add "${IPv6_HS_NETWORK}::${dst}" vrf "${VRF_DEVNAME}" \
484*6ab4eb5aSAndrea Mayer			encap seg6 mode "${mode}" segs "${policy}" \
485*6ab4eb5aSAndrea Mayer			dev "${VRF_DEVNAME}"
486*6ab4eb5aSAndrea Mayer
487*6ab4eb5aSAndrea Mayer		ip -netns "${nsname}" -6 neigh \
488*6ab4eb5aSAndrea Mayer			add proxy "${IPv6_HS_NETWORK}::${dst}" \
489*6ab4eb5aSAndrea Mayer			dev "${RT2HS_DEVNAME}"
490*6ab4eb5aSAndrea Mayer	else
491*6ab4eb5aSAndrea Mayer		# "dev" must be different from the one where the packet is
492*6ab4eb5aSAndrea Mayer		# received, otherwise the proxy arp does not work.
493*6ab4eb5aSAndrea Mayer		ip -netns "${nsname}" -4 route \
494*6ab4eb5aSAndrea Mayer			add "${IPv4_HS_NETWORK}.${dst}" vrf "${VRF_DEVNAME}" \
495*6ab4eb5aSAndrea Mayer			encap seg6 mode "${mode}" segs "${policy}" \
496*6ab4eb5aSAndrea Mayer			dev "${VRF_DEVNAME}"
497*6ab4eb5aSAndrea Mayer	fi
498*6ab4eb5aSAndrea Mayer}
499*6ab4eb5aSAndrea Mayer
500*6ab4eb5aSAndrea Mayer# see __setup_rt_policy
501*6ab4eb5aSAndrea Mayersetup_rt_policy_ipv6()
502*6ab4eb5aSAndrea Mayer{
503*6ab4eb5aSAndrea Mayer	__setup_rt_policy "$1" "$2" "$3" "$4" "$5" 6
504*6ab4eb5aSAndrea Mayer}
505*6ab4eb5aSAndrea Mayer
506*6ab4eb5aSAndrea Mayer#see __setup_rt_policy
507*6ab4eb5aSAndrea Mayersetup_rt_policy_ipv4()
508*6ab4eb5aSAndrea Mayer{
509*6ab4eb5aSAndrea Mayer	__setup_rt_policy "$1" "$2" "$3" "$4" "$5" 4
510*6ab4eb5aSAndrea Mayer}
511*6ab4eb5aSAndrea Mayer
512*6ab4eb5aSAndrea Mayersetup_hs()
513*6ab4eb5aSAndrea Mayer{
514*6ab4eb5aSAndrea Mayer	local hs="$1"
515*6ab4eb5aSAndrea Mayer	local rt="$2"
516*6ab4eb5aSAndrea Mayer	local hsname
517*6ab4eb5aSAndrea Mayer	local rtname
518*6ab4eb5aSAndrea Mayer
519*6ab4eb5aSAndrea Mayer	hsname="$(get_hsname "${hs}")"
520*6ab4eb5aSAndrea Mayer	rtname="$(get_rtname "${rt}")"
521*6ab4eb5aSAndrea Mayer
522*6ab4eb5aSAndrea Mayer	ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.all.accept_dad=0
523*6ab4eb5aSAndrea Mayer	ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.default.accept_dad=0
524*6ab4eb5aSAndrea Mayer
525*6ab4eb5aSAndrea Mayer	ip -netns "${hsname}" link add veth0 type veth \
526*6ab4eb5aSAndrea Mayer		peer name "${RT2HS_DEVNAME}" netns "${rtname}"
527*6ab4eb5aSAndrea Mayer
528*6ab4eb5aSAndrea Mayer	ip -netns "${hsname}" addr \
529*6ab4eb5aSAndrea Mayer		add "${IPv6_HS_NETWORK}::${hs}/64" dev veth0 nodad
530*6ab4eb5aSAndrea Mayer	ip -netns "${hsname}" addr add "${IPv4_HS_NETWORK}.${hs}/24" dev veth0
531*6ab4eb5aSAndrea Mayer
532*6ab4eb5aSAndrea Mayer	ip -netns "${hsname}" link set veth0 up
533*6ab4eb5aSAndrea Mayer	ip -netns "${hsname}" link set lo up
534*6ab4eb5aSAndrea Mayer
535*6ab4eb5aSAndrea Mayer	# configure the VRF on the router which is directly connected to the
536*6ab4eb5aSAndrea Mayer	# source host.
537*6ab4eb5aSAndrea Mayer	ip -netns "${rtname}" link \
538*6ab4eb5aSAndrea Mayer		add "${VRF_DEVNAME}" type vrf table "${VRF_TID}"
539*6ab4eb5aSAndrea Mayer	ip -netns "${rtname}" link set "${VRF_DEVNAME}" up
540*6ab4eb5aSAndrea Mayer
541*6ab4eb5aSAndrea Mayer	# enslave the veth interface connecting the router with the host to the
542*6ab4eb5aSAndrea Mayer	# VRF in the access router
543*6ab4eb5aSAndrea Mayer	ip -netns "${rtname}" link \
544*6ab4eb5aSAndrea Mayer		set "${RT2HS_DEVNAME}" master "${VRF_DEVNAME}"
545*6ab4eb5aSAndrea Mayer
546*6ab4eb5aSAndrea Mayer	ip -netns "${rtname}" addr \
547*6ab4eb5aSAndrea Mayer		add "${IPv6_HS_NETWORK}::254/64" dev "${RT2HS_DEVNAME}" nodad
548*6ab4eb5aSAndrea Mayer	ip -netns "${rtname}" addr \
549*6ab4eb5aSAndrea Mayer		add "${IPv4_HS_NETWORK}.254/24" dev "${RT2HS_DEVNAME}"
550*6ab4eb5aSAndrea Mayer
551*6ab4eb5aSAndrea Mayer	ip -netns "${rtname}" link set "${RT2HS_DEVNAME}" up
552*6ab4eb5aSAndrea Mayer
553*6ab4eb5aSAndrea Mayer	ip netns exec "${rtname}" \
554*6ab4eb5aSAndrea Mayer		sysctl -wq net.ipv6.conf."${RT2HS_DEVNAME}".proxy_ndp=1
555*6ab4eb5aSAndrea Mayer	ip netns exec "${rtname}" \
556*6ab4eb5aSAndrea Mayer		sysctl -wq net.ipv4.conf."${RT2HS_DEVNAME}".proxy_arp=1
557*6ab4eb5aSAndrea Mayer
558*6ab4eb5aSAndrea Mayer	# disable the rp_filter otherwise the kernel gets confused about how
559*6ab4eb5aSAndrea Mayer	# to route decap ipv4 packets.
560*6ab4eb5aSAndrea Mayer	ip netns exec "${rtname}" \
561*6ab4eb5aSAndrea Mayer		sysctl -wq net.ipv4.conf."${RT2HS_DEVNAME}".rp_filter=0
562*6ab4eb5aSAndrea Mayer
563*6ab4eb5aSAndrea Mayer	ip netns exec "${rtname}" sh -c "echo 1 > /proc/sys/net/vrf/strict_mode"
564*6ab4eb5aSAndrea Mayer}
565*6ab4eb5aSAndrea Mayer
566*6ab4eb5aSAndrea Mayersetup()
567*6ab4eb5aSAndrea Mayer{
568*6ab4eb5aSAndrea Mayer	local i
569*6ab4eb5aSAndrea Mayer
570*6ab4eb5aSAndrea Mayer	# create routers
571*6ab4eb5aSAndrea Mayer	ROUTERS="1 2 3 4"; readonly ROUTERS
572*6ab4eb5aSAndrea Mayer	for i in ${ROUTERS}; do
573*6ab4eb5aSAndrea Mayer		create_router "${i}"
574*6ab4eb5aSAndrea Mayer	done
575*6ab4eb5aSAndrea Mayer
576*6ab4eb5aSAndrea Mayer	# create hosts
577*6ab4eb5aSAndrea Mayer	HOSTS="1 2 3 4"; readonly HOSTS
578*6ab4eb5aSAndrea Mayer	for i in ${HOSTS}; do
579*6ab4eb5aSAndrea Mayer		create_host "${i}"
580*6ab4eb5aSAndrea Mayer	done
581*6ab4eb5aSAndrea Mayer
582*6ab4eb5aSAndrea Mayer	# set up the links for connecting routers
583*6ab4eb5aSAndrea Mayer	add_link_rt_pairs 1 "2 3 4"
584*6ab4eb5aSAndrea Mayer	add_link_rt_pairs 2 "3 4"
585*6ab4eb5aSAndrea Mayer	add_link_rt_pairs 3 "4"
586*6ab4eb5aSAndrea Mayer
587*6ab4eb5aSAndrea Mayer	# set up the basic connectivity of routers and routes required for
588*6ab4eb5aSAndrea Mayer	# reachability of SIDs.
589*6ab4eb5aSAndrea Mayer	setup_rt_networking 1 "2 3 4"
590*6ab4eb5aSAndrea Mayer	setup_rt_networking 2 "1 3 4"
591*6ab4eb5aSAndrea Mayer	setup_rt_networking 3 "1 2 4"
592*6ab4eb5aSAndrea Mayer	setup_rt_networking 4 "1 2 3"
593*6ab4eb5aSAndrea Mayer
594*6ab4eb5aSAndrea Mayer	# set up the hosts connected to routers
595*6ab4eb5aSAndrea Mayer	setup_hs 1 1
596*6ab4eb5aSAndrea Mayer	setup_hs 2 2
597*6ab4eb5aSAndrea Mayer	setup_hs 3 3
598*6ab4eb5aSAndrea Mayer	setup_hs 4 4
599*6ab4eb5aSAndrea Mayer
600*6ab4eb5aSAndrea Mayer	# set up default SRv6 Endpoints (i.e. SRv6 End and SRv6 End.DT46)
601*6ab4eb5aSAndrea Mayer	setup_rt_local_sids 1 "2 3 4"
602*6ab4eb5aSAndrea Mayer	setup_rt_local_sids 2 "1 3 4"
603*6ab4eb5aSAndrea Mayer	setup_rt_local_sids 3 "1 2 4"
604*6ab4eb5aSAndrea Mayer	setup_rt_local_sids 4 "1 2 3"
605*6ab4eb5aSAndrea Mayer
606*6ab4eb5aSAndrea Mayer	# set up SRv6 policies
607*6ab4eb5aSAndrea Mayer
608*6ab4eb5aSAndrea Mayer	# create an IPv6 VPN between hosts hs-1 and hs-2.
609*6ab4eb5aSAndrea Mayer	# the network path between hs-1 and hs-2 traverses several routers
610*6ab4eb5aSAndrea Mayer	# depending on the direction of traffic.
611*6ab4eb5aSAndrea Mayer	#
612*6ab4eb5aSAndrea Mayer	# Direction hs-1 -> hs-2 (H.Encaps.Red)
613*6ab4eb5aSAndrea Mayer	#  - rt-3,rt-4 (SRv6 End behaviors)
614*6ab4eb5aSAndrea Mayer	#  - rt-2 (SRv6 End.DT46 behavior)
615*6ab4eb5aSAndrea Mayer	#
616*6ab4eb5aSAndrea Mayer	# Direction hs-2 -> hs-1 (H.Encaps.Red)
617*6ab4eb5aSAndrea Mayer	#  - rt-1 (SRv6 End.DT46 behavior)
618*6ab4eb5aSAndrea Mayer	setup_rt_policy_ipv6 2 1 "3 4" 2 encap.red
619*6ab4eb5aSAndrea Mayer	setup_rt_policy_ipv6 1 2 "" 1 encap.red
620*6ab4eb5aSAndrea Mayer
621*6ab4eb5aSAndrea Mayer	# create an IPv4 VPN between hosts hs-1 and hs-2
622*6ab4eb5aSAndrea Mayer	# the network path between hs-1 and hs-2 traverses several routers
623*6ab4eb5aSAndrea Mayer	# depending on the direction of traffic.
624*6ab4eb5aSAndrea Mayer	#
625*6ab4eb5aSAndrea Mayer	# Direction hs-1 -> hs-2 (H.Encaps.Red)
626*6ab4eb5aSAndrea Mayer	# - rt-2 (SRv6 End.DT46 behavior)
627*6ab4eb5aSAndrea Mayer	#
628*6ab4eb5aSAndrea Mayer	# Direction hs-2 -> hs-1 (H.Encaps.Red)
629*6ab4eb5aSAndrea Mayer	#  - rt-4,rt-3 (SRv6 End behaviors)
630*6ab4eb5aSAndrea Mayer	#  - rt-1 (SRv6 End.DT46 behavior)
631*6ab4eb5aSAndrea Mayer	setup_rt_policy_ipv4 2 1 "" 2 encap.red
632*6ab4eb5aSAndrea Mayer	setup_rt_policy_ipv4 1 2 "4 3" 1 encap.red
633*6ab4eb5aSAndrea Mayer
634*6ab4eb5aSAndrea Mayer	# create an IPv6 VPN between hosts hs-3 and hs-4
635*6ab4eb5aSAndrea Mayer	# the network path between hs-3 and hs-4 traverses several routers
636*6ab4eb5aSAndrea Mayer	# depending on the direction of traffic.
637*6ab4eb5aSAndrea Mayer	#
638*6ab4eb5aSAndrea Mayer	# Direction hs-3 -> hs-4 (H.Encaps.Red)
639*6ab4eb5aSAndrea Mayer	# - rt-2 (SRv6 End Behavior)
640*6ab4eb5aSAndrea Mayer	# - rt-4 (SRv6 End.DT46 behavior)
641*6ab4eb5aSAndrea Mayer	#
642*6ab4eb5aSAndrea Mayer	# Direction hs-4 -> hs-3 (H.Encaps.Red)
643*6ab4eb5aSAndrea Mayer	#  - rt-1 (SRv6 End behavior)
644*6ab4eb5aSAndrea Mayer	#  - rt-3 (SRv6 End.DT46 behavior)
645*6ab4eb5aSAndrea Mayer	setup_rt_policy_ipv6 4 3 "2" 4 encap.red
646*6ab4eb5aSAndrea Mayer	setup_rt_policy_ipv6 3 4 "1" 3 encap.red
647*6ab4eb5aSAndrea Mayer
648*6ab4eb5aSAndrea Mayer	# testing environment was set up successfully
649*6ab4eb5aSAndrea Mayer	SETUP_ERR=0
650*6ab4eb5aSAndrea Mayer}
651*6ab4eb5aSAndrea Mayer
652*6ab4eb5aSAndrea Mayercheck_rt_connectivity()
653*6ab4eb5aSAndrea Mayer{
654*6ab4eb5aSAndrea Mayer	local rtsrc="$1"
655*6ab4eb5aSAndrea Mayer	local rtdst="$2"
656*6ab4eb5aSAndrea Mayer	local prefix
657*6ab4eb5aSAndrea Mayer	local rtsrc_nsname
658*6ab4eb5aSAndrea Mayer
659*6ab4eb5aSAndrea Mayer	rtsrc_nsname="$(get_rtname "${rtsrc}")"
660*6ab4eb5aSAndrea Mayer
661*6ab4eb5aSAndrea Mayer	prefix="$(get_network_prefix "${rtsrc}" "${rtdst}")"
662*6ab4eb5aSAndrea Mayer
663*6ab4eb5aSAndrea Mayer	ip netns exec "${rtsrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
664*6ab4eb5aSAndrea Mayer		"${prefix}::${rtdst}" >/dev/null 2>&1
665*6ab4eb5aSAndrea Mayer}
666*6ab4eb5aSAndrea Mayer
667*6ab4eb5aSAndrea Mayercheck_and_log_rt_connectivity()
668*6ab4eb5aSAndrea Mayer{
669*6ab4eb5aSAndrea Mayer	local rtsrc="$1"
670*6ab4eb5aSAndrea Mayer	local rtdst="$2"
671*6ab4eb5aSAndrea Mayer
672*6ab4eb5aSAndrea Mayer	check_rt_connectivity "${rtsrc}" "${rtdst}"
673*6ab4eb5aSAndrea Mayer	log_test $? 0 "Routers connectivity: rt-${rtsrc} -> rt-${rtdst}"
674*6ab4eb5aSAndrea Mayer}
675*6ab4eb5aSAndrea Mayer
676*6ab4eb5aSAndrea Mayercheck_hs_ipv6_connectivity()
677*6ab4eb5aSAndrea Mayer{
678*6ab4eb5aSAndrea Mayer	local hssrc="$1"
679*6ab4eb5aSAndrea Mayer	local hsdst="$2"
680*6ab4eb5aSAndrea Mayer	local hssrc_nsname
681*6ab4eb5aSAndrea Mayer
682*6ab4eb5aSAndrea Mayer	hssrc_nsname="$(get_hsname "${hssrc}")"
683*6ab4eb5aSAndrea Mayer
684*6ab4eb5aSAndrea Mayer	ip netns exec "${hssrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
685*6ab4eb5aSAndrea Mayer		"${IPv6_HS_NETWORK}::${hsdst}" >/dev/null 2>&1
686*6ab4eb5aSAndrea Mayer}
687*6ab4eb5aSAndrea Mayer
688*6ab4eb5aSAndrea Mayercheck_hs_ipv4_connectivity()
689*6ab4eb5aSAndrea Mayer{
690*6ab4eb5aSAndrea Mayer	local hssrc="$1"
691*6ab4eb5aSAndrea Mayer	local hsdst="$2"
692*6ab4eb5aSAndrea Mayer	local hssrc_nsname
693*6ab4eb5aSAndrea Mayer
694*6ab4eb5aSAndrea Mayer	hssrc_nsname="$(get_hsname "${hssrc}")"
695*6ab4eb5aSAndrea Mayer
696*6ab4eb5aSAndrea Mayer	ip netns exec "${hssrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
697*6ab4eb5aSAndrea Mayer		"${IPv4_HS_NETWORK}.${hsdst}" >/dev/null 2>&1
698*6ab4eb5aSAndrea Mayer}
699*6ab4eb5aSAndrea Mayer
700*6ab4eb5aSAndrea Mayercheck_and_log_hs2gw_connectivity()
701*6ab4eb5aSAndrea Mayer{
702*6ab4eb5aSAndrea Mayer	local hssrc="$1"
703*6ab4eb5aSAndrea Mayer
704*6ab4eb5aSAndrea Mayer	check_hs_ipv6_connectivity "${hssrc}" 254
705*6ab4eb5aSAndrea Mayer	log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> gw"
706*6ab4eb5aSAndrea Mayer
707*6ab4eb5aSAndrea Mayer	check_hs_ipv4_connectivity "${hssrc}" 254
708*6ab4eb5aSAndrea Mayer	log_test $? 0 "IPv4 Hosts connectivity: hs-${hssrc} -> gw"
709*6ab4eb5aSAndrea Mayer}
710*6ab4eb5aSAndrea Mayer
711*6ab4eb5aSAndrea Mayercheck_and_log_hs_ipv6_connectivity()
712*6ab4eb5aSAndrea Mayer{
713*6ab4eb5aSAndrea Mayer	local hssrc="$1"
714*6ab4eb5aSAndrea Mayer	local hsdst="$2"
715*6ab4eb5aSAndrea Mayer
716*6ab4eb5aSAndrea Mayer	check_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
717*6ab4eb5aSAndrea Mayer	log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}"
718*6ab4eb5aSAndrea Mayer}
719*6ab4eb5aSAndrea Mayer
720*6ab4eb5aSAndrea Mayercheck_and_log_hs_ipv4_connectivity()
721*6ab4eb5aSAndrea Mayer{
722*6ab4eb5aSAndrea Mayer	local hssrc="$1"
723*6ab4eb5aSAndrea Mayer	local hsdst="$2"
724*6ab4eb5aSAndrea Mayer
725*6ab4eb5aSAndrea Mayer	check_hs_ipv4_connectivity "${hssrc}" "${hsdst}"
726*6ab4eb5aSAndrea Mayer	log_test $? 0 "IPv4 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}"
727*6ab4eb5aSAndrea Mayer}
728*6ab4eb5aSAndrea Mayer
729*6ab4eb5aSAndrea Mayercheck_and_log_hs_connectivity()
730*6ab4eb5aSAndrea Mayer{
731*6ab4eb5aSAndrea Mayer	local hssrc="$1"
732*6ab4eb5aSAndrea Mayer	local hsdst="$2"
733*6ab4eb5aSAndrea Mayer
734*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv4_connectivity "${hssrc}" "${hsdst}"
735*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
736*6ab4eb5aSAndrea Mayer}
737*6ab4eb5aSAndrea Mayer
738*6ab4eb5aSAndrea Mayercheck_and_log_hs_ipv6_isolation()
739*6ab4eb5aSAndrea Mayer{
740*6ab4eb5aSAndrea Mayer	local hssrc="$1"
741*6ab4eb5aSAndrea Mayer	local hsdst="$2"
742*6ab4eb5aSAndrea Mayer
743*6ab4eb5aSAndrea Mayer	# in this case, the connectivity test must fail
744*6ab4eb5aSAndrea Mayer	check_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
745*6ab4eb5aSAndrea Mayer	log_test $? 1 "IPv6 Hosts isolation: hs-${hssrc} -X-> hs-${hsdst}"
746*6ab4eb5aSAndrea Mayer}
747*6ab4eb5aSAndrea Mayer
748*6ab4eb5aSAndrea Mayercheck_and_log_hs_ipv4_isolation()
749*6ab4eb5aSAndrea Mayer{
750*6ab4eb5aSAndrea Mayer	local hssrc="$1"
751*6ab4eb5aSAndrea Mayer	local hsdst="$2"
752*6ab4eb5aSAndrea Mayer
753*6ab4eb5aSAndrea Mayer	# in this case, the connectivity test must fail
754*6ab4eb5aSAndrea Mayer	check_hs_ipv4_connectivity "${hssrc}" "${hsdst}"
755*6ab4eb5aSAndrea Mayer	log_test $? 1 "IPv4 Hosts isolation: hs-${hssrc} -X-> hs-${hsdst}"
756*6ab4eb5aSAndrea Mayer}
757*6ab4eb5aSAndrea Mayer
758*6ab4eb5aSAndrea Mayercheck_and_log_hs_isolation()
759*6ab4eb5aSAndrea Mayer{
760*6ab4eb5aSAndrea Mayer	local hssrc="$1"
761*6ab4eb5aSAndrea Mayer	local hsdst="$2"
762*6ab4eb5aSAndrea Mayer
763*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv6_isolation "${hssrc}" "${hsdst}"
764*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv4_isolation "${hssrc}" "${hsdst}"
765*6ab4eb5aSAndrea Mayer}
766*6ab4eb5aSAndrea Mayer
767*6ab4eb5aSAndrea Mayerrouter_tests()
768*6ab4eb5aSAndrea Mayer{
769*6ab4eb5aSAndrea Mayer	local i
770*6ab4eb5aSAndrea Mayer	local j
771*6ab4eb5aSAndrea Mayer
772*6ab4eb5aSAndrea Mayer	log_section "IPv6 routers connectivity test"
773*6ab4eb5aSAndrea Mayer
774*6ab4eb5aSAndrea Mayer	for i in ${ROUTERS}; do
775*6ab4eb5aSAndrea Mayer		for j in ${ROUTERS}; do
776*6ab4eb5aSAndrea Mayer			if [ "${i}" -eq "${j}" ]; then
777*6ab4eb5aSAndrea Mayer				continue
778*6ab4eb5aSAndrea Mayer			fi
779*6ab4eb5aSAndrea Mayer
780*6ab4eb5aSAndrea Mayer			check_and_log_rt_connectivity "${i}" "${j}"
781*6ab4eb5aSAndrea Mayer		done
782*6ab4eb5aSAndrea Mayer	done
783*6ab4eb5aSAndrea Mayer}
784*6ab4eb5aSAndrea Mayer
785*6ab4eb5aSAndrea Mayerhost2gateway_tests()
786*6ab4eb5aSAndrea Mayer{
787*6ab4eb5aSAndrea Mayer	local hs
788*6ab4eb5aSAndrea Mayer
789*6ab4eb5aSAndrea Mayer	log_section "IPv4/IPv6 connectivity test among hosts and gateways"
790*6ab4eb5aSAndrea Mayer
791*6ab4eb5aSAndrea Mayer	for hs in ${HOSTS}; do
792*6ab4eb5aSAndrea Mayer		check_and_log_hs2gw_connectivity "${hs}"
793*6ab4eb5aSAndrea Mayer	done
794*6ab4eb5aSAndrea Mayer}
795*6ab4eb5aSAndrea Mayer
796*6ab4eb5aSAndrea Mayerhost_vpn_tests()
797*6ab4eb5aSAndrea Mayer{
798*6ab4eb5aSAndrea Mayer	log_section "SRv6 VPN connectivity test hosts (h1 <-> h2, IPv4/IPv6)"
799*6ab4eb5aSAndrea Mayer
800*6ab4eb5aSAndrea Mayer	check_and_log_hs_connectivity 1 2
801*6ab4eb5aSAndrea Mayer	check_and_log_hs_connectivity 2 1
802*6ab4eb5aSAndrea Mayer
803*6ab4eb5aSAndrea Mayer	log_section "SRv6 VPN connectivity test hosts (h3 <-> h4, IPv6 only)"
804*6ab4eb5aSAndrea Mayer
805*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv6_connectivity 3 4
806*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv6_connectivity 4 3
807*6ab4eb5aSAndrea Mayer}
808*6ab4eb5aSAndrea Mayer
809*6ab4eb5aSAndrea Mayerhost_vpn_isolation_tests()
810*6ab4eb5aSAndrea Mayer{
811*6ab4eb5aSAndrea Mayer	local l1="1 2"
812*6ab4eb5aSAndrea Mayer	local l2="3 4"
813*6ab4eb5aSAndrea Mayer	local tmp
814*6ab4eb5aSAndrea Mayer	local i
815*6ab4eb5aSAndrea Mayer	local j
816*6ab4eb5aSAndrea Mayer	local k
817*6ab4eb5aSAndrea Mayer
818*6ab4eb5aSAndrea Mayer	log_section "SRv6 VPN isolation test among hosts"
819*6ab4eb5aSAndrea Mayer
820*6ab4eb5aSAndrea Mayer	for k in 0 1; do
821*6ab4eb5aSAndrea Mayer		for i in ${l1}; do
822*6ab4eb5aSAndrea Mayer			for j in ${l2}; do
823*6ab4eb5aSAndrea Mayer				check_and_log_hs_isolation "${i}" "${j}"
824*6ab4eb5aSAndrea Mayer			done
825*6ab4eb5aSAndrea Mayer		done
826*6ab4eb5aSAndrea Mayer
827*6ab4eb5aSAndrea Mayer		# let us test the reverse path
828*6ab4eb5aSAndrea Mayer		tmp="${l1}"; l1="${l2}"; l2="${tmp}"
829*6ab4eb5aSAndrea Mayer	done
830*6ab4eb5aSAndrea Mayer
831*6ab4eb5aSAndrea Mayer	log_section "SRv6 VPN isolation test among hosts (h2 <-> h4, IPv4 only)"
832*6ab4eb5aSAndrea Mayer
833*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv4_isolation 2 4
834*6ab4eb5aSAndrea Mayer	check_and_log_hs_ipv4_isolation 4 2
835*6ab4eb5aSAndrea Mayer}
836*6ab4eb5aSAndrea Mayer
837*6ab4eb5aSAndrea Mayertest_iproute2_supp_or_ksft_skip()
838*6ab4eb5aSAndrea Mayer{
839*6ab4eb5aSAndrea Mayer	if ! ip route help 2>&1 | grep -qo "encap.red"; then
840*6ab4eb5aSAndrea Mayer		echo "SKIP: Missing SRv6 encap.red support in iproute2"
841*6ab4eb5aSAndrea Mayer		exit "${ksft_skip}"
842*6ab4eb5aSAndrea Mayer	fi
843*6ab4eb5aSAndrea Mayer}
844*6ab4eb5aSAndrea Mayer
845*6ab4eb5aSAndrea Mayertest_vrf_or_ksft_skip()
846*6ab4eb5aSAndrea Mayer{
847*6ab4eb5aSAndrea Mayer	modprobe vrf &>/dev/null || true
848*6ab4eb5aSAndrea Mayer	if [ ! -e /proc/sys/net/vrf/strict_mode ]; then
849*6ab4eb5aSAndrea Mayer		echo "SKIP: vrf sysctl does not exist"
850*6ab4eb5aSAndrea Mayer		exit "${ksft_skip}"
851*6ab4eb5aSAndrea Mayer	fi
852*6ab4eb5aSAndrea Mayer}
853*6ab4eb5aSAndrea Mayer
854*6ab4eb5aSAndrea Mayerif [ "$(id -u)" -ne 0 ]; then
855*6ab4eb5aSAndrea Mayer	echo "SKIP: Need root privileges"
856*6ab4eb5aSAndrea Mayer	exit "${ksft_skip}"
857*6ab4eb5aSAndrea Mayerfi
858*6ab4eb5aSAndrea Mayer
859*6ab4eb5aSAndrea Mayer# required programs to carry out this selftest
860*6ab4eb5aSAndrea Mayertest_command_or_ksft_skip ip
861*6ab4eb5aSAndrea Mayertest_command_or_ksft_skip ping
862*6ab4eb5aSAndrea Mayertest_command_or_ksft_skip sysctl
863*6ab4eb5aSAndrea Mayertest_command_or_ksft_skip grep
864*6ab4eb5aSAndrea Mayer
865*6ab4eb5aSAndrea Mayertest_iproute2_supp_or_ksft_skip
866*6ab4eb5aSAndrea Mayertest_vrf_or_ksft_skip
867*6ab4eb5aSAndrea Mayer
868*6ab4eb5aSAndrea Mayerset -e
869*6ab4eb5aSAndrea Mayertrap cleanup EXIT
870*6ab4eb5aSAndrea Mayer
871*6ab4eb5aSAndrea Mayersetup
872*6ab4eb5aSAndrea Mayerset +e
873*6ab4eb5aSAndrea Mayer
874*6ab4eb5aSAndrea Mayerrouter_tests
875*6ab4eb5aSAndrea Mayerhost2gateway_tests
876*6ab4eb5aSAndrea Mayerhost_vpn_tests
877*6ab4eb5aSAndrea Mayerhost_vpn_isolation_tests
878*6ab4eb5aSAndrea Mayer
879*6ab4eb5aSAndrea Mayerprint_log_test_results
880