Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # Test traffic distribution when there are multiple paths between an IPv6 GRE
0005 # tunnel. The tunnel carries IPv4 and IPv6 traffic between multiple hosts.
0006 # Multiple routes are in the underlay network. With the default multipath
0007 # policy, SW2 will only look at the outer IP addresses, hence only a single
0008 # route would be used.
0009 #
0010 # +--------------------------------+
0011 # | H1                             |
0012 # |                     $h1 +      |
0013 # |   198.51.100.{2-253}/24 |      |
0014 # |   2001:db8:1::{2-fd}/64 |      |
0015 # +-------------------------|------+
0016 #                           |
0017 # +-------------------------|-------------------+
0018 # | SW1                     |                   |
0019 # |                    $ol1 +                   |
0020 # |         198.51.100.1/24                     |
0021 # |        2001:db8:1::1/64                     |
0022 # |                                             |
0023 # |+ g1 (ip6gre)                                |
0024 # |  loc=2001:db8:3::1                          |
0025 # |  rem=2001:db8:3::2 -.                       |
0026 # |     tos=inherit     |                       |
0027 # |                     v                       |
0028 # |                     + $ul1                  |
0029 # |                     | 2001:db8:10::1/64     |
0030 # +---------------------|-----------------------+
0031 #                       |
0032 # +---------------------|-----------------------+
0033 # | SW2                 |                       |
0034 # |               $ul21 +                       |
0035 # |   2001:db8:10::2/64 |                       |
0036 # |                     |                       |
0037 # !   __________________+___                    |
0038 # |  /                      \                   |
0039 # |  |                      |                   |
0040 # |  + $ul22.111 (vlan)     + $ul22.222 (vlan)  |
0041 # |  | 2001:db8:11::1/64    | 2001:db8:12::1/64 |
0042 # |  |                      |                   |
0043 # +--|----------------------|-------------------+
0044 #    |                      |
0045 # +--|----------------------|-------------------+
0046 # |  |                      |                   |
0047 # |  + $ul32.111 (vlan)     + $ul32.222 (vlan)  |
0048 # |  | 2001:db8:11::2/64    | 2001:db8:12::2/64 |
0049 # |  |                      |                   |
0050 # |  \__________________+___/                   |
0051 # |                     |                       |
0052 # |                     |                       |
0053 # |               $ul31 +                       |
0054 # |   2001:db8:13::1/64 |                   SW3 |
0055 # +---------------------|-----------------------+
0056 #                       |
0057 # +---------------------|-----------------------+
0058 # |                     + $ul4                  |
0059 # |                     ^ 2001:db8:13::2/64     |
0060 # |                     |                       |
0061 # |+ g2 (ip6gre)        |                       |
0062 # |  loc=2001:db8:3::2  |                       |
0063 # |  rem=2001:db8:3::1 -'                       |
0064 # |  tos=inherit                                |
0065 # |                                             |
0066 # |                    $ol4 +                   |
0067 # |          203.0.113.1/24 |                   |
0068 # |        2001:db8:2::1/64 |               SW4 |
0069 # +-------------------------|-------------------+
0070 #                           |
0071 # +-------------------------|------+
0072 # |                         |      |
0073 # |                     $h2 +      |
0074 # |    203.0.113.{2-253}/24        |
0075 # |   2001:db8:2::{2-fd}/64     H2 |
0076 # +--------------------------------+
0077 
0078 ALL_TESTS="
0079         ping_ipv4
0080         ping_ipv6
0081         custom_hash
0082 "
0083 
0084 NUM_NETIFS=10
0085 source lib.sh
0086 
0087 h1_create()
0088 {
0089         simple_if_init $h1 198.51.100.2/24 2001:db8:1::2/64
0090         ip route add vrf v$h1 default via 198.51.100.1 dev $h1
0091         ip -6 route add vrf v$h1 default via 2001:db8:1::1 dev $h1
0092 }
0093 
0094 h1_destroy()
0095 {
0096         ip -6 route del vrf v$h1 default
0097         ip route del vrf v$h1 default
0098         simple_if_fini $h1 198.51.100.2/24 2001:db8:1::2/64
0099 }
0100 
0101 sw1_create()
0102 {
0103         simple_if_init $ol1 198.51.100.1/24 2001:db8:1::1/64
0104         __simple_if_init $ul1 v$ol1 2001:db8:10::1/64
0105 
0106         tunnel_create g1 ip6gre 2001:db8:3::1 2001:db8:3::2 tos inherit \
0107                 dev v$ol1
0108         __simple_if_init g1 v$ol1 2001:db8:3::1/128
0109         ip route add vrf v$ol1 2001:db8:3::2/128 via 2001:db8:10::2
0110 
0111         ip route add vrf v$ol1 203.0.113.0/24 dev g1
0112         ip -6 route add vrf v$ol1 2001:db8:2::/64 dev g1
0113 }
0114 
0115 sw1_destroy()
0116 {
0117         ip -6 route del vrf v$ol1 2001:db8:2::/64
0118         ip route del vrf v$ol1 203.0.113.0/24
0119 
0120         ip route del vrf v$ol1 2001:db8:3::2/128
0121         __simple_if_fini g1 2001:db8:3::1/128
0122         tunnel_destroy g1
0123 
0124         __simple_if_fini $ul1 2001:db8:10::1/64
0125         simple_if_fini $ol1 198.51.100.1/24 2001:db8:1::1/64
0126 }
0127 
0128 sw2_create()
0129 {
0130         simple_if_init $ul21 2001:db8:10::2/64
0131         __simple_if_init $ul22 v$ul21
0132         vlan_create $ul22 111 v$ul21 2001:db8:11::1/64
0133         vlan_create $ul22 222 v$ul21 2001:db8:12::1/64
0134 
0135         ip -6 route add vrf v$ul21 2001:db8:3::1/128 via 2001:db8:10::1
0136         ip -6 route add vrf v$ul21 2001:db8:3::2/128 \
0137            nexthop via 2001:db8:11::2 \
0138            nexthop via 2001:db8:12::2
0139 }
0140 
0141 sw2_destroy()
0142 {
0143         ip -6 route del vrf v$ul21 2001:db8:3::2/128
0144         ip -6 route del vrf v$ul21 2001:db8:3::1/128
0145 
0146         vlan_destroy $ul22 222
0147         vlan_destroy $ul22 111
0148         __simple_if_fini $ul22
0149         simple_if_fini $ul21 2001:db8:10::2/64
0150 }
0151 
0152 sw3_create()
0153 {
0154         simple_if_init $ul31 2001:db8:13::1/64
0155         __simple_if_init $ul32 v$ul31
0156         vlan_create $ul32 111 v$ul31 2001:db8:11::2/64
0157         vlan_create $ul32 222 v$ul31 2001:db8:12::2/64
0158 
0159         ip -6 route add vrf v$ul31 2001:db8:3::2/128 via 2001:db8:13::2
0160         ip -6 route add vrf v$ul31 2001:db8:3::1/128 \
0161            nexthop via 2001:db8:11::1 \
0162            nexthop via 2001:db8:12::1
0163 
0164         tc qdisc add dev $ul32 clsact
0165         tc filter add dev $ul32 ingress pref 111 prot 802.1Q \
0166            flower vlan_id 111 action pass
0167         tc filter add dev $ul32 ingress pref 222 prot 802.1Q \
0168            flower vlan_id 222 action pass
0169 }
0170 
0171 sw3_destroy()
0172 {
0173         tc qdisc del dev $ul32 clsact
0174 
0175         ip -6 route del vrf v$ul31 2001:db8:3::1/128
0176         ip -6 route del vrf v$ul31 2001:db8:3::2/128
0177 
0178         vlan_destroy $ul32 222
0179         vlan_destroy $ul32 111
0180         __simple_if_fini $ul32
0181         simple_if_fini $ul31 2001:db8:13::1/64
0182 }
0183 
0184 sw4_create()
0185 {
0186         simple_if_init $ol4 203.0.113.1/24 2001:db8:2::1/64
0187         __simple_if_init $ul4 v$ol4 2001:db8:13::2/64
0188 
0189         tunnel_create g2 ip6gre 2001:db8:3::2 2001:db8:3::1 tos inherit \
0190                 dev v$ol4
0191         __simple_if_init g2 v$ol4 2001:db8:3::2/128
0192         ip -6 route add vrf v$ol4 2001:db8:3::1/128 via 2001:db8:13::1
0193 
0194         ip route add vrf v$ol4 198.51.100.0/24 dev g2
0195         ip -6 route add vrf v$ol4 2001:db8:1::/64 dev g2
0196 }
0197 
0198 sw4_destroy()
0199 {
0200         ip -6 route del vrf v$ol4 2001:db8:1::/64
0201         ip route del vrf v$ol4 198.51.100.0/24
0202 
0203         ip -6 route del vrf v$ol4 2001:db8:3::1/128
0204         __simple_if_fini g2 2001:db8:3::2/128
0205         tunnel_destroy g2
0206 
0207         __simple_if_fini $ul4 2001:db8:13::2/64
0208         simple_if_fini $ol4 203.0.113.1/24 2001:db8:2::1/64
0209 }
0210 
0211 h2_create()
0212 {
0213         simple_if_init $h2 203.0.113.2/24 2001:db8:2::2/64
0214         ip route add vrf v$h2 default via 203.0.113.1 dev $h2
0215         ip -6 route add vrf v$h2 default via 2001:db8:2::1 dev $h2
0216 }
0217 
0218 h2_destroy()
0219 {
0220         ip -6 route del vrf v$h2 default
0221         ip route del vrf v$h2 default
0222         simple_if_fini $h2 203.0.113.2/24 2001:db8:2::2/64
0223 }
0224 
0225 setup_prepare()
0226 {
0227         h1=${NETIFS[p1]}
0228 
0229         ol1=${NETIFS[p2]}
0230         ul1=${NETIFS[p3]}
0231 
0232         ul21=${NETIFS[p4]}
0233         ul22=${NETIFS[p5]}
0234 
0235         ul32=${NETIFS[p6]}
0236         ul31=${NETIFS[p7]}
0237 
0238         ul4=${NETIFS[p8]}
0239         ol4=${NETIFS[p9]}
0240 
0241         h2=${NETIFS[p10]}
0242 
0243         vrf_prepare
0244         h1_create
0245         sw1_create
0246         sw2_create
0247         sw3_create
0248         sw4_create
0249         h2_create
0250 
0251         forwarding_enable
0252 }
0253 
0254 cleanup()
0255 {
0256         pre_cleanup
0257 
0258         forwarding_restore
0259 
0260         h2_destroy
0261         sw4_destroy
0262         sw3_destroy
0263         sw2_destroy
0264         sw1_destroy
0265         h1_destroy
0266         vrf_cleanup
0267 }
0268 
0269 ping_ipv4()
0270 {
0271         ping_test $h1 203.0.113.2
0272 }
0273 
0274 ping_ipv6()
0275 {
0276         ping6_test $h1 2001:db8:2::2
0277 }
0278 
0279 send_src_ipv4()
0280 {
0281         ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0282                 -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \
0283                 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0284 }
0285 
0286 send_dst_ipv4()
0287 {
0288         ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0289                 -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \
0290                 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0291 }
0292 
0293 send_src_udp4()
0294 {
0295         ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0296                 -A 198.51.100.2 -B 203.0.113.2 \
0297                 -d 1msec -t udp "sp=0-32768,dp=30000"
0298 }
0299 
0300 send_dst_udp4()
0301 {
0302         ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0303                 -A 198.51.100.2 -B 203.0.113.2 \
0304                 -d 1msec -t udp "sp=20000,dp=0-32768"
0305 }
0306 
0307 send_src_ipv6()
0308 {
0309         ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0310                 -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:2::2 \
0311                 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0312 }
0313 
0314 send_dst_ipv6()
0315 {
0316         ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0317                 -A 2001:db8:1::2 -B "2001:db8:2::2-2001:db8:2::fd" \
0318                 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0319 }
0320 
0321 send_flowlabel()
0322 {
0323         # Generate 16384 echo requests, each with a random flow label.
0324         for _ in $(seq 1 16384); do
0325                 ip vrf exec v$h1 \
0326                         $PING6 2001:db8:2::2 -F 0 -c 1 -q >/dev/null 2>&1
0327         done
0328 }
0329 
0330 send_src_udp6()
0331 {
0332         ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0333                 -A 2001:db8:1::2 -B 2001:db8:2::2 \
0334                 -d 1msec -t udp "sp=0-32768,dp=30000"
0335 }
0336 
0337 send_dst_udp6()
0338 {
0339         ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0340                 -A 2001:db8:1::2 -B 2001:db8:2::2 \
0341                 -d 1msec -t udp "sp=20000,dp=0-32768"
0342 }
0343 
0344 custom_hash_test()
0345 {
0346         local field="$1"; shift
0347         local balanced="$1"; shift
0348         local send_flows="$@"
0349 
0350         RET=0
0351 
0352         local t0_111=$(tc_rule_stats_get $ul32 111 ingress)
0353         local t0_222=$(tc_rule_stats_get $ul32 222 ingress)
0354 
0355         $send_flows
0356 
0357         local t1_111=$(tc_rule_stats_get $ul32 111 ingress)
0358         local t1_222=$(tc_rule_stats_get $ul32 222 ingress)
0359 
0360         local d111=$((t1_111 - t0_111))
0361         local d222=$((t1_222 - t0_222))
0362 
0363         local diff=$((d222 - d111))
0364         local sum=$((d111 + d222))
0365 
0366         local pct=$(echo "$diff / $sum * 100" | bc -l)
0367         local is_balanced=$(echo "-20 <= $pct && $pct <= 20" | bc)
0368 
0369         [[ ( $is_balanced -eq 1 && $balanced == "balanced" ) ||
0370            ( $is_balanced -eq 0 && $balanced == "unbalanced" ) ]]
0371         check_err $? "Expected traffic to be $balanced, but it is not"
0372 
0373         log_test "Multipath hash field: $field ($balanced)"
0374         log_info "Packets sent on path1 / path2: $d111 / $d222"
0375 }
0376 
0377 custom_hash_v4()
0378 {
0379         log_info "Running IPv4 overlay custom multipath hash tests"
0380 
0381         # Prevent the neighbour table from overflowing, as different neighbour
0382         # entries will be created on $ol4 when using different destination IPs.
0383         sysctl_set net.ipv4.neigh.default.gc_thresh1 1024
0384         sysctl_set net.ipv4.neigh.default.gc_thresh2 1024
0385         sysctl_set net.ipv4.neigh.default.gc_thresh3 1024
0386 
0387         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0040
0388         custom_hash_test "Inner source IP" "balanced" send_src_ipv4
0389         custom_hash_test "Inner source IP" "unbalanced" send_dst_ipv4
0390 
0391         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0080
0392         custom_hash_test "Inner destination IP" "balanced" send_dst_ipv4
0393         custom_hash_test "Inner destination IP" "unbalanced" send_src_ipv4
0394 
0395         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0400
0396         custom_hash_test "Inner source port" "balanced" send_src_udp4
0397         custom_hash_test "Inner source port" "unbalanced" send_dst_udp4
0398 
0399         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0800
0400         custom_hash_test "Inner destination port" "balanced" send_dst_udp4
0401         custom_hash_test "Inner destination port" "unbalanced" send_src_udp4
0402 
0403         sysctl_restore net.ipv4.neigh.default.gc_thresh3
0404         sysctl_restore net.ipv4.neigh.default.gc_thresh2
0405         sysctl_restore net.ipv4.neigh.default.gc_thresh1
0406 }
0407 
0408 custom_hash_v6()
0409 {
0410         log_info "Running IPv6 overlay custom multipath hash tests"
0411 
0412         # Prevent the neighbour table from overflowing, as different neighbour
0413         # entries will be created on $ol4 when using different destination IPs.
0414         sysctl_set net.ipv6.neigh.default.gc_thresh1 1024
0415         sysctl_set net.ipv6.neigh.default.gc_thresh2 1024
0416         sysctl_set net.ipv6.neigh.default.gc_thresh3 1024
0417 
0418         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0040
0419         custom_hash_test "Inner source IP" "balanced" send_src_ipv6
0420         custom_hash_test "Inner source IP" "unbalanced" send_dst_ipv6
0421 
0422         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0080
0423         custom_hash_test "Inner destination IP" "balanced" send_dst_ipv6
0424         custom_hash_test "Inner destination IP" "unbalanced" send_src_ipv6
0425 
0426         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0200
0427         custom_hash_test "Inner flowlabel" "balanced" send_flowlabel
0428         custom_hash_test "Inner flowlabel" "unbalanced" send_src_ipv6
0429 
0430         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0400
0431         custom_hash_test "Inner source port" "balanced" send_src_udp6
0432         custom_hash_test "Inner source port" "unbalanced" send_dst_udp6
0433 
0434         sysctl_set net.ipv6.fib_multipath_hash_fields 0x0800
0435         custom_hash_test "Inner destination port" "balanced" send_dst_udp6
0436         custom_hash_test "Inner destination port" "unbalanced" send_src_udp6
0437 
0438         sysctl_restore net.ipv6.neigh.default.gc_thresh3
0439         sysctl_restore net.ipv6.neigh.default.gc_thresh2
0440         sysctl_restore net.ipv6.neigh.default.gc_thresh1
0441 }
0442 
0443 custom_hash()
0444 {
0445         # Test that when the hash policy is set to custom, traffic is
0446         # distributed only according to the fields set in the
0447         # fib_multipath_hash_fields sysctl.
0448         #
0449         # Each time set a different field and make sure traffic is only
0450         # distributed when the field is changed in the packet stream.
0451 
0452         sysctl_set net.ipv6.fib_multipath_hash_policy 3
0453 
0454         custom_hash_v4
0455         custom_hash_v6
0456 
0457         sysctl_restore net.ipv6.fib_multipath_hash_policy
0458 }
0459 
0460 trap cleanup EXIT
0461 
0462 setup_prepare
0463 setup_wait
0464 tests_run
0465 
0466 exit $EXIT_STATUS