1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# +-------------------------+ 5# | H1 | 6# | $h1 + | 7# | 192.0.2.2/24 | | 8# | 2001:db8:1::2/64 | | 9# +-------------------|-----+ 10# | 11# +-------------------|----------------------+ 12# | | R1 | 13# | $rp11 + | 14# | 192.0.2.1/24 | 15# | 2001:db8:1::1/64 | 16# | | 17# | + $rp12 + $rp13 | 18# | | 169.254.2.12/24 | 169.254.3.13/24 | 19# | | fe80:2::12/64 | fe80:3::13/64 | 20# +--|--------------------|------------------+ 21# | | 22# +--|--------------------|------------------+ 23# | + $rp22 + $rp23 | 24# | 169.254.2.22/24 169.254.3.23/24 | 25# | fe80:2::22/64 fe80:3::23/64 | 26# | | 27# | $rp21 + | 28# | 198.51.100.1/24 | | 29# | 2001:db8:2::1/64 | R2 | 30# +-------------------|----------------------+ 31# | 32# +-------------------|-----+ 33# | | | 34# | $h2 + | 35# | 198.51.100.2/24 | 36# | 2001:db8:2::2/64 H2 | 37# +-------------------------+ 38 39ALL_TESTS=" 40 ping_ipv4 41 ping_ipv6 42 multipath_test 43 nh_stats_test_v4 44 nh_stats_test_v6 45" 46NUM_NETIFS=8 47source lib.sh 48source router_mpath_nh_lib.sh 49 50h1_create() 51{ 52 vrf_create "vrf-h1" 53 ip link set dev $h1 master vrf-h1 54 55 ip link set dev vrf-h1 up 56 ip link set dev $h1 up 57 58 ip address add 192.0.2.2/24 dev $h1 59 ip address add 2001:db8:1::2/64 dev $h1 60 61 ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1 62 ip route add 2001:db8:2::/64 vrf vrf-h1 nexthop via 2001:db8:1::1 63} 64 65h1_destroy() 66{ 67 ip route del 2001:db8:2::/64 vrf vrf-h1 68 ip route del 198.51.100.0/24 vrf vrf-h1 69 70 ip address del 2001:db8:1::2/64 dev $h1 71 ip address del 192.0.2.2/24 dev $h1 72 73 ip link set dev $h1 down 74 vrf_destroy "vrf-h1" 75} 76 77h2_create() 78{ 79 vrf_create "vrf-h2" 80 ip link set dev $h2 master vrf-h2 81 82 ip link set dev vrf-h2 up 83 ip link set dev $h2 up 84 85 ip address add 198.51.100.2/24 dev $h2 86 ip address add 2001:db8:2::2/64 dev $h2 87 88 ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1 89 ip route add 2001:db8:1::/64 vrf vrf-h2 nexthop via 2001:db8:2::1 90} 91 92h2_destroy() 93{ 94 ip route del 2001:db8:1::/64 vrf vrf-h2 95 ip route del 192.0.2.0/24 vrf vrf-h2 96 97 ip address del 2001:db8:2::2/64 dev $h2 98 ip address del 198.51.100.2/24 dev $h2 99 100 ip link set dev $h2 down 101 vrf_destroy "vrf-h2" 102} 103 104router1_create() 105{ 106 vrf_create "vrf-r1" 107 ip link set dev $rp11 master vrf-r1 108 ip link set dev $rp12 master vrf-r1 109 ip link set dev $rp13 master vrf-r1 110 111 ip link set dev vrf-r1 up 112 ip link set dev $rp11 up 113 ip link set dev $rp12 up 114 ip link set dev $rp13 up 115 116 ip address add 192.0.2.1/24 dev $rp11 117 ip address add 2001:db8:1::1/64 dev $rp11 118 119 ip address add 169.254.2.12/24 dev $rp12 120 ip address add fe80:2::12/64 dev $rp12 121 122 ip address add 169.254.3.13/24 dev $rp13 123 ip address add fe80:3::13/64 dev $rp13 124} 125 126router1_destroy() 127{ 128 ip route del 2001:db8:2::/64 vrf vrf-r1 129 ip route del 198.51.100.0/24 vrf vrf-r1 130 131 ip address del fe80:3::13/64 dev $rp13 132 ip address del 169.254.3.13/24 dev $rp13 133 134 ip address del fe80:2::12/64 dev $rp12 135 ip address del 169.254.2.12/24 dev $rp12 136 137 ip address del 2001:db8:1::1/64 dev $rp11 138 ip address del 192.0.2.1/24 dev $rp11 139 140 ip nexthop del id 103 141 ip nexthop del id 101 142 ip nexthop del id 102 143 ip nexthop del id 106 144 ip nexthop del id 104 145 ip nexthop del id 105 146 147 ip link set dev $rp13 down 148 ip link set dev $rp12 down 149 ip link set dev $rp11 down 150 151 vrf_destroy "vrf-r1" 152} 153 154router2_create() 155{ 156 vrf_create "vrf-r2" 157 ip link set dev $rp21 master vrf-r2 158 ip link set dev $rp22 master vrf-r2 159 ip link set dev $rp23 master vrf-r2 160 161 ip link set dev vrf-r2 up 162 ip link set dev $rp21 up 163 ip link set dev $rp22 up 164 ip link set dev $rp23 up 165 166 ip address add 198.51.100.1/24 dev $rp21 167 ip address add 2001:db8:2::1/64 dev $rp21 168 169 ip address add 169.254.2.22/24 dev $rp22 170 ip address add fe80:2::22/64 dev $rp22 171 172 ip address add 169.254.3.23/24 dev $rp23 173 ip address add fe80:3::23/64 dev $rp23 174} 175 176router2_destroy() 177{ 178 ip route del 2001:db8:1::/64 vrf vrf-r2 179 ip route del 192.0.2.0/24 vrf vrf-r2 180 181 ip address del fe80:3::23/64 dev $rp23 182 ip address del 169.254.3.23/24 dev $rp23 183 184 ip address del fe80:2::22/64 dev $rp22 185 ip address del 169.254.2.22/24 dev $rp22 186 187 ip address del 2001:db8:2::1/64 dev $rp21 188 ip address del 198.51.100.1/24 dev $rp21 189 190 ip nexthop del id 201 191 ip nexthop del id 202 192 ip nexthop del id 204 193 ip nexthop del id 205 194 195 ip link set dev $rp23 down 196 ip link set dev $rp22 down 197 ip link set dev $rp21 down 198 199 vrf_destroy "vrf-r2" 200} 201 202routing_nh_obj() 203{ 204 ip nexthop add id 101 via 169.254.2.22 dev $rp12 205 ip nexthop add id 102 via 169.254.3.23 dev $rp13 206 ip nexthop add id 103 group 101/102 type resilient buckets 512 \ 207 idle_timer 0 208 ip route add 198.51.100.0/24 vrf vrf-r1 nhid 103 209 210 ip nexthop add id 104 via fe80:2::22 dev $rp12 211 ip nexthop add id 105 via fe80:3::23 dev $rp13 212 ip nexthop add id 106 group 104/105 type resilient buckets 512 \ 213 idle_timer 0 214 ip route add 2001:db8:2::/64 vrf vrf-r1 nhid 106 215 216 ip nexthop add id 201 via 169.254.2.12 dev $rp22 217 ip nexthop add id 202 via 169.254.3.13 dev $rp23 218 ip nexthop add id 203 group 201/202 type resilient buckets 512 \ 219 idle_timer 0 220 ip route add 192.0.2.0/24 vrf vrf-r2 nhid 203 221 222 ip nexthop add id 204 via fe80:2::12 dev $rp22 223 ip nexthop add id 205 via fe80:3::13 dev $rp23 224 ip nexthop add id 206 group 204/205 type resilient buckets 512 \ 225 idle_timer 0 226 ip route add 2001:db8:1::/64 vrf vrf-r2 nhid 206 227} 228 229multipath4_test() 230{ 231 local desc="$1" 232 local weight_rp12=$2 233 local weight_rp13=$3 234 local t0_rp12 t0_rp13 t1_rp12 t1_rp13 235 local packets_rp12 packets_rp13 236 237 # Transmit multiple flows from h1 to h2 and make sure they are 238 # distributed between both multipath links (rp12 and rp13) 239 # according to the provided weights. 240 sysctl_set net.ipv4.fib_multipath_hash_policy 1 241 242 t0_rp12=$(link_stats_tx_packets_get $rp12) 243 t0_rp13=$(link_stats_tx_packets_get $rp13) 244 245 ip vrf exec vrf-h1 $MZ $h1 -q -p 64 -A 192.0.2.2 -B 198.51.100.2 \ 246 -d $MZ_DELAY -t udp "sp=1024,dp=0-32768" 247 248 t1_rp12=$(link_stats_tx_packets_get $rp12) 249 t1_rp13=$(link_stats_tx_packets_get $rp13) 250 251 let "packets_rp12 = $t1_rp12 - $t0_rp12" 252 let "packets_rp13 = $t1_rp13 - $t0_rp13" 253 multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13 254 255 # Restore settings. 256 sysctl_restore net.ipv4.fib_multipath_hash_policy 257} 258 259multipath6_l4_test() 260{ 261 local desc="$1" 262 local weight_rp12=$2 263 local weight_rp13=$3 264 local t0_rp12 t0_rp13 t1_rp12 t1_rp13 265 local packets_rp12 packets_rp13 266 267 # Transmit multiple flows from h1 to h2 and make sure they are 268 # distributed between both multipath links (rp12 and rp13) 269 # according to the provided weights. 270 sysctl_set net.ipv6.fib_multipath_hash_policy 1 271 272 t0_rp12=$(link_stats_tx_packets_get $rp12) 273 t0_rp13=$(link_stats_tx_packets_get $rp13) 274 275 $MZ $h1 -6 -q -p 64 -A 2001:db8:1::2 -B 2001:db8:2::2 \ 276 -d $MZ_DELAY -t udp "sp=1024,dp=0-32768" 277 278 t1_rp12=$(link_stats_tx_packets_get $rp12) 279 t1_rp13=$(link_stats_tx_packets_get $rp13) 280 281 let "packets_rp12 = $t1_rp12 - $t0_rp12" 282 let "packets_rp13 = $t1_rp13 - $t0_rp13" 283 multipath_eval "$desc" $weight_rp12 $weight_rp13 $packets_rp12 $packets_rp13 284 285 sysctl_restore net.ipv6.fib_multipath_hash_policy 286} 287 288multipath_test() 289{ 290 # Without an idle timer, weight replacement should happen immediately. 291 log_info "Running multipath tests without an idle timer" 292 ip nexthop replace id 103 group 101/102 type resilient idle_timer 0 293 ip nexthop replace id 106 group 104/105 type resilient idle_timer 0 294 295 log_info "Running IPv4 multipath tests" 296 ip nexthop replace id 103 group 101,1/102,1 type resilient 297 multipath4_test "ECMP" 1 1 298 ip nexthop replace id 103 group 101,2/102,1 type resilient 299 multipath4_test "Weighted MP 2:1" 2 1 300 ip nexthop replace id 103 group 101,11/102,45 type resilient 301 multipath4_test "Weighted MP 11:45" 11 45 302 303 ip nexthop replace id 103 group 101,1/102,1 type resilient 304 305 log_info "Running IPv6 L4 hash multipath tests" 306 ip nexthop replace id 106 group 104,1/105,1 type resilient 307 multipath6_l4_test "ECMP" 1 1 308 ip nexthop replace id 106 group 104,2/105,1 type resilient 309 multipath6_l4_test "Weighted MP 2:1" 2 1 310 ip nexthop replace id 106 group 104,11/105,45 type resilient 311 multipath6_l4_test "Weighted MP 11:45" 11 45 312 313 ip nexthop replace id 106 group 104,1/105,1 type resilient 314 315 # With an idle timer, weight replacement should not happen, so the 316 # expected ratio should always be the initial one (1:1). 317 log_info "Running multipath tests with an idle timer of 120 seconds" 318 ip nexthop replace id 103 group 101/102 type resilient idle_timer 120 319 ip nexthop replace id 106 group 104/105 type resilient idle_timer 120 320 321 log_info "Running IPv4 multipath tests" 322 ip nexthop replace id 103 group 101,1/102,1 type resilient 323 multipath4_test "ECMP" 1 1 324 ip nexthop replace id 103 group 101,2/102,1 type resilient 325 multipath4_test "Weighted MP 2:1" 1 1 326 ip nexthop replace id 103 group 101,11/102,45 type resilient 327 multipath4_test "Weighted MP 11:45" 1 1 328 329 ip nexthop replace id 103 group 101,1/102,1 type resilient 330 331 log_info "Running IPv6 L4 hash multipath tests" 332 ip nexthop replace id 106 group 104,1/105,1 type resilient 333 multipath6_l4_test "ECMP" 1 1 334 ip nexthop replace id 106 group 104,2/105,1 type resilient 335 multipath6_l4_test "Weighted MP 2:1" 1 1 336 ip nexthop replace id 106 group 104,11/105,45 type resilient 337 multipath6_l4_test "Weighted MP 11:45" 1 1 338 339 ip nexthop replace id 106 group 104,1/105,1 type resilient 340 341 # With a short idle timer and enough idle time, weight replacement 342 # should happen. 343 log_info "Running multipath tests with an idle timer of 5 seconds" 344 ip nexthop replace id 103 group 101/102 type resilient idle_timer 5 345 ip nexthop replace id 106 group 104/105 type resilient idle_timer 5 346 347 log_info "Running IPv4 multipath tests" 348 sleep 10 349 ip nexthop replace id 103 group 101,1/102,1 type resilient 350 multipath4_test "ECMP" 1 1 351 sleep 10 352 ip nexthop replace id 103 group 101,2/102,1 type resilient 353 multipath4_test "Weighted MP 2:1" 2 1 354 sleep 10 355 ip nexthop replace id 103 group 101,11/102,45 type resilient 356 multipath4_test "Weighted MP 11:45" 11 45 357 358 ip nexthop replace id 103 group 101,1/102,1 type resilient 359 360 log_info "Running IPv6 L4 hash multipath tests" 361 sleep 10 362 ip nexthop replace id 106 group 104,1/105,1 type resilient 363 multipath6_l4_test "ECMP" 1 1 364 sleep 10 365 ip nexthop replace id 106 group 104,2/105,1 type resilient 366 multipath6_l4_test "Weighted MP 2:1" 2 1 367 sleep 10 368 ip nexthop replace id 106 group 104,11/105,45 type resilient 369 multipath6_l4_test "Weighted MP 11:45" 11 45 370 371 ip nexthop replace id 106 group 104,1/105,1 type resilient 372} 373 374nh_stats_test_v4() 375{ 376 __nh_stats_test_v4 resilient 377} 378 379nh_stats_test_v6() 380{ 381 __nh_stats_test_v6 resilient 382} 383 384setup_prepare() 385{ 386 h1=${NETIFS[p1]} 387 rp11=${NETIFS[p2]} 388 389 rp12=${NETIFS[p3]} 390 rp22=${NETIFS[p4]} 391 392 rp13=${NETIFS[p5]} 393 rp23=${NETIFS[p6]} 394 395 rp21=${NETIFS[p7]} 396 h2=${NETIFS[p8]} 397 398 vrf_prepare 399 400 h1_create 401 h2_create 402 403 router1_create 404 router2_create 405 406 forwarding_enable 407} 408 409cleanup() 410{ 411 pre_cleanup 412 413 forwarding_restore 414 415 router2_destroy 416 router1_destroy 417 418 h2_destroy 419 h1_destroy 420 421 vrf_cleanup 422} 423 424ping_ipv4() 425{ 426 ping_test $h1 198.51.100.2 427} 428 429ping_ipv6() 430{ 431 ping6_test $h1 2001:db8:2::2 432} 433 434ip nexthop ls >/dev/null 2>&1 435if [ $? -ne 0 ]; then 436 echo "Nexthop objects not supported; skipping tests" 437 exit $ksft_skip 438fi 439 440trap cleanup EXIT 441 442setup_prepare 443setup_wait 444routing_nh_obj 445 446tests_run 447 448exit $EXIT_STATUS 449