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 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
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
0382
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
0413
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
0446
0447
0448
0449
0450
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