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 ALL_TESTS="
0046 ping_ipv4
0047 ping_ipv6
0048 custom_hash
0049 "
0050
0051 NUM_NETIFS=8
0052 source lib.sh
0053
0054 h1_create()
0055 {
0056 simple_if_init $h1 198.51.100.2/24 2001:db8:1::2/64
0057 ip route add vrf v$h1 default via 198.51.100.1 dev $h1
0058 ip -6 route add vrf v$h1 default via 2001:db8:1::1 dev $h1
0059 }
0060
0061 h1_destroy()
0062 {
0063 ip -6 route del vrf v$h1 default
0064 ip route del vrf v$h1 default
0065 simple_if_fini $h1 198.51.100.2/24 2001:db8:1::2/64
0066 }
0067
0068 sw1_create()
0069 {
0070 simple_if_init $rp1 198.51.100.1/24 2001:db8:1::1/64
0071 __simple_if_init $rp11 v$rp1 192.0.2.1/28 2001:db8:2::1/64
0072 __simple_if_init $rp12 v$rp1 192.0.2.17/28 2001:db8:3::1/64
0073
0074 ip route add vrf v$rp1 203.0.113.0/24 \
0075 nexthop via 192.0.2.2 dev $rp11 \
0076 nexthop via 192.0.2.18 dev $rp12
0077
0078 ip -6 route add vrf v$rp1 2001:db8:4::/64 \
0079 nexthop via 2001:db8:2::2 dev $rp11 \
0080 nexthop via 2001:db8:3::2 dev $rp12
0081 }
0082
0083 sw1_destroy()
0084 {
0085 ip -6 route del vrf v$rp1 2001:db8:4::/64
0086
0087 ip route del vrf v$rp1 203.0.113.0/24
0088
0089 __simple_if_fini $rp12 192.0.2.17/28 2001:db8:3::1/64
0090 __simple_if_fini $rp11 192.0.2.1/28 2001:db8:2::1/64
0091 simple_if_fini $rp1 198.51.100.1/24 2001:db8:1::1/64
0092 }
0093
0094 sw2_create()
0095 {
0096 simple_if_init $rp2 203.0.113.1/24 2001:db8:4::1/64
0097 __simple_if_init $rp21 v$rp2 192.0.2.2/28 2001:db8:2::2/64
0098 __simple_if_init $rp22 v$rp2 192.0.2.18/28 2001:db8:3::2/64
0099
0100 ip route add vrf v$rp2 198.51.100.0/24 \
0101 nexthop via 192.0.2.1 dev $rp21 \
0102 nexthop via 192.0.2.17 dev $rp22
0103
0104 ip -6 route add vrf v$rp2 2001:db8:1::/64 \
0105 nexthop via 2001:db8:2::1 dev $rp21 \
0106 nexthop via 2001:db8:3::1 dev $rp22
0107 }
0108
0109 sw2_destroy()
0110 {
0111 ip -6 route del vrf v$rp2 2001:db8:1::/64
0112
0113 ip route del vrf v$rp2 198.51.100.0/24
0114
0115 __simple_if_fini $rp22 192.0.2.18/28 2001:db8:3::2/64
0116 __simple_if_fini $rp21 192.0.2.2/28 2001:db8:2::2/64
0117 simple_if_fini $rp2 203.0.113.1/24 2001:db8:4::1/64
0118 }
0119
0120 h2_create()
0121 {
0122 simple_if_init $h2 203.0.113.2/24 2001:db8:4::2/64
0123 ip route add vrf v$h2 default via 203.0.113.1 dev $h2
0124 ip -6 route add vrf v$h2 default via 2001:db8:4::1 dev $h2
0125 }
0126
0127 h2_destroy()
0128 {
0129 ip -6 route del vrf v$h2 default
0130 ip route del vrf v$h2 default
0131 simple_if_fini $h2 203.0.113.2/24 2001:db8:4::2/64
0132 }
0133
0134 setup_prepare()
0135 {
0136 h1=${NETIFS[p1]}
0137
0138 rp1=${NETIFS[p2]}
0139
0140 rp11=${NETIFS[p3]}
0141 rp21=${NETIFS[p4]}
0142
0143 rp12=${NETIFS[p5]}
0144 rp22=${NETIFS[p6]}
0145
0146 rp2=${NETIFS[p7]}
0147
0148 h2=${NETIFS[p8]}
0149
0150 vrf_prepare
0151 h1_create
0152 sw1_create
0153 sw2_create
0154 h2_create
0155
0156 forwarding_enable
0157 }
0158
0159 cleanup()
0160 {
0161 pre_cleanup
0162
0163 forwarding_restore
0164
0165 h2_destroy
0166 sw2_destroy
0167 sw1_destroy
0168 h1_destroy
0169 vrf_cleanup
0170 }
0171
0172 ping_ipv4()
0173 {
0174 ping_test $h1 203.0.113.2
0175 }
0176
0177 ping_ipv6()
0178 {
0179 ping6_test $h1 2001:db8:4::2
0180 }
0181
0182 send_src_ipv4()
0183 {
0184 ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0185 -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \
0186 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0187 }
0188
0189 send_dst_ipv4()
0190 {
0191 ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0192 -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \
0193 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0194 }
0195
0196 send_src_udp4()
0197 {
0198 ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0199 -A 198.51.100.2 -B 203.0.113.2 \
0200 -d 1msec -t udp "sp=0-32768,dp=30000"
0201 }
0202
0203 send_dst_udp4()
0204 {
0205 ip vrf exec v$h1 $MZ $h1 -q -p 64 \
0206 -A 198.51.100.2 -B 203.0.113.2 \
0207 -d 1msec -t udp "sp=20000,dp=0-32768"
0208 }
0209
0210 send_src_ipv6()
0211 {
0212 ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0213 -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:4::2 \
0214 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0215 }
0216
0217 send_dst_ipv6()
0218 {
0219 ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0220 -A 2001:db8:1::2 -B "2001:db8:4::2-2001:db8:4::fd" \
0221 -d 1msec -c 50 -t udp "sp=20000,dp=30000"
0222 }
0223
0224 send_flowlabel()
0225 {
0226
0227 for _ in $(seq 1 16384); do
0228 ip vrf exec v$h1 \
0229 $PING6 2001:db8:4::2 -F 0 -c 1 -q >/dev/null 2>&1
0230 done
0231 }
0232
0233 send_src_udp6()
0234 {
0235 ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0236 -A 2001:db8:1::2 -B 2001:db8:4::2 \
0237 -d 1msec -t udp "sp=0-32768,dp=30000"
0238 }
0239
0240 send_dst_udp6()
0241 {
0242 ip vrf exec v$h1 $MZ -6 $h1 -q -p 64 \
0243 -A 2001:db8:1::2 -B 2001:db8:4::2 \
0244 -d 1msec -t udp "sp=20000,dp=0-32768"
0245 }
0246
0247 custom_hash_test()
0248 {
0249 local field="$1"; shift
0250 local balanced="$1"; shift
0251 local send_flows="$@"
0252
0253 RET=0
0254
0255 local t0_rp11=$(link_stats_tx_packets_get $rp11)
0256 local t0_rp12=$(link_stats_tx_packets_get $rp12)
0257
0258 $send_flows
0259
0260 local t1_rp11=$(link_stats_tx_packets_get $rp11)
0261 local t1_rp12=$(link_stats_tx_packets_get $rp12)
0262
0263 local d_rp11=$((t1_rp11 - t0_rp11))
0264 local d_rp12=$((t1_rp12 - t0_rp12))
0265
0266 local diff=$((d_rp12 - d_rp11))
0267 local sum=$((d_rp11 + d_rp12))
0268
0269 local pct=$(echo "$diff / $sum * 100" | bc -l)
0270 local is_balanced=$(echo "-20 <= $pct && $pct <= 20" | bc)
0271
0272 [[ ( $is_balanced -eq 1 && $balanced == "balanced" ) ||
0273 ( $is_balanced -eq 0 && $balanced == "unbalanced" ) ]]
0274 check_err $? "Expected traffic to be $balanced, but it is not"
0275
0276 log_test "Multipath hash field: $field ($balanced)"
0277 log_info "Packets sent on path1 / path2: $d_rp11 / $d_rp12"
0278 }
0279
0280 custom_hash_v4()
0281 {
0282 log_info "Running IPv4 custom multipath hash tests"
0283
0284 sysctl_set net.ipv4.fib_multipath_hash_policy 3
0285
0286
0287
0288 sysctl_set net.ipv4.neigh.default.gc_thresh1 1024
0289 sysctl_set net.ipv4.neigh.default.gc_thresh2 1024
0290 sysctl_set net.ipv4.neigh.default.gc_thresh3 1024
0291
0292 sysctl_set net.ipv4.fib_multipath_hash_fields 0x0001
0293 custom_hash_test "Source IP" "balanced" send_src_ipv4
0294 custom_hash_test "Source IP" "unbalanced" send_dst_ipv4
0295
0296 sysctl_set net.ipv4.fib_multipath_hash_fields 0x0002
0297 custom_hash_test "Destination IP" "balanced" send_dst_ipv4
0298 custom_hash_test "Destination IP" "unbalanced" send_src_ipv4
0299
0300 sysctl_set net.ipv4.fib_multipath_hash_fields 0x0010
0301 custom_hash_test "Source port" "balanced" send_src_udp4
0302 custom_hash_test "Source port" "unbalanced" send_dst_udp4
0303
0304 sysctl_set net.ipv4.fib_multipath_hash_fields 0x0020
0305 custom_hash_test "Destination port" "balanced" send_dst_udp4
0306 custom_hash_test "Destination port" "unbalanced" send_src_udp4
0307
0308 sysctl_restore net.ipv4.neigh.default.gc_thresh3
0309 sysctl_restore net.ipv4.neigh.default.gc_thresh2
0310 sysctl_restore net.ipv4.neigh.default.gc_thresh1
0311
0312 sysctl_restore net.ipv4.fib_multipath_hash_policy
0313 }
0314
0315 custom_hash_v6()
0316 {
0317 log_info "Running IPv6 custom multipath hash tests"
0318
0319 sysctl_set net.ipv6.fib_multipath_hash_policy 3
0320
0321
0322
0323 sysctl_set net.ipv6.neigh.default.gc_thresh1 1024
0324 sysctl_set net.ipv6.neigh.default.gc_thresh2 1024
0325 sysctl_set net.ipv6.neigh.default.gc_thresh3 1024
0326
0327 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0001
0328 custom_hash_test "Source IP" "balanced" send_src_ipv6
0329 custom_hash_test "Source IP" "unbalanced" send_dst_ipv6
0330
0331 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0002
0332 custom_hash_test "Destination IP" "balanced" send_dst_ipv6
0333 custom_hash_test "Destination IP" "unbalanced" send_src_ipv6
0334
0335 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0008
0336 custom_hash_test "Flowlabel" "balanced" send_flowlabel
0337 custom_hash_test "Flowlabel" "unbalanced" send_src_ipv6
0338
0339 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0010
0340 custom_hash_test "Source port" "balanced" send_src_udp6
0341 custom_hash_test "Source port" "unbalanced" send_dst_udp6
0342
0343 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0020
0344 custom_hash_test "Destination port" "balanced" send_dst_udp6
0345 custom_hash_test "Destination port" "unbalanced" send_src_udp6
0346
0347 sysctl_restore net.ipv6.neigh.default.gc_thresh3
0348 sysctl_restore net.ipv6.neigh.default.gc_thresh2
0349 sysctl_restore net.ipv6.neigh.default.gc_thresh1
0350
0351 sysctl_restore net.ipv6.fib_multipath_hash_policy
0352 }
0353
0354 custom_hash()
0355 {
0356
0357
0358
0359
0360
0361
0362 custom_hash_v4
0363 custom_hash_v6
0364 }
0365
0366 trap cleanup EXIT
0367
0368 setup_prepare
0369 setup_wait
0370 tests_run
0371
0372 exit $EXIT_STATUS