0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
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
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
0380
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
0411
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
0444
0445
0446
0447
0448
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