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