1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# Test traffic distribution when a wECMP route forwards traffic to two GRE 5# tunnels. 6# 7# +-------------------------+ 8# | H1 | 9# | $h1 + | 10# | 192.0.2.1/28 | | 11# | 2001:db8:1::1/64 | | 12# +-------------------|-----+ 13# | 14# +-------------------|------------------------+ 15# | SW1 | | 16# | $ol1 + | 17# | 192.0.2.2/28 | 18# | 2001:db8:1::2/64 | 19# | | 20# | + g1a (gre) + g1b (gre) | 21# | loc=192.0.2.65 loc=192.0.2.81 | 22# | rem=192.0.2.66 --. rem=192.0.2.82 --. | 23# | tos=inherit | tos=inherit | | 24# | .------------------' | | 25# | | .------------------' | 26# | v v | 27# | + $ul1.111 (vlan) + $ul1.222 (vlan) | 28# | | 192.0.2.129/28 | 192.0.2.145/28 | 29# | \ / | 30# | \________________/ | 31# | | | 32# | + $ul1 | 33# +------------|-------------------------------+ 34# | 35# +------------|-------------------------------+ 36# | SW2 + $ul2 | 37# | _______|________ | 38# | / \ | 39# | / \ | 40# | + $ul2.111 (vlan) + $ul2.222 (vlan) | 41# | ^ 192.0.2.130/28 ^ 192.0.2.146/28 | 42# | | | | 43# | | '------------------. | 44# | '------------------. | | 45# | + g2a (gre) | + g2b (gre) | | 46# | loc=192.0.2.66 | loc=192.0.2.82 | | 47# | rem=192.0.2.65 --' rem=192.0.2.81 --' | 48# | tos=inherit tos=inherit | 49# | | 50# | $ol2 + | 51# | 192.0.2.17/28 | | 52# | 2001:db8:2::1/64 | | 53# +-------------------|------------------------+ 54# | 55# +-------------------|-----+ 56# | H2 | | 57# | $h2 + | 58# | 192.0.2.18/28 | 59# | 2001:db8:2::2/64 | 60# +-------------------------+ 61 62ALL_TESTS=" 63 ping_ipv4 64 ping_ipv6 65 multipath_ipv4 66 multipath_ipv6 67 multipath_ipv6_l4 68" 69 70NUM_NETIFS=6 71source lib.sh 72 73h1_create() 74{ 75 simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64 76 ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2 77 ip route add vrf v$h1 2001:db8:2::/64 via 2001:db8:1::2 78} 79 80h1_destroy() 81{ 82 ip route del vrf v$h1 2001:db8:2::/64 via 2001:db8:1::2 83 ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2 84 simple_if_fini $h1 192.0.2.1/28 85} 86 87sw1_create() 88{ 89 simple_if_init $ol1 192.0.2.2/28 2001:db8:1::2/64 90 __simple_if_init $ul1 v$ol1 91 vlan_create $ul1 111 v$ol1 192.0.2.129/28 92 vlan_create $ul1 222 v$ol1 192.0.2.145/28 93 94 tunnel_create g1a gre 192.0.2.65 192.0.2.66 tos inherit dev v$ol1 95 __simple_if_init g1a v$ol1 192.0.2.65/32 96 ip route add vrf v$ol1 192.0.2.66/32 via 192.0.2.130 97 98 tunnel_create g1b gre 192.0.2.81 192.0.2.82 tos inherit dev v$ol1 99 __simple_if_init g1b v$ol1 192.0.2.81/32 100 ip route add vrf v$ol1 192.0.2.82/32 via 192.0.2.146 101 102 ip route add vrf v$ol1 192.0.2.16/28 \ 103 nexthop dev g1a \ 104 nexthop dev g1b 105 ip route add vrf v$ol1 2001:db8:2::/64 \ 106 nexthop dev g1a \ 107 nexthop dev g1b 108 109 tc qdisc add dev $ul1 clsact 110 tc filter add dev $ul1 egress pref 111 prot 802.1q \ 111 flower vlan_id 111 action pass 112 tc filter add dev $ul1 egress pref 222 prot 802.1q \ 113 flower vlan_id 222 action pass 114} 115 116sw1_destroy() 117{ 118 tc qdisc del dev $ul1 clsact 119 120 ip route del vrf v$ol1 2001:db8:2::/64 121 ip route del vrf v$ol1 192.0.2.16/28 122 123 ip route del vrf v$ol1 192.0.2.82/32 via 192.0.2.146 124 __simple_if_fini g1b 192.0.2.81/32 125 tunnel_destroy g1b 126 127 ip route del vrf v$ol1 192.0.2.66/32 via 192.0.2.130 128 __simple_if_fini g1a 192.0.2.65/32 129 tunnel_destroy g1a 130 131 vlan_destroy $ul1 222 132 vlan_destroy $ul1 111 133 __simple_if_fini $ul1 134 simple_if_fini $ol1 192.0.2.2/28 2001:db8:1::2/64 135} 136 137sw2_create() 138{ 139 simple_if_init $ol2 192.0.2.17/28 2001:db8:2::1/64 140 __simple_if_init $ul2 v$ol2 141 vlan_create $ul2 111 v$ol2 192.0.2.130/28 142 vlan_create $ul2 222 v$ol2 192.0.2.146/28 143 144 tunnel_create g2a gre 192.0.2.66 192.0.2.65 tos inherit dev v$ol2 145 __simple_if_init g2a v$ol2 192.0.2.66/32 146 ip route add vrf v$ol2 192.0.2.65/32 via 192.0.2.129 147 148 tunnel_create g2b gre 192.0.2.82 192.0.2.81 tos inherit dev v$ol2 149 __simple_if_init g2b v$ol2 192.0.2.82/32 150 ip route add vrf v$ol2 192.0.2.81/32 via 192.0.2.145 151 152 ip route add vrf v$ol2 192.0.2.0/28 \ 153 nexthop dev g2a \ 154 nexthop dev g2b 155 ip route add vrf v$ol2 2001:db8:1::/64 \ 156 nexthop dev g2a \ 157 nexthop dev g2b 158} 159 160sw2_destroy() 161{ 162 ip route del vrf v$ol2 2001:db8:1::/64 163 ip route del vrf v$ol2 192.0.2.0/28 164 165 ip route del vrf v$ol2 192.0.2.81/32 via 192.0.2.145 166 __simple_if_fini g2b 192.0.2.82/32 167 tunnel_destroy g2b 168 169 ip route del vrf v$ol2 192.0.2.65/32 via 192.0.2.129 170 __simple_if_fini g2a 192.0.2.66/32 171 tunnel_destroy g2a 172 173 vlan_destroy $ul2 222 174 vlan_destroy $ul2 111 175 __simple_if_fini $ul2 176 simple_if_fini $ol2 192.0.2.17/28 2001:db8:2::1/64 177} 178 179h2_create() 180{ 181 simple_if_init $h2 192.0.2.18/28 2001:db8:2::2/64 182 ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17 183 ip route add vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1 184} 185 186h2_destroy() 187{ 188 ip route del vrf v$h2 2001:db8:1::/64 via 2001:db8:2::1 189 ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17 190 simple_if_fini $h2 192.0.2.18/28 2001:db8:2::2/64 191} 192 193setup_prepare() 194{ 195 h1=${NETIFS[p1]} 196 ol1=${NETIFS[p2]} 197 198 ul1=${NETIFS[p3]} 199 ul2=${NETIFS[p4]} 200 201 ol2=${NETIFS[p5]} 202 h2=${NETIFS[p6]} 203 204 vrf_prepare 205 h1_create 206 sw1_create 207 sw2_create 208 h2_create 209} 210 211cleanup() 212{ 213 pre_cleanup 214 215 h2_destroy 216 sw2_destroy 217 sw1_destroy 218 h1_destroy 219 vrf_cleanup 220} 221 222multipath4_test() 223{ 224 local what=$1; shift 225 local weight1=$1; shift 226 local weight2=$1; shift 227 228 sysctl_set net.ipv4.fib_multipath_hash_policy 1 229 ip route replace vrf v$ol1 192.0.2.16/28 \ 230 nexthop dev g1a weight $weight1 \ 231 nexthop dev g1b weight $weight2 232 233 local t0_111=$(tc_rule_stats_get $ul1 111 egress) 234 local t0_222=$(tc_rule_stats_get $ul1 222 egress) 235 236 ip vrf exec v$h1 \ 237 $MZ $h1 -q -p 64 -A 192.0.2.1 -B 192.0.2.18 \ 238 -d 1msec -t udp "sp=1024,dp=0-32768" 239 240 local t1_111=$(tc_rule_stats_get $ul1 111 egress) 241 local t1_222=$(tc_rule_stats_get $ul1 222 egress) 242 243 local d111=$((t1_111 - t0_111)) 244 local d222=$((t1_222 - t0_222)) 245 multipath_eval "$what" $weight1 $weight2 $d111 $d222 246 247 ip route replace vrf v$ol1 192.0.2.16/28 \ 248 nexthop dev g1a \ 249 nexthop dev g1b 250 sysctl_restore net.ipv4.fib_multipath_hash_policy 251} 252 253multipath6_l4_test() 254{ 255 local what=$1; shift 256 local weight1=$1; shift 257 local weight2=$1; shift 258 259 sysctl_set net.ipv6.fib_multipath_hash_policy 1 260 ip route replace vrf v$ol1 2001:db8:2::/64 \ 261 nexthop dev g1a weight $weight1 \ 262 nexthop dev g1b weight $weight2 263 264 local t0_111=$(tc_rule_stats_get $ul1 111 egress) 265 local t0_222=$(tc_rule_stats_get $ul1 222 egress) 266 267 ip vrf exec v$h1 \ 268 $MZ $h1 -6 -q -p 64 -A 2001:db8:1::1 -B 2001:db8:2::2 \ 269 -d 1msec -t udp "sp=1024,dp=0-32768" 270 271 local t1_111=$(tc_rule_stats_get $ul1 111 egress) 272 local t1_222=$(tc_rule_stats_get $ul1 222 egress) 273 274 local d111=$((t1_111 - t0_111)) 275 local d222=$((t1_222 - t0_222)) 276 multipath_eval "$what" $weight1 $weight2 $d111 $d222 277 278 ip route replace vrf v$ol1 2001:db8:2::/64 \ 279 nexthop dev g1a \ 280 nexthop dev g1b 281 sysctl_restore net.ipv6.fib_multipath_hash_policy 282} 283 284multipath6_test() 285{ 286 local what=$1; shift 287 local weight1=$1; shift 288 local weight2=$1; shift 289 290 ip route replace vrf v$ol1 2001:db8:2::/64 \ 291 nexthop dev g1a weight $weight1 \ 292 nexthop dev g1b weight $weight2 293 294 local t0_111=$(tc_rule_stats_get $ul1 111 egress) 295 local t0_222=$(tc_rule_stats_get $ul1 222 egress) 296 297 # Generate 16384 echo requests, each with a random flow label. 298 for ((i=0; i < 16384; ++i)); do 299 ip vrf exec v$h1 $PING6 2001:db8:2::2 -F 0 -c 1 -q &> /dev/null 300 done 301 302 local t1_111=$(tc_rule_stats_get $ul1 111 egress) 303 local t1_222=$(tc_rule_stats_get $ul1 222 egress) 304 305 local d111=$((t1_111 - t0_111)) 306 local d222=$((t1_222 - t0_222)) 307 multipath_eval "$what" $weight1 $weight2 $d111 $d222 308 309 ip route replace vrf v$ol1 2001:db8:2::/64 \ 310 nexthop dev g1a \ 311 nexthop dev g1b 312} 313 314ping_ipv4() 315{ 316 ping_test $h1 192.0.2.18 317} 318 319ping_ipv6() 320{ 321 ping6_test $h1 2001:db8:2::2 322} 323 324multipath_ipv4() 325{ 326 log_info "Running IPv4 multipath tests" 327 multipath4_test "ECMP" 1 1 328 multipath4_test "Weighted MP 2:1" 2 1 329 multipath4_test "Weighted MP 11:45" 11 45 330} 331 332multipath_ipv6() 333{ 334 log_info "Running IPv6 multipath tests" 335 multipath6_test "ECMP" 1 1 336 multipath6_test "Weighted MP 2:1" 2 1 337 multipath6_test "Weighted MP 11:45" 11 45 338} 339 340multipath_ipv6_l4() 341{ 342 log_info "Running IPv6 L4 hash multipath tests" 343 multipath6_l4_test "ECMP" 1 1 344 multipath6_l4_test "Weighted MP 2:1" 2 1 345 multipath6_l4_test "Weighted MP 11:45" 11 45 346} 347 348trap cleanup EXIT 349 350setup_prepare 351setup_wait 352tests_run 353 354exit $EXIT_STATUS 355