drm/bridge: adv7511: Switch to atomic operations
[drm/drm-misc.git] / tools / testing / selftests / net / srv6_end_flavors_test.sh
blob50563443a4adced4784c08413ea37504417da08e
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
4 # author: Andrea Mayer <andrea.mayer@uniroma2.it>
5 # author: Paolo Lungaroni <paolo.lungaroni@uniroma2.it>
7 # This script is designed to test the support for "flavors" in the SRv6 End
8 # behavior.
10 # Flavors defined in RFC8986 [1] represent additional operations that can modify
11 # or extend the existing SRv6 End, End.X and End.T behaviors. For the sake of
12 # convenience, we report the list of flavors described in [1] hereafter:
13 # - Penultimate Segment Pop (PSP);
14 # - Ultimate Segment Pop (USP);
15 # - Ultimate Segment Decapsulation (USD).
17 # The End, End.X, and End.T behaviors can support these flavors either
18 # individually or in combinations.
19 # Currently in this selftest we consider only the PSP flavor for the SRv6 End
20 # behavior. However, it is possible to extend the script as soon as other
21 # flavors will be supported in the kernel.
23 # The purpose of the PSP flavor consists in instructing the penultimate node
24 # listed in the SRv6 policy to remove (i.e. pop) the outermost SRH from the IPv6
25 # header.
26 # A PSP enabled SRv6 End behavior instance processes the SRH by:
27 # - decrementing the Segment Left (SL) value from 1 to 0;
28 # - copying the last SID from the SID List into the IPv6 Destination Address
29 # (DA);
30 # - removing the SRH from the extension headers following the IPv6 header.
32 # Once the SRH is removed, the IPv6 packet is forwarded to the destination using
33 # the IPv6 DA updated during the PSP operation (i.e. the IPv6 DA corresponding
34 # to the last SID carried by the removed SRH).
36 # Although the PSP flavor can be set for any SRv6 End behavior instance on any
37 # SR node, it will be active only on such behaviors bound to a penultimate SID
38 # for a given SRv6 policy.
39 # SL=2 SL=1 SL=0
40 # | | |
41 # For example, given the SRv6 policy (SID List := <X, Y, Z>):
42 # - a PSP enabled SRv6 End behavior bound to SID Y will apply the PSP operation
43 # as Segment Left (SL) is 1, corresponding to the Penultimate Segment of the
44 # SID List;
45 # - a PSP enabled SRv6 End behavior bound to SID X will *NOT* apply the PSP
46 # operation as the Segment Left is 2. This behavior instance will apply the
47 # "standard" End packet processing, ignoring the configured PSP flavor at
48 # all.
50 # [1] RFC8986: https://datatracker.ietf.org/doc/html/rfc8986
52 # Network topology
53 # ================
55 # The network topology used in this selftest is depicted hereafter, composed by
56 # two hosts (hs-1, hs-2) and four routers (rt-1, rt-2, rt-3, rt-4).
57 # Hosts hs-1 and hs-2 are connected to routers rt-1 and rt-2, respectively,
58 # allowing them to communicate with each other.
59 # Traffic exchanged between hs-1 and hs-2 can follow different network paths.
60 # The network operator, through specific SRv6 Policies can steer traffic to one
61 # path rather than another. In this selftest this is implemented as follows:
63 # i) The SRv6 H.Insert behavior applies SRv6 Policies on traffic received by
64 # connected hosts. It pushes the Segment Routing Header (SRH) after the
65 # IPv6 header. The SRH contains the SID List (i.e. SRv6 Policy) needed for
66 # steering traffic across the segments/waypoints specified in that list;
68 # ii) The SRv6 End behavior advances the active SID in the SID List carried by
69 # the SRH;
71 # iii) The PSP enabled SRv6 End behavior is used to remove the SRH when such
72 # behavior is configured on a node bound to the Penultimate Segment carried
73 # by the SID List.
75 # cafe::1 cafe::2
76 # +--------+ +--------+
77 # | | | |
78 # | hs-1 | | hs-2 |
79 # | | | |
80 # +---+----+ +--- +---+
81 # cafe::/64 | | cafe::/64
82 # | |
83 # +---+----+ +----+---+
84 # | | fcf0:0:1:2::/64 | |
85 # | rt-1 +-------------------+ rt-2 |
86 # | | | |
87 # +---+----+ +----+---+
88 # | . . |
89 # | fcf0:0:1:3::/64 . |
90 # | . . |
91 # | . . |
92 # fcf0:0:1:4::/64 | . | fcf0:0:2:3::/64
93 # | . . |
94 # | . . |
95 # | fcf0:0:2:4::/64 . |
96 # | . . |
97 # +---+----+ +----+---+
98 # | | | |
99 # | rt-4 +-------------------+ rt-3 |
100 # | | fcf0:0:3:4::/64 | |
101 # +---+----+ +----+---+
103 # Every fcf0:0:x:y::/64 network interconnects the SRv6 routers rt-x with rt-y in
104 # the IPv6 operator network.
107 # Local SID table
108 # ===============
110 # Each SRv6 router is configured with a Local SID table in which SIDs are
111 # stored. Considering the given SRv6 router rt-x, at least two SIDs are
112 # configured in the Local SID table:
114 # Local SID table for SRv6 router rt-x
115 # +---------------------------------------------------------------------+
116 # |fcff:x::e is associated with the SRv6 End behavior |
117 # |fcff:x::ef1 is associated with the SRv6 End behavior with PSP flavor |
118 # +---------------------------------------------------------------------+
120 # The fcff::/16 prefix is reserved by the operator for the SIDs. Reachability of
121 # SIDs is ensured by proper configuration of the IPv6 operator's network and
122 # SRv6 routers.
125 # SRv6 Policies
126 # =============
128 # An SRv6 ingress router applies different SRv6 Policies to the traffic received
129 # from connected hosts on the basis of the destination addresses.
130 # In case of SRv6 H.Insert behavior, the SRv6 Policy enforcement consists of
131 # pushing the SRH (carrying a given SID List) after the existing IPv6 header.
132 # Note that in the inserting mode, there is no encapsulation at all.
134 # Before applying an SRv6 Policy using the SRv6 H.Insert behavior
135 # +------+---------+
136 # | IPv6 | Payload |
137 # +------+---------+
139 # After applying an SRv6 Policy using the SRv6 H.Insert behavior
140 # +------+-----+---------+
141 # | IPv6 | SRH | Payload |
142 # +------+-----+---------+
144 # Traffic from hs-1 to hs-2
145 # -------------------------
147 # Packets generated from hs-1 and directed towards hs-2 are
148 # handled by rt-1 which applies the following SRv6 Policy:
150 # i.a) IPv6 traffic, SID List=fcff:3::e,fcff:4::ef1,fcff:2::ef1,cafe::2
152 # Router rt-1 is configured to enforce the Policy (i.a) through the SRv6
153 # H.Insert behavior which pushes the SRH after the existing IPv6 header. This
154 # Policy steers the traffic from hs-1 across rt-3, rt-4, rt-2 and finally to the
155 # destination hs-2.
157 # As the packet reaches the router rt-3, the SRv6 End behavior bound to SID
158 # fcff:3::e is triggered. The behavior updates the Segment Left (from SL=3 to
159 # SL=2) in the SRH, the IPv6 DA with fcff:4::ef1 and forwards the packet to the
160 # next router on the path, i.e. rt-4.
162 # When router rt-4 receives the packet, the PSP enabled SRv6 End behavior bound
163 # to SID fcff:4::ef1 is executed. Since the SL=2, the PSP operation is *NOT*
164 # kicked in and the behavior applies the default End processing: the Segment
165 # Left is decreased (from SL=2 to SL=1), the IPv6 DA is updated with the SID
166 # fcff:2::ef1 and the packet is forwarded to router rt-2.
168 # The PSP enabled SRv6 End behavior on rt-2 is associated with SID fcff:2::ef1
169 # and is executed as the packet is received. Because SL=1, the behavior applies
170 # the PSP processing on the packet as follows: i) SL is decreased, i.e. from
171 # SL=1 to SL=0; ii) last SID (cafe::2) is copied into the IPv6 DA; iii) the
172 # outermost SRH is removed from the extension headers following the IPv6 header.
173 # Once the PSP processing is completed, the packet is forwarded to the host hs-2
174 # (destination).
176 # Traffic from hs-2 to hs-1
177 # -------------------------
179 # Packets generated from hs-2 and directed to hs-1 are handled by rt-2 which
180 # applies the following SRv6 Policy:
182 # i.b) IPv6 traffic, SID List=fcff:1::ef1,cafe::1
184 # Router rt-2 is configured to enforce the Policy (i.b) through the SRv6
185 # H.Insert behavior which pushes the SRH after the existing IPv6 header. This
186 # Policy steers the traffic from hs-2 across rt-1 and finally to the
187 # destination hs-1
190 # When the router rt-1 receives the packet, the PSP enabled SRv6 End behavior
191 # associated with the SID fcff:1::ef1 is triggered. Since the SL=1,
192 # the PSP operation takes place: i) the SL is decremented; ii) the IPv6 DA is
193 # set with the last SID; iii) the SRH is removed from the extension headers
194 # after the IPv6 header. At this point, the packet with IPv6 DA=cafe::1 is sent
195 # to the destination, i.e. hs-1.
197 # Kselftest framework requirement - SKIP code is 4.
198 readonly ksft_skip=4
200 readonly RDMSUFF="$(mktemp -u XXXXXXXX)"
201 readonly DUMMY_DEVNAME="dum0"
202 readonly RT2HS_DEVNAME="veth1"
203 readonly LOCALSID_TABLE_ID=90
204 readonly IPv6_RT_NETWORK=fcf0:0
205 readonly IPv6_HS_NETWORK=cafe
206 readonly IPv6_TESTS_ADDR=2001:db8::1
207 readonly LOCATOR_SERVICE=fcff
208 readonly END_FUNC=000e
209 readonly END_PSP_FUNC=0ef1
211 PING_TIMEOUT_SEC=4
212 PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
214 # IDs of routers and hosts are initialized during the setup of the testing
215 # network
216 ROUTERS=''
217 HOSTS=''
219 SETUP_ERR=1
221 ret=${ksft_skip}
222 nsuccess=0
223 nfail=0
225 log_test()
227 local rc="$1"
228 local expected="$2"
229 local msg="$3"
231 if [ "${rc}" -eq "${expected}" ]; then
232 nsuccess=$((nsuccess+1))
233 printf "\n TEST: %-60s [ OK ]\n" "${msg}"
234 else
235 ret=1
236 nfail=$((nfail+1))
237 printf "\n TEST: %-60s [FAIL]\n" "${msg}"
238 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
239 echo
240 echo "hit enter to continue, 'q' to quit"
241 read a
242 [ "$a" = "q" ] && exit 1
247 print_log_test_results()
249 printf "\nTests passed: %3d\n" "${nsuccess}"
250 printf "Tests failed: %3d\n" "${nfail}"
252 # when a test fails, the value of 'ret' is set to 1 (error code).
253 # Conversely, when all tests are passed successfully, the 'ret' value
254 # is set to 0 (success code).
255 if [ "${ret}" -ne 1 ]; then
256 ret=0
260 log_section()
262 echo
263 echo "################################################################################"
264 echo "TEST SECTION: $*"
265 echo "################################################################################"
268 test_command_or_ksft_skip()
270 local cmd="$1"
272 if [ ! -x "$(command -v "${cmd}")" ]; then
273 echo "SKIP: Could not run test without \"${cmd}\" tool";
274 exit "${ksft_skip}"
278 get_nodename()
280 local name="$1"
282 echo "${name}-${RDMSUFF}"
285 get_rtname()
287 local rtid="$1"
289 get_nodename "rt-${rtid}"
292 get_hsname()
294 local hsid="$1"
296 get_nodename "hs-${hsid}"
299 __create_namespace()
301 local name="$1"
303 ip netns add "${name}"
306 create_router()
308 local rtid="$1"
309 local nsname
311 nsname="$(get_rtname "${rtid}")"
313 __create_namespace "${nsname}"
316 create_host()
318 local hsid="$1"
319 local nsname
321 nsname="$(get_hsname "${hsid}")"
323 __create_namespace "${nsname}"
326 cleanup()
328 local nsname
329 local i
331 # destroy routers
332 for i in ${ROUTERS}; do
333 nsname="$(get_rtname "${i}")"
335 ip netns del "${nsname}" &>/dev/null || true
336 done
338 # destroy hosts
339 for i in ${HOSTS}; do
340 nsname="$(get_hsname "${i}")"
342 ip netns del "${nsname}" &>/dev/null || true
343 done
345 # check whether the setup phase was completed successfully or not. In
346 # case of an error during the setup phase of the testing environment,
347 # the selftest is considered as "skipped".
348 if [ "${SETUP_ERR}" -ne 0 ]; then
349 echo "SKIP: Setting up the testing environment failed"
350 exit "${ksft_skip}"
353 exit "${ret}"
356 add_link_rt_pairs()
358 local rt="$1"
359 local rt_neighs="$2"
360 local neigh
361 local nsname
362 local neigh_nsname
364 nsname="$(get_rtname "${rt}")"
366 for neigh in ${rt_neighs}; do
367 neigh_nsname="$(get_rtname "${neigh}")"
369 ip link add "veth-rt-${rt}-${neigh}" netns "${nsname}" \
370 type veth peer name "veth-rt-${neigh}-${rt}" \
371 netns "${neigh_nsname}"
372 done
375 get_network_prefix()
377 local rt="$1"
378 local neigh="$2"
379 local p="${rt}"
380 local q="${neigh}"
382 if [ "${p}" -gt "${q}" ]; then
383 p="${q}"; q="${rt}"
386 echo "${IPv6_RT_NETWORK}:${p}:${q}"
389 # Given the description of a router <id:op> as an input, the function returns
390 # the <id> token which represents the ID of the router.
391 # i.e. input: "12:psp"
392 # output: "12"
393 __get_srv6_rtcfg_id()
395 local element="$1"
397 echo "${element}" | cut -d':' -f1
400 # Given the description of a router <id:op> as an input, the function returns
401 # the <op> token which represents the operation (e.g. End behavior with or
402 # withouth flavors) configured for the node.
404 # Note that when the operation represents an End behavior with a list of
405 # flavors, the output is the ordered version of that list.
406 # i.e. input: "5:usp,psp,usd"
407 # output: "psp,usd,usp"
408 __get_srv6_rtcfg_op()
410 local element="$1"
412 # return the lexicographically ordered flavors
413 echo "${element}" | cut -d':' -f2 | sed 's/,/\n/g' | sort | \
414 xargs | sed 's/ /,/g'
417 # Setup the basic networking for the routers
418 setup_rt_networking()
420 local rt="$1"
421 local rt_neighs="$2"
422 local nsname
423 local net_prefix
424 local devname
425 local neigh
427 nsname="$(get_rtname "${rt}")"
429 for neigh in ${rt_neighs}; do
430 devname="veth-rt-${rt}-${neigh}"
432 net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
434 ip -netns "${nsname}" addr \
435 add "${net_prefix}::${rt}/64" dev "${devname}" nodad
437 ip -netns "${nsname}" link set "${devname}" up
438 done
440 ip -netns "${nsname}" link set lo up
442 ip -netns "${nsname}" link add ${DUMMY_DEVNAME} type dummy
443 ip -netns "${nsname}" link set ${DUMMY_DEVNAME} up
445 ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.all.accept_dad=0
446 ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.default.accept_dad=0
447 ip netns exec "${nsname}" sysctl -wq net.ipv6.conf.all.forwarding=1
450 # Setup local SIDs for an SRv6 router
451 setup_rt_local_sids()
453 local rt="$1"
454 local rt_neighs="$2"
455 local net_prefix
456 local devname
457 local nsname
458 local neigh
460 nsname="$(get_rtname "${rt}")"
462 for neigh in ${rt_neighs}; do
463 devname="veth-rt-${rt}-${neigh}"
465 net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
467 # set underlay network routes for SIDs reachability
468 ip -netns "${nsname}" -6 route \
469 add "${LOCATOR_SERVICE}:${neigh}::/32" \
470 table "${LOCALSID_TABLE_ID}" \
471 via "${net_prefix}::${neigh}" dev "${devname}"
472 done
474 # Local End behavior (note that "dev" is a dummy interface chosen for
475 # the sake of simplicity).
476 ip -netns "${nsname}" -6 route \
477 add "${LOCATOR_SERVICE}:${rt}::${END_FUNC}" \
478 table "${LOCALSID_TABLE_ID}" \
479 encap seg6local action End dev "${DUMMY_DEVNAME}"
482 # all SIDs start with a common locator. Routes and SRv6 Endpoint
483 # behavior instaces are grouped together in the 'localsid' table.
484 ip -netns "${nsname}" -6 rule \
485 add to "${LOCATOR_SERVICE}::/16" \
486 lookup "${LOCALSID_TABLE_ID}" prio 999
488 # set default routes to unreachable
489 ip -netns "${nsname}" -6 route \
490 add unreachable default metric 4278198272 \
491 dev "${DUMMY_DEVNAME}"
494 # This helper function builds and installs the SID List (i.e. SRv6 Policy)
495 # to be applied on incoming packets at the ingress node. Moreover, it
496 # configures the SRv6 nodes specified in the SID List to process the traffic
497 # according to the operations required by the Policy itself.
498 # args:
499 # $1 - destination host (i.e. cafe::x host)
500 # $2 - SRv6 router configured for enforcing the SRv6 Policy
501 # $3 - compact way to represent a list of SRv6 routers with their operations
502 # (i.e. behaviors) that each of them needs to perform. Every <nodeid:op>
503 # element constructs a SID that is associated with the behavior <op> on
504 # the <nodeid> node. The list of such elements forms an SRv6 Policy.
505 __setup_rt_policy()
507 local dst="$1"
508 local encap_rt="$2"
509 local policy_rts="$3"
510 local behavior_cfg
511 local in_nsname
512 local rt_nsname
513 local policy=''
514 local function
515 local fullsid
516 local op_type
517 local node
518 local n
520 in_nsname="$(get_rtname "${encap_rt}")"
522 for n in ${policy_rts}; do
523 node="$(__get_srv6_rtcfg_id "${n}")"
524 op_type="$(__get_srv6_rtcfg_op "${n}")"
525 rt_nsname="$(get_rtname "${node}")"
527 case "${op_type}" in
528 "noflv")
529 policy="${policy}${LOCATOR_SERVICE}:${node}::${END_FUNC},"
530 function="${END_FUNC}"
531 behavior_cfg="End"
534 "psp")
535 policy="${policy}${LOCATOR_SERVICE}:${node}::${END_PSP_FUNC},"
536 function="${END_PSP_FUNC}"
537 behavior_cfg="End flavors psp"
541 break
543 esac
545 fullsid="${LOCATOR_SERVICE}:${node}::${function}"
547 # add SRv6 Endpoint behavior to the selected router
548 if ! ip -netns "${rt_nsname}" -6 route get "${fullsid}" \
549 &>/dev/null; then
550 ip -netns "${rt_nsname}" -6 route \
551 add "${fullsid}" \
552 table "${LOCALSID_TABLE_ID}" \
553 encap seg6local action ${behavior_cfg} \
554 dev "${DUMMY_DEVNAME}"
556 done
558 # we need to remove the trailing comma to avoid inserting an empty
559 # address (::0) in the SID List.
560 policy="${policy%,}"
562 # add SRv6 policy to incoming traffic sent by connected hosts
563 ip -netns "${in_nsname}" -6 route \
564 add "${IPv6_HS_NETWORK}::${dst}" \
565 encap seg6 mode inline segs "${policy}" \
566 dev "${DUMMY_DEVNAME}"
568 ip -netns "${in_nsname}" -6 neigh \
569 add proxy "${IPv6_HS_NETWORK}::${dst}" \
570 dev "${RT2HS_DEVNAME}"
573 # see __setup_rt_policy
574 setup_rt_policy_ipv6()
576 __setup_rt_policy "$1" "$2" "$3"
579 setup_hs()
581 local hs="$1"
582 local rt="$2"
583 local hsname
584 local rtname
586 hsname="$(get_hsname "${hs}")"
587 rtname="$(get_rtname "${rt}")"
589 ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.all.accept_dad=0
590 ip netns exec "${hsname}" sysctl -wq net.ipv6.conf.default.accept_dad=0
592 ip -netns "${hsname}" link add veth0 type veth \
593 peer name "${RT2HS_DEVNAME}" netns "${rtname}"
595 ip -netns "${hsname}" addr \
596 add "${IPv6_HS_NETWORK}::${hs}/64" dev veth0 nodad
598 ip -netns "${hsname}" link set veth0 up
599 ip -netns "${hsname}" link set lo up
601 ip -netns "${rtname}" addr \
602 add "${IPv6_HS_NETWORK}::254/64" dev "${RT2HS_DEVNAME}" nodad
604 ip -netns "${rtname}" link set "${RT2HS_DEVNAME}" up
606 ip netns exec "${rtname}" \
607 sysctl -wq net.ipv6.conf."${RT2HS_DEVNAME}".proxy_ndp=1
610 setup()
612 local i
614 # create routers
615 ROUTERS="1 2 3 4"; readonly ROUTERS
616 for i in ${ROUTERS}; do
617 create_router "${i}"
618 done
620 # create hosts
621 HOSTS="1 2"; readonly HOSTS
622 for i in ${HOSTS}; do
623 create_host "${i}"
624 done
626 # set up the links for connecting routers
627 add_link_rt_pairs 1 "2 3 4"
628 add_link_rt_pairs 2 "3 4"
629 add_link_rt_pairs 3 "4"
631 # set up the basic connectivity of routers and routes required for
632 # reachability of SIDs.
633 setup_rt_networking 1 "2 3 4"
634 setup_rt_networking 2 "1 3 4"
635 setup_rt_networking 3 "1 2 4"
636 setup_rt_networking 4 "1 2 3"
638 # set up the hosts connected to routers
639 setup_hs 1 1
640 setup_hs 2 2
642 # set up default SRv6 Endpoints (i.e. SRv6 End behavior)
643 setup_rt_local_sids 1 "2 3 4"
644 setup_rt_local_sids 2 "1 3 4"
645 setup_rt_local_sids 3 "1 2 4"
646 setup_rt_local_sids 4 "1 2 3"
648 # set up SRv6 policies
649 # create a connection between hosts hs-1 and hs-2.
650 # The path between hs-1 and hs-2 traverses SRv6 aware routers.
651 # For each direction two path are chosen:
653 # Direction hs-1 -> hs-2 (PSP flavor)
654 # - rt-1 (SRv6 H.Insert policy)
655 # - rt-3 (SRv6 End behavior)
656 # - rt-4 (SRv6 End flavor PSP with SL>1, acting as End behavior)
657 # - rt-2 (SRv6 End flavor PSP with SL=1)
659 # Direction hs-2 -> hs-1 (PSP flavor)
660 # - rt-2 (SRv6 H.Insert policy)
661 # - rt-1 (SRv6 End flavor PSP with SL=1)
662 setup_rt_policy_ipv6 2 1 "3:noflv 4:psp 2:psp"
663 setup_rt_policy_ipv6 1 2 "1:psp"
665 # testing environment was set up successfully
666 SETUP_ERR=0
669 check_rt_connectivity()
671 local rtsrc="$1"
672 local rtdst="$2"
673 local prefix
674 local rtsrc_nsname
676 rtsrc_nsname="$(get_rtname "${rtsrc}")"
678 prefix="$(get_network_prefix "${rtsrc}" "${rtdst}")"
680 ip netns exec "${rtsrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
681 "${prefix}::${rtdst}" >/dev/null 2>&1
684 check_and_log_rt_connectivity()
686 local rtsrc="$1"
687 local rtdst="$2"
689 check_rt_connectivity "${rtsrc}" "${rtdst}"
690 log_test $? 0 "Routers connectivity: rt-${rtsrc} -> rt-${rtdst}"
693 check_hs_ipv6_connectivity()
695 local hssrc="$1"
696 local hsdst="$2"
697 local hssrc_nsname
699 hssrc_nsname="$(get_hsname "${hssrc}")"
701 ip netns exec "${hssrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
702 "${IPv6_HS_NETWORK}::${hsdst}" >/dev/null 2>&1
705 check_and_log_hs2gw_connectivity()
707 local hssrc="$1"
709 check_hs_ipv6_connectivity "${hssrc}" 254
710 log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> gw"
713 check_and_log_hs_ipv6_connectivity()
715 local hssrc="$1"
716 local hsdst="$2"
718 check_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
719 log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}"
722 check_and_log_hs_connectivity()
724 local hssrc="$1"
725 local hsdst="$2"
727 check_and_log_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
730 router_tests()
732 local i
733 local j
735 log_section "IPv6 routers connectivity test"
737 for i in ${ROUTERS}; do
738 for j in ${ROUTERS}; do
739 if [ "${i}" -eq "${j}" ]; then
740 continue
743 check_and_log_rt_connectivity "${i}" "${j}"
744 done
745 done
748 host2gateway_tests()
750 local hs
752 log_section "IPv6 connectivity test among hosts and gateways"
754 for hs in ${HOSTS}; do
755 check_and_log_hs2gw_connectivity "${hs}"
756 done
759 host_srv6_end_flv_psp_tests()
761 log_section "SRv6 connectivity test hosts (h1 <-> h2, PSP flavor)"
763 check_and_log_hs_connectivity 1 2
764 check_and_log_hs_connectivity 2 1
767 test_iproute2_supp_or_ksft_skip()
769 local flavor="$1"
771 if ! ip route help 2>&1 | grep -qo "${flavor}"; then
772 echo "SKIP: Missing SRv6 ${flavor} flavor support in iproute2"
773 exit "${ksft_skip}"
777 test_kernel_supp_or_ksft_skip()
779 local flavor="$1"
780 local test_netns
782 test_netns="kflv-$(mktemp -u XXXXXXXX)"
784 if ! ip netns add "${test_netns}"; then
785 echo "SKIP: Cannot set up netns to test kernel support for flavors"
786 exit "${ksft_skip}"
789 if ! ip -netns "${test_netns}" link \
790 add "${DUMMY_DEVNAME}" type dummy; then
791 echo "SKIP: Cannot set up dummy dev to test kernel support for flavors"
793 ip netns del "${test_netns}"
794 exit "${ksft_skip}"
797 if ! ip -netns "${test_netns}" link \
798 set "${DUMMY_DEVNAME}" up; then
799 echo "SKIP: Cannot activate dummy dev to test kernel support for flavors"
801 ip netns del "${test_netns}"
802 exit "${ksft_skip}"
805 if ! ip -netns "${test_netns}" -6 route \
806 add "${IPv6_TESTS_ADDR}" encap seg6local \
807 action End flavors "${flavor}" dev "${DUMMY_DEVNAME}"; then
808 echo "SKIP: ${flavor} flavor not supported in kernel"
810 ip netns del "${test_netns}"
811 exit "${ksft_skip}"
814 ip netns del "${test_netns}"
817 test_dummy_dev_or_ksft_skip()
819 local test_netns
821 test_netns="dummy-$(mktemp -u XXXXXXXX)"
823 if ! ip netns add "${test_netns}"; then
824 echo "SKIP: Cannot set up netns for testing dummy dev support"
825 exit "${ksft_skip}"
828 modprobe dummy &>/dev/null || true
829 if ! ip -netns "${test_netns}" link \
830 add "${DUMMY_DEVNAME}" type dummy; then
831 echo "SKIP: dummy dev not supported"
833 ip netns del "${test_netns}"
834 exit "${ksft_skip}"
837 ip netns del "${test_netns}"
840 if [ "$(id -u)" -ne 0 ]; then
841 echo "SKIP: Need root privileges"
842 exit "${ksft_skip}"
845 # required programs to carry out this selftest
846 test_command_or_ksft_skip ip
847 test_command_or_ksft_skip ping
848 test_command_or_ksft_skip sysctl
849 test_command_or_ksft_skip grep
850 test_command_or_ksft_skip cut
851 test_command_or_ksft_skip sed
852 test_command_or_ksft_skip sort
853 test_command_or_ksft_skip xargs
855 test_dummy_dev_or_ksft_skip
856 test_iproute2_supp_or_ksft_skip psp
857 test_kernel_supp_or_ksft_skip psp
859 set -e
860 trap cleanup EXIT
862 setup
863 set +e
865 router_tests
866 host2gateway_tests
867 host_srv6_end_flv_psp_tests
869 print_log_test_results