ip6gre_custom_multipath_hash.sh (12870B)
1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test traffic distribution when there are multiple paths between an IPv6 GRE 5# tunnel. The tunnel carries IPv4 and IPv6 traffic between multiple hosts. 6# Multiple routes are in the underlay network. With the default multipath 7# policy, SW2 will only look at the outer IP addresses, hence only a single 8# route would be used. 9# 10# +--------------------------------+ 11# | H1 | 12# | $h1 + | 13# | 198.51.100.{2-253}/24 | | 14# | 2001:db8:1::{2-fd}/64 | | 15# +-------------------------|------+ 16# | 17# +-------------------------|-------------------+ 18# | SW1 | | 19# | $ol1 + | 20# | 198.51.100.1/24 | 21# | 2001:db8:1::1/64 | 22# | | 23# |+ g1 (ip6gre) | 24# | loc=2001:db8:3::1 | 25# | rem=2001:db8:3::2 -. | 26# | tos=inherit | | 27# | v | 28# | + $ul1 | 29# | | 2001:db8:10::1/64 | 30# +---------------------|-----------------------+ 31# | 32# +---------------------|-----------------------+ 33# | SW2 | | 34# | $ul21 + | 35# | 2001:db8:10::2/64 | | 36# | | | 37# ! __________________+___ | 38# | / \ | 39# | | | | 40# | + $ul22.111 (vlan) + $ul22.222 (vlan) | 41# | | 2001:db8:11::1/64 | 2001:db8:12::1/64 | 42# | | | | 43# +--|----------------------|-------------------+ 44# | | 45# +--|----------------------|-------------------+ 46# | | | | 47# | + $ul32.111 (vlan) + $ul32.222 (vlan) | 48# | | 2001:db8:11::2/64 | 2001:db8:12::2/64 | 49# | | | | 50# | \__________________+___/ | 51# | | | 52# | | | 53# | $ul31 + | 54# | 2001:db8:13::1/64 | SW3 | 55# +---------------------|-----------------------+ 56# | 57# +---------------------|-----------------------+ 58# | + $ul4 | 59# | ^ 2001:db8:13::2/64 | 60# | | | 61# |+ g2 (ip6gre) | | 62# | loc=2001:db8:3::2 | | 63# | rem=2001:db8:3::1 -' | 64# | tos=inherit | 65# | | 66# | $ol4 + | 67# | 203.0.113.1/24 | | 68# | 2001:db8:2::1/64 | SW4 | 69# +-------------------------|-------------------+ 70# | 71# +-------------------------|------+ 72# | | | 73# | $h2 + | 74# | 203.0.113.{2-253}/24 | 75# | 2001:db8:2::{2-fd}/64 H2 | 76# +--------------------------------+ 77 78ALL_TESTS=" 79 ping_ipv4 80 ping_ipv6 81 custom_hash 82" 83 84NUM_NETIFS=10 85source lib.sh 86 87h1_create() 88{ 89 simple_if_init $h1 198.51.100.2/24 2001:db8:1::2/64 90 ip route add vrf v$h1 default via 198.51.100.1 dev $h1 91 ip -6 route add vrf v$h1 default via 2001:db8:1::1 dev $h1 92} 93 94h1_destroy() 95{ 96 ip -6 route del vrf v$h1 default 97 ip route del vrf v$h1 default 98 simple_if_fini $h1 198.51.100.2/24 2001:db8:1::2/64 99} 100 101sw1_create() 102{ 103 simple_if_init $ol1 198.51.100.1/24 2001:db8:1::1/64 104 __simple_if_init $ul1 v$ol1 2001:db8:10::1/64 105 106 tunnel_create g1 ip6gre 2001:db8:3::1 2001:db8:3::2 tos inherit \ 107 dev v$ol1 108 __simple_if_init g1 v$ol1 2001:db8:3::1/128 109 ip route add vrf v$ol1 2001:db8:3::2/128 via 2001:db8:10::2 110 111 ip route add vrf v$ol1 203.0.113.0/24 dev g1 112 ip -6 route add vrf v$ol1 2001:db8:2::/64 dev g1 113} 114 115sw1_destroy() 116{ 117 ip -6 route del vrf v$ol1 2001:db8:2::/64 118 ip route del vrf v$ol1 203.0.113.0/24 119 120 ip route del vrf v$ol1 2001:db8:3::2/128 121 __simple_if_fini g1 2001:db8:3::1/128 122 tunnel_destroy g1 123 124 __simple_if_fini $ul1 2001:db8:10::1/64 125 simple_if_fini $ol1 198.51.100.1/24 2001:db8:1::1/64 126} 127 128sw2_create() 129{ 130 simple_if_init $ul21 2001:db8:10::2/64 131 __simple_if_init $ul22 v$ul21 132 vlan_create $ul22 111 v$ul21 2001:db8:11::1/64 133 vlan_create $ul22 222 v$ul21 2001:db8:12::1/64 134 135 ip -6 route add vrf v$ul21 2001:db8:3::1/128 via 2001:db8:10::1 136 ip -6 route add vrf v$ul21 2001:db8:3::2/128 \ 137 nexthop via 2001:db8:11::2 \ 138 nexthop via 2001:db8:12::2 139} 140 141sw2_destroy() 142{ 143 ip -6 route del vrf v$ul21 2001:db8:3::2/128 144 ip -6 route del vrf v$ul21 2001:db8:3::1/128 145 146 vlan_destroy $ul22 222 147 vlan_destroy $ul22 111 148 __simple_if_fini $ul22 149 simple_if_fini $ul21 2001:db8:10::2/64 150} 151 152sw3_create() 153{ 154 simple_if_init $ul31 2001:db8:13::1/64 155 __simple_if_init $ul32 v$ul31 156 vlan_create $ul32 111 v$ul31 2001:db8:11::2/64 157 vlan_create $ul32 222 v$ul31 2001:db8:12::2/64 158 159 ip -6 route add vrf v$ul31 2001:db8:3::2/128 via 2001:db8:13::2 160 ip -6 route add vrf v$ul31 2001:db8:3::1/128 \ 161 nexthop via 2001:db8:11::1 \ 162 nexthop via 2001:db8:12::1 163 164 tc qdisc add dev $ul32 clsact 165 tc filter add dev $ul32 ingress pref 111 prot 802.1Q \ 166 flower vlan_id 111 action pass 167 tc filter add dev $ul32 ingress pref 222 prot 802.1Q \ 168 flower vlan_id 222 action pass 169} 170 171sw3_destroy() 172{ 173 tc qdisc del dev $ul32 clsact 174 175 ip -6 route del vrf v$ul31 2001:db8:3::1/128 176 ip -6 route del vrf v$ul31 2001:db8:3::2/128 177 178 vlan_destroy $ul32 222 179 vlan_destroy $ul32 111 180 __simple_if_fini $ul32 181 simple_if_fini $ul31 2001:db8:13::1/64 182} 183 184sw4_create() 185{ 186 simple_if_init $ol4 203.0.113.1/24 2001:db8:2::1/64 187 __simple_if_init $ul4 v$ol4 2001:db8:13::2/64 188 189 tunnel_create g2 ip6gre 2001:db8:3::2 2001:db8:3::1 tos inherit \ 190 dev v$ol4 191 __simple_if_init g2 v$ol4 2001:db8:3::2/128 192 ip -6 route add vrf v$ol4 2001:db8:3::1/128 via 2001:db8:13::1 193 194 ip route add vrf v$ol4 198.51.100.0/24 dev g2 195 ip -6 route add vrf v$ol4 2001:db8:1::/64 dev g2 196} 197 198sw4_destroy() 199{ 200 ip -6 route del vrf v$ol4 2001:db8:1::/64 201 ip route del vrf v$ol4 198.51.100.0/24 202 203 ip -6 route del vrf v$ol4 2001:db8:3::1/128 204 __simple_if_fini g2 2001:db8:3::2/128 205 tunnel_destroy g2 206 207 __simple_if_fini $ul4 2001:db8:13::2/64 208 simple_if_fini $ol4 203.0.113.1/24 2001:db8:2::1/64 209} 210 211h2_create() 212{ 213 simple_if_init $h2 203.0.113.2/24 2001:db8:2::2/64 214 ip route add vrf v$h2 default via 203.0.113.1 dev $h2 215 ip -6 route add vrf v$h2 default via 2001:db8:2::1 dev $h2 216} 217 218h2_destroy() 219{ 220 ip -6 route del vrf v$h2 default 221 ip route del vrf v$h2 default 222 simple_if_fini $h2 203.0.113.2/24 2001:db8:2::2/64 223} 224 225setup_prepare() 226{ 227 h1=${NETIFS[p1]} 228 229 ol1=${NETIFS[p2]} 230 ul1=${NETIFS[p3]} 231 232 ul21=${NETIFS[p4]} 233 ul22=${NETIFS[p5]} 234 235 ul32=${NETIFS[p6]} 236 ul31=${NETIFS[p7]} 237 238 ul4=${NETIFS[p8]} 239 ol4=${NETIFS[p9]} 240 241 h2=${NETIFS[p10]} 242 243 vrf_prepare 244 h1_create 245 sw1_create 246 sw2_create 247 sw3_create 248 sw4_create 249 h2_create 250 251 forwarding_enable 252} 253 254cleanup() 255{ 256 pre_cleanup 257 258 forwarding_restore 259 260 h2_destroy 261 sw4_destroy 262 sw3_destroy 263 sw2_destroy 264 sw1_destroy 265 h1_destroy 266 vrf_cleanup 267} 268 269ping_ipv4() 270{ 271 ping_test $h1 203.0.113.2 272} 273 274ping_ipv6() 275{ 276 ping6_test $h1 2001:db8:2::2 277} 278 279send_src_ipv4() 280{ 281 $MZ $h1 -q -p 64 -A "198.51.100.2-198.51.100.253" -B 203.0.113.2 \ 282 -d 1msec -c 50 -t udp "sp=20000,dp=30000" 283} 284 285send_dst_ipv4() 286{ 287 $MZ $h1 -q -p 64 -A 198.51.100.2 -B "203.0.113.2-203.0.113.253" \ 288 -d 1msec -c 50 -t udp "sp=20000,dp=30000" 289} 290 291send_src_udp4() 292{ 293 $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ 294 -d 1msec -t udp "sp=0-32768,dp=30000" 295} 296 297send_dst_udp4() 298{ 299 $MZ $h1 -q -p 64 -A 198.51.100.2 -B 203.0.113.2 \ 300 -d 1msec -t udp "sp=20000,dp=0-32768" 301} 302 303send_src_ipv6() 304{ 305 $MZ -6 $h1 -q -p 64 -A "2001:db8:1::2-2001:db8:1::fd" -B 2001:db8:2::2 \ 306 -d 1msec -c 50 -t udp "sp=20000,dp=30000" 307} 308 309send_dst_ipv6() 310{ 311 $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B "2001:db8:2::2-2001:db8:2::fd" \ 312 -d 1msec -c 50 -t udp "sp=20000,dp=30000" 313} 314 315send_flowlabel() 316{ 317 # Generate 16384 echo requests, each with a random flow label. 318 for _ in $(seq 1 16384); do 319 ip vrf exec v$h1 \ 320 $PING6 2001:db8:2::2 -F 0 -c 1 -q >/dev/null 2>&1 321 done 322} 323 324send_src_udp6() 325{ 326 $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ 327 -d 1msec -t udp "sp=0-32768,dp=30000" 328} 329 330send_dst_udp6() 331{ 332 $MZ -6 $h1 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ 333 -d 1msec -t udp "sp=20000,dp=0-32768" 334} 335 336custom_hash_test() 337{ 338 local field="$1"; shift 339 local balanced="$1"; shift 340 local send_flows="$@" 341 342 RET=0 343 344 local t0_111=$(tc_rule_stats_get $ul32 111 ingress) 345 local t0_222=$(tc_rule_stats_get $ul32 222 ingress) 346 347 $send_flows 348 349 local t1_111=$(tc_rule_stats_get $ul32 111 ingress) 350 local t1_222=$(tc_rule_stats_get $ul32 222 ingress) 351 352 local d111=$((t1_111 - t0_111)) 353 local d222=$((t1_222 - t0_222)) 354 355 local diff=$((d222 - d111)) 356 local sum=$((d111 + d222)) 357 358 local pct=$(echo "$diff / $sum * 100" | bc -l) 359 local is_balanced=$(echo "-20 <= $pct && $pct <= 20" | bc) 360 361 [[ ( $is_balanced -eq 1 && $balanced == "balanced" ) || 362 ( $is_balanced -eq 0 && $balanced == "unbalanced" ) ]] 363 check_err $? "Expected traffic to be $balanced, but it is not" 364 365 log_test "Multipath hash field: $field ($balanced)" 366 log_info "Packets sent on path1 / path2: $d111 / $d222" 367} 368 369custom_hash_v4() 370{ 371 log_info "Running IPv4 overlay custom multipath hash tests" 372 373 # Prevent the neighbour table from overflowing, as different neighbour 374 # entries will be created on $ol4 when using different destination IPs. 375 sysctl_set net.ipv4.neigh.default.gc_thresh1 1024 376 sysctl_set net.ipv4.neigh.default.gc_thresh2 1024 377 sysctl_set net.ipv4.neigh.default.gc_thresh3 1024 378 379 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0040 380 custom_hash_test "Inner source IP" "balanced" send_src_ipv4 381 custom_hash_test "Inner source IP" "unbalanced" send_dst_ipv4 382 383 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0080 384 custom_hash_test "Inner destination IP" "balanced" send_dst_ipv4 385 custom_hash_test "Inner destination IP" "unbalanced" send_src_ipv4 386 387 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0400 388 custom_hash_test "Inner source port" "balanced" send_src_udp4 389 custom_hash_test "Inner source port" "unbalanced" send_dst_udp4 390 391 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0800 392 custom_hash_test "Inner destination port" "balanced" send_dst_udp4 393 custom_hash_test "Inner destination port" "unbalanced" send_src_udp4 394 395 sysctl_restore net.ipv4.neigh.default.gc_thresh3 396 sysctl_restore net.ipv4.neigh.default.gc_thresh2 397 sysctl_restore net.ipv4.neigh.default.gc_thresh1 398} 399 400custom_hash_v6() 401{ 402 log_info "Running IPv6 overlay custom multipath hash tests" 403 404 # Prevent the neighbour table from overflowing, as different neighbour 405 # entries will be created on $ol4 when using different destination IPs. 406 sysctl_set net.ipv6.neigh.default.gc_thresh1 1024 407 sysctl_set net.ipv6.neigh.default.gc_thresh2 1024 408 sysctl_set net.ipv6.neigh.default.gc_thresh3 1024 409 410 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0040 411 custom_hash_test "Inner source IP" "balanced" send_src_ipv6 412 custom_hash_test "Inner source IP" "unbalanced" send_dst_ipv6 413 414 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0080 415 custom_hash_test "Inner destination IP" "balanced" send_dst_ipv6 416 custom_hash_test "Inner destination IP" "unbalanced" send_src_ipv6 417 418 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0200 419 custom_hash_test "Inner flowlabel" "balanced" send_flowlabel 420 custom_hash_test "Inner flowlabel" "unbalanced" send_src_ipv6 421 422 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0400 423 custom_hash_test "Inner source port" "balanced" send_src_udp6 424 custom_hash_test "Inner source port" "unbalanced" send_dst_udp6 425 426 sysctl_set net.ipv6.fib_multipath_hash_fields 0x0800 427 custom_hash_test "Inner destination port" "balanced" send_dst_udp6 428 custom_hash_test "Inner destination port" "unbalanced" send_src_udp6 429 430 sysctl_restore net.ipv6.neigh.default.gc_thresh3 431 sysctl_restore net.ipv6.neigh.default.gc_thresh2 432 sysctl_restore net.ipv6.neigh.default.gc_thresh1 433} 434 435custom_hash() 436{ 437 # Test that when the hash policy is set to custom, traffic is 438 # distributed only according to the fields set in the 439 # fib_multipath_hash_fields sysctl. 440 # 441 # Each time set a different field and make sure traffic is only 442 # distributed when the field is changed in the packet stream. 443 444 sysctl_set net.ipv6.fib_multipath_hash_policy 3 445 446 custom_hash_v4 447 custom_hash_v6 448 449 sysctl_restore net.ipv6.fib_multipath_hash_policy 450} 451 452trap cleanup EXIT 453 454setup_prepare 455setup_wait 456tests_run 457 458exit $EXIT_STATUS