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