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