Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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