~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/srv6_end_flavors_test.sh

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/bin/bash
  2 # SPDX-License-Identifier: GPL-2.0
  3 #
  4 # author: Andrea Mayer <andrea.mayer@uniroma2.it>
  5 # author: Paolo Lungaroni <paolo.lungaroni@uniroma2.it>
  6 #
  7 # This script is designed to test the support for "flavors" in the SRv6 End
  8 # behavior.
  9 #
 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).
 16 #
 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.
 22 #
 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.
 31 #
 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).
 35 #
 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.
 49 #
 50 # [1] RFC8986: https://datatracker.ietf.org/doc/html/rfc8986
 51 #
 52 # Network topology
 53 # ================
 54 #
 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:
 62 #
 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;
 67 #
 68 #  ii) The SRv6 End behavior advances the active SID in the SID List carried by
 69 #      the SRH;
 70 #
 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.
 74 #
 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 #              +---+----+                   +----+---+
102 #
103 # Every fcf0:0:x:y::/64 network interconnects the SRv6 routers rt-x with rt-y in
104 # the IPv6 operator network.
105 #
106 #
107 # Local SID table
108 # ===============
109 #
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:
113 #
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 #   +---------------------------------------------------------------------+
119 #
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.
123 #
124 #
125 # SRv6 Policies
126 # =============
127 #
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.
133 #
134 #   Before applying an SRv6 Policy using the SRv6 H.Insert behavior
135 #   +------+---------+
136 #   | IPv6 | Payload |
137 #   +------+---------+
138 #
139 #   After applying an SRv6 Policy using the SRv6 H.Insert behavior
140 #   +------+-----+---------+
141 #   | IPv6 | SRH | Payload |
142 #   +------+-----+---------+
143 #
144 # Traffic from hs-1 to hs-2
145 # -------------------------
146 #
147 # Packets generated from hs-1 and directed towards hs-2 are
148 # handled by rt-1 which applies the following SRv6 Policy:
149 #
150 #   i.a) IPv6 traffic, SID List=fcff:3::e,fcff:4::ef1,fcff:2::ef1,cafe::2
151 #
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.
156 #
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.
161 #
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.
167 #
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).
175 #
176 # Traffic from hs-2 to hs-1
177 # -------------------------
178 #
179 # Packets generated from hs-2 and directed to hs-1 are handled by rt-2 which
180 # applies the following SRv6 Policy:
181 #
182 #   i.b) IPv6 traffic, SID List=fcff:1::ef1,cafe::1
183 #
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
188 #
189 #
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.
196 
197 # Kselftest framework requirement - SKIP code is 4.
198 readonly ksft_skip=4
199 
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
210 
211 PING_TIMEOUT_SEC=4
212 PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
213 
214 # IDs of routers and hosts are initialized during the setup of the testing
215 # network
216 ROUTERS=''
217 HOSTS=''
218 
219 SETUP_ERR=1
220 
221 ret=${ksft_skip}
222 nsuccess=0
223 nfail=0
224 
225 log_test()
226 {
227         local rc="$1"
228         local expected="$2"
229         local msg="$3"
230 
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
243                 fi
244         fi
245 }
246 
247 print_log_test_results()
248 {
249         printf "\nTests passed: %3d\n" "${nsuccess}"
250         printf "Tests failed: %3d\n"   "${nfail}"
251 
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
257         fi
258 }
259 
260 log_section()
261 {
262         echo
263         echo "################################################################################"
264         echo "TEST SECTION: $*"
265         echo "################################################################################"
266 }
267 
268 test_command_or_ksft_skip()
269 {
270         local cmd="$1"
271 
272         if [ ! -x "$(command -v "${cmd}")" ]; then
273                 echo "SKIP: Could not run test without \"${cmd}\" tool";
274                 exit "${ksft_skip}"
275         fi
276 }
277 
278 get_nodename()
279 {
280         local name="$1"
281 
282         echo "${name}-${RDMSUFF}"
283 }
284 
285 get_rtname()
286 {
287         local rtid="$1"
288 
289         get_nodename "rt-${rtid}"
290 }
291 
292 get_hsname()
293 {
294         local hsid="$1"
295 
296         get_nodename "hs-${hsid}"
297 }
298 
299 __create_namespace()
300 {
301         local name="$1"
302 
303         ip netns add "${name}"
304 }
305 
306 create_router()
307 {
308         local rtid="$1"
309         local nsname
310 
311         nsname="$(get_rtname "${rtid}")"
312 
313         __create_namespace "${nsname}"
314 }
315 
316 create_host()
317 {
318         local hsid="$1"
319         local nsname
320 
321         nsname="$(get_hsname "${hsid}")"
322 
323         __create_namespace "${nsname}"
324 }
325 
326 cleanup()
327 {
328         local nsname
329         local i
330 
331         # destroy routers
332         for i in ${ROUTERS}; do
333                 nsname="$(get_rtname "${i}")"
334 
335                 ip netns del "${nsname}" &>/dev/null || true
336         done
337 
338         # destroy hosts
339         for i in ${HOSTS}; do
340                 nsname="$(get_hsname "${i}")"
341 
342                 ip netns del "${nsname}" &>/dev/null || true
343         done
344 
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}"
351         fi
352 
353         exit "${ret}"
354 }
355 
356 add_link_rt_pairs()
357 {
358         local rt="$1"
359         local rt_neighs="$2"
360         local neigh
361         local nsname
362         local neigh_nsname
363 
364         nsname="$(get_rtname "${rt}")"
365 
366         for neigh in ${rt_neighs}; do
367                 neigh_nsname="$(get_rtname "${neigh}")"
368 
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
373 }
374 
375 get_network_prefix()
376 {
377         local rt="$1"
378         local neigh="$2"
379         local p="${rt}"
380         local q="${neigh}"
381 
382         if [ "${p}" -gt "${q}" ]; then
383                 p="${q}"; q="${rt}"
384         fi
385 
386         echo "${IPv6_RT_NETWORK}:${p}:${q}"
387 }
388 
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()
394 {
395         local element="$1"
396 
397         echo "${element}" | cut -d':' -f1
398 }
399 
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.
403 
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()
409 {
410         local element="$1"
411 
412         # return the lexicographically ordered flavors
413         echo "${element}" | cut -d':' -f2 | sed 's/,/\n/g' | sort | \
414                 xargs | sed 's/ /,/g'
415 }
416 
417 # Setup the basic networking for the routers
418 setup_rt_networking()
419 {
420         local rt="$1"
421         local rt_neighs="$2"
422         local nsname
423         local net_prefix
424         local devname
425         local neigh
426 
427         nsname="$(get_rtname "${rt}")"
428 
429         for neigh in ${rt_neighs}; do
430                 devname="veth-rt-${rt}-${neigh}"
431 
432                 net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
433 
434                 ip -netns "${nsname}" addr \
435                         add "${net_prefix}::${rt}/64" dev "${devname}" nodad
436 
437                 ip -netns "${nsname}" link set "${devname}" up
438         done
439 
440         ip -netns "${nsname}" link set lo up
441 
442         ip -netns "${nsname}" link add ${DUMMY_DEVNAME} type dummy
443         ip -netns "${nsname}" link set ${DUMMY_DEVNAME} up
444 
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
448 }
449 
450 # Setup local SIDs for an SRv6 router
451 setup_rt_local_sids()
452 {
453         local rt="$1"
454         local rt_neighs="$2"
455         local net_prefix
456         local devname
457         local nsname
458         local neigh
459 
460         nsname="$(get_rtname "${rt}")"
461 
462         for neigh in ${rt_neighs}; do
463                 devname="veth-rt-${rt}-${neigh}"
464 
465                 net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
466 
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
473 
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}"
480 
481 
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
487 
488         # set default routes to unreachable
489         ip -netns "${nsname}" -6 route \
490                 add unreachable default metric 4278198272 \
491                 dev "${DUMMY_DEVNAME}"
492 }
493 
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()
506 {
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
519 
520         in_nsname="$(get_rtname "${encap_rt}")"
521 
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}")"
526 
527                 case "${op_type}" in
528                 "noflv")
529                         policy="${policy}${LOCATOR_SERVICE}:${node}::${END_FUNC},"
530                         function="${END_FUNC}"
531                         behavior_cfg="End"
532                         ;;
533 
534                 "psp")
535                         policy="${policy}${LOCATOR_SERVICE}:${node}::${END_PSP_FUNC},"
536                         function="${END_PSP_FUNC}"
537                         behavior_cfg="End flavors psp"
538                         ;;
539 
540                 *)
541                         break
542                         ;;
543                 esac
544 
545                 fullsid="${LOCATOR_SERVICE}:${node}::${function}"
546 
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}"
555                 fi
556         done
557 
558         # we need to remove the trailing comma to avoid inserting an empty
559         # address (::0) in the SID List.
560         policy="${policy%,}"
561 
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}"
567 
568         ip -netns "${in_nsname}" -6 neigh \
569                 add proxy "${IPv6_HS_NETWORK}::${dst}" \
570                 dev "${RT2HS_DEVNAME}"
571 }
572 
573 # see __setup_rt_policy
574 setup_rt_policy_ipv6()
575 {
576         __setup_rt_policy "$1" "$2" "$3"
577 }
578 
579 setup_hs()
580 {
581         local hs="$1"
582         local rt="$2"
583         local hsname
584         local rtname
585 
586         hsname="$(get_hsname "${hs}")"
587         rtname="$(get_rtname "${rt}")"
588 
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
591 
592         ip -netns "${hsname}" link add veth0 type veth \
593                 peer name "${RT2HS_DEVNAME}" netns "${rtname}"
594 
595         ip -netns "${hsname}" addr \
596                 add "${IPv6_HS_NETWORK}::${hs}/64" dev veth0 nodad
597 
598         ip -netns "${hsname}" link set veth0 up
599         ip -netns "${hsname}" link set lo up
600 
601         ip -netns "${rtname}" addr \
602                 add "${IPv6_HS_NETWORK}::254/64" dev "${RT2HS_DEVNAME}" nodad
603 
604         ip -netns "${rtname}" link set "${RT2HS_DEVNAME}" up
605 
606         ip netns exec "${rtname}" \
607                 sysctl -wq net.ipv6.conf."${RT2HS_DEVNAME}".proxy_ndp=1
608 }
609 
610 setup()
611 {
612         local i
613 
614         # create routers
615         ROUTERS="1 2 3 4"; readonly ROUTERS
616         for i in ${ROUTERS}; do
617                 create_router "${i}"
618         done
619 
620         # create hosts
621         HOSTS="1 2"; readonly HOSTS
622         for i in ${HOSTS}; do
623                 create_host "${i}"
624         done
625 
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"
630 
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"
637 
638         # set up the hosts connected to routers
639         setup_hs 1 1
640         setup_hs 2 2
641 
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"
647 
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:
652         #
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)
658         #
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"
664 
665         # testing environment was set up successfully
666         SETUP_ERR=0
667 }
668 
669 check_rt_connectivity()
670 {
671         local rtsrc="$1"
672         local rtdst="$2"
673         local prefix
674         local rtsrc_nsname
675 
676         rtsrc_nsname="$(get_rtname "${rtsrc}")"
677 
678         prefix="$(get_network_prefix "${rtsrc}" "${rtdst}")"
679 
680         ip netns exec "${rtsrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
681                 "${prefix}::${rtdst}" >/dev/null 2>&1
682 }
683 
684 check_and_log_rt_connectivity()
685 {
686         local rtsrc="$1"
687         local rtdst="$2"
688 
689         check_rt_connectivity "${rtsrc}" "${rtdst}"
690         log_test $? 0 "Routers connectivity: rt-${rtsrc} -> rt-${rtdst}"
691 }
692 
693 check_hs_ipv6_connectivity()
694 {
695         local hssrc="$1"
696         local hsdst="$2"
697         local hssrc_nsname
698 
699         hssrc_nsname="$(get_hsname "${hssrc}")"
700 
701         ip netns exec "${hssrc_nsname}" ping -c 1 -W "${PING_TIMEOUT_SEC}" \
702                 "${IPv6_HS_NETWORK}::${hsdst}" >/dev/null 2>&1
703 }
704 
705 check_and_log_hs2gw_connectivity()
706 {
707         local hssrc="$1"
708 
709         check_hs_ipv6_connectivity "${hssrc}" 254
710         log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> gw"
711 }
712 
713 check_and_log_hs_ipv6_connectivity()
714 {
715         local hssrc="$1"
716         local hsdst="$2"
717 
718         check_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
719         log_test $? 0 "IPv6 Hosts connectivity: hs-${hssrc} -> hs-${hsdst}"
720 }
721 
722 check_and_log_hs_connectivity()
723 {
724         local hssrc="$1"
725         local hsdst="$2"
726 
727         check_and_log_hs_ipv6_connectivity "${hssrc}" "${hsdst}"
728 }
729 
730 router_tests()
731 {
732         local i
733         local j
734 
735         log_section "IPv6 routers connectivity test"
736 
737         for i in ${ROUTERS}; do
738                 for j in ${ROUTERS}; do
739                         if [ "${i}" -eq "${j}" ]; then
740                                 continue
741                         fi
742 
743                         check_and_log_rt_connectivity "${i}" "${j}"
744                 done
745         done
746 }
747 
748 host2gateway_tests()
749 {
750         local hs
751 
752         log_section "IPv6 connectivity test among hosts and gateways"
753 
754         for hs in ${HOSTS}; do
755                 check_and_log_hs2gw_connectivity "${hs}"
756         done
757 }
758 
759 host_srv6_end_flv_psp_tests()
760 {
761         log_section "SRv6 connectivity test hosts (h1 <-> h2, PSP flavor)"
762 
763         check_and_log_hs_connectivity 1 2
764         check_and_log_hs_connectivity 2 1
765 }
766 
767 test_iproute2_supp_or_ksft_skip()
768 {
769         local flavor="$1"
770 
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}"
774         fi
775 }
776 
777 test_kernel_supp_or_ksft_skip()
778 {
779         local flavor="$1"
780         local test_netns
781 
782         test_netns="kflv-$(mktemp -u XXXXXXXX)"
783 
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}"
787         fi
788 
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"
792 
793                 ip netns del "${test_netns}"
794                 exit "${ksft_skip}"
795         fi
796 
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"
800 
801                 ip netns del "${test_netns}"
802                 exit "${ksft_skip}"
803         fi
804 
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"
809 
810                 ip netns del "${test_netns}"
811                 exit "${ksft_skip}"
812         fi
813 
814         ip netns del "${test_netns}"
815 }
816 
817 test_dummy_dev_or_ksft_skip()
818 {
819         local test_netns
820 
821         test_netns="dummy-$(mktemp -u XXXXXXXX)"
822 
823         if ! ip netns add "${test_netns}"; then
824                 echo "SKIP: Cannot set up netns for testing dummy dev support"
825                 exit "${ksft_skip}"
826         fi
827 
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"
832 
833                 ip netns del "${test_netns}"
834                 exit "${ksft_skip}"
835         fi
836 
837         ip netns del "${test_netns}"
838 }
839 
840 if [ "$(id -u)" -ne 0 ]; then
841         echo "SKIP: Need root privileges"
842         exit "${ksft_skip}"
843 fi
844 
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
854 
855 test_dummy_dev_or_ksft_skip
856 test_iproute2_supp_or_ksft_skip psp
857 test_kernel_supp_or_ksft_skip psp
858 
859 set -e
860 trap cleanup EXIT
861 
862 setup
863 set +e
864 
865 router_tests
866 host2gateway_tests
867 host_srv6_end_flv_psp_tests
868 
869 print_log_test_results

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php