1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# This test is for checking bridge backup port and backup nexthop ID 5# functionality. The topology consists of two bridge (VTEPs) connected using 6# VXLAN. The test checks that when the switch port (swp1) is down, traffic is 7# redirected to the VXLAN port (vx0). When a backup nexthop ID is configured, 8# the test checks that traffic is redirected with the correct nexthop 9# information. 10# 11# +------------------------------------+ +------------------------------------+ 12# | + swp1 + vx0 | | + swp1 + vx0 | 13# | | | | | | | | 14# | | br0 | | | | | | 15# | +------------+-----------+ | | +------------+-----------+ | 16# | | | | | | 17# | | | | | | 18# | + | | + | 19# | br0 | | br0 | 20# | + | | + | 21# | | | | | | 22# | | | | | | 23# | + | | + | 24# | br0.10 | | br0.10 | 25# | 192.0.2.65/28 | | 192.0.2.66/28 | 26# | | | | 27# | | | | 28# | 192.0.2.33 | | 192.0.2.34 | 29# | + lo | | + lo | 30# | | | | 31# | | | | 32# | 192.0.2.49/28 | | 192.0.2.50/28 | 33# | veth0 +-------+ veth0 | 34# | | | | 35# | sw1 | | sw2 | 36# +------------------------------------+ +------------------------------------+ 37 38source lib.sh 39ret=0 40 41# All tests in this script. Can be overridden with -t option. 42TESTS=" 43 backup_port 44 backup_nhid 45 backup_nhid_invalid 46 backup_nhid_ping 47 backup_nhid_torture 48" 49VERBOSE=0 50PAUSE_ON_FAIL=no 51PAUSE=no 52PING_TIMEOUT=5 53 54################################################################################ 55# Utilities 56 57log_test() 58{ 59 local rc=$1 60 local expected=$2 61 local msg="$3" 62 63 if [ ${rc} -eq ${expected} ]; then 64 printf "TEST: %-60s [ OK ]\n" "${msg}" 65 nsuccess=$((nsuccess+1)) 66 else 67 ret=1 68 nfail=$((nfail+1)) 69 printf "TEST: %-60s [FAIL]\n" "${msg}" 70 if [ "$VERBOSE" = "1" ]; then 71 echo " rc=$rc, expected $expected" 72 fi 73 74 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 75 echo 76 echo "hit enter to continue, 'q' to quit" 77 read a 78 [ "$a" = "q" ] && exit 1 79 fi 80 fi 81 82 if [ "${PAUSE}" = "yes" ]; then 83 echo 84 echo "hit enter to continue, 'q' to quit" 85 read a 86 [ "$a" = "q" ] && exit 1 87 fi 88 89 [ "$VERBOSE" = "1" ] && echo 90} 91 92run_cmd() 93{ 94 local cmd="$1" 95 local out 96 local stderr="2>/dev/null" 97 98 if [ "$VERBOSE" = "1" ]; then 99 printf "COMMAND: $cmd\n" 100 stderr= 101 fi 102 103 out=$(eval $cmd $stderr) 104 rc=$? 105 if [ "$VERBOSE" = "1" -a -n "$out" ]; then 106 echo " $out" 107 fi 108 109 return $rc 110} 111 112tc_check_packets() 113{ 114 local ns=$1; shift 115 local id=$1; shift 116 local handle=$1; shift 117 local count=$1; shift 118 local pkts 119 120 sleep 0.1 121 pkts=$(tc -n $ns -j -s filter show $id \ 122 | jq ".[] | select(.options.handle == $handle) | \ 123 .options.actions[0].stats.packets") 124 [[ $pkts == $count ]] 125} 126 127################################################################################ 128# Setup 129 130setup_topo_ns() 131{ 132 local ns=$1; shift 133 134 ip netns exec $ns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1 135 ip netns exec $ns sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1 136 ip netns exec $ns sysctl -qw net.ipv6.conf.all.accept_dad=0 137 ip netns exec $ns sysctl -qw net.ipv6.conf.default.accept_dad=0 138} 139 140setup_topo() 141{ 142 local ns 143 144 setup_ns sw1 sw2 145 for ns in $sw1 $sw2; do 146 setup_topo_ns $ns 147 done 148 149 ip link add name veth0 type veth peer name veth1 150 ip link set dev veth0 netns $sw1 name veth0 151 ip link set dev veth1 netns $sw2 name veth0 152} 153 154setup_sw_common() 155{ 156 local ns=$1; shift 157 local local_addr=$1; shift 158 local remote_addr=$1; shift 159 local veth_addr=$1; shift 160 local gw_addr=$1; shift 161 local br_addr=$1; shift 162 163 ip -n $ns address add $local_addr/32 dev lo 164 165 ip -n $ns link set dev veth0 up 166 ip -n $ns address add $veth_addr/28 dev veth0 167 ip -n $ns route add default via $gw_addr 168 169 ip -n $ns link add name br0 up type bridge vlan_filtering 1 \ 170 vlan_default_pvid 0 mcast_snooping 0 171 172 ip -n $ns link add link br0 name br0.10 up type vlan id 10 173 bridge -n $ns vlan add vid 10 dev br0 self 174 ip -n $ns address add $br_addr/28 dev br0.10 175 176 ip -n $ns link add name swp1 up type dummy 177 ip -n $ns link set dev swp1 master br0 178 bridge -n $ns vlan add vid 10 dev swp1 untagged 179 180 ip -n $ns link add name vx0 up master br0 type vxlan \ 181 local $local_addr dstport 4789 nolearning external 182 bridge -n $ns link set dev vx0 vlan_tunnel on learning off 183 184 bridge -n $ns vlan add vid 10 dev vx0 185 bridge -n $ns vlan add vid 10 dev vx0 tunnel_info id 10010 186} 187 188setup_sw1() 189{ 190 local ns=$sw1 191 local local_addr=192.0.2.33 192 local remote_addr=192.0.2.34 193 local veth_addr=192.0.2.49 194 local gw_addr=192.0.2.50 195 local br_addr=192.0.2.65 196 197 setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr \ 198 $br_addr 199} 200 201setup_sw2() 202{ 203 local ns=$sw2 204 local local_addr=192.0.2.34 205 local remote_addr=192.0.2.33 206 local veth_addr=192.0.2.50 207 local gw_addr=192.0.2.49 208 local br_addr=192.0.2.66 209 210 setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr \ 211 $br_addr 212} 213 214setup() 215{ 216 set -e 217 218 setup_topo 219 setup_sw1 220 setup_sw2 221 222 sleep 5 223 224 set +e 225} 226 227cleanup() 228{ 229 cleanup_ns $sw1 $sw2 230} 231 232################################################################################ 233# Tests 234 235backup_port() 236{ 237 local dmac=00:11:22:33:44:55 238 local smac=00:aa:bb:cc:dd:ee 239 240 echo 241 echo "Backup port" 242 echo "-----------" 243 244 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact" 245 run_cmd "tc -n $sw1 filter replace dev swp1 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass" 246 247 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact" 248 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass" 249 250 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 251 252 # Initial state - check that packets are forwarded out of swp1 when it 253 # has a carrier and not forwarded out of any port when it does not have 254 # a carrier. 255 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 256 tc_check_packets $sw1 "dev swp1 egress" 101 1 257 log_test $? 0 "Forwarding out of swp1" 258 tc_check_packets $sw1 "dev vx0 egress" 101 0 259 log_test $? 0 "No forwarding out of vx0" 260 261 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 262 log_test $? 0 "swp1 carrier off" 263 264 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 265 tc_check_packets $sw1 "dev swp1 egress" 101 1 266 log_test $? 0 "No forwarding out of swp1" 267 tc_check_packets $sw1 "dev vx0 egress" 101 0 268 log_test $? 0 "No forwarding out of vx0" 269 270 run_cmd "ip -n $sw1 link set dev swp1 carrier on" 271 log_test $? 0 "swp1 carrier on" 272 273 # Configure vx0 as the backup port of swp1 and check that packets are 274 # forwarded out of swp1 when it has a carrier and out of vx0 when swp1 275 # does not have a carrier. 276 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 277 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 278 log_test $? 0 "vx0 configured as backup port of swp1" 279 280 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 281 tc_check_packets $sw1 "dev swp1 egress" 101 2 282 log_test $? 0 "Forwarding out of swp1" 283 tc_check_packets $sw1 "dev vx0 egress" 101 0 284 log_test $? 0 "No forwarding out of vx0" 285 286 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 287 log_test $? 0 "swp1 carrier off" 288 289 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 290 tc_check_packets $sw1 "dev swp1 egress" 101 2 291 log_test $? 0 "No forwarding out of swp1" 292 tc_check_packets $sw1 "dev vx0 egress" 101 1 293 log_test $? 0 "Forwarding out of vx0" 294 295 run_cmd "ip -n $sw1 link set dev swp1 carrier on" 296 log_test $? 0 "swp1 carrier on" 297 298 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 299 tc_check_packets $sw1 "dev swp1 egress" 101 3 300 log_test $? 0 "Forwarding out of swp1" 301 tc_check_packets $sw1 "dev vx0 egress" 101 1 302 log_test $? 0 "No forwarding out of vx0" 303 304 # Remove vx0 as the backup port of swp1 and check that packets are no 305 # longer forwarded out of vx0 when swp1 does not have a carrier. 306 run_cmd "bridge -n $sw1 link set dev swp1 nobackup_port" 307 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 308 log_test $? 1 "vx0 not configured as backup port of swp1" 309 310 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 311 tc_check_packets $sw1 "dev swp1 egress" 101 4 312 log_test $? 0 "Forwarding out of swp1" 313 tc_check_packets $sw1 "dev vx0 egress" 101 1 314 log_test $? 0 "No forwarding out of vx0" 315 316 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 317 log_test $? 0 "swp1 carrier off" 318 319 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 320 tc_check_packets $sw1 "dev swp1 egress" 101 4 321 log_test $? 0 "No forwarding out of swp1" 322 tc_check_packets $sw1 "dev vx0 egress" 101 1 323 log_test $? 0 "No forwarding out of vx0" 324} 325 326backup_nhid() 327{ 328 local dmac=00:11:22:33:44:55 329 local smac=00:aa:bb:cc:dd:ee 330 331 echo 332 echo "Backup nexthop ID" 333 echo "-----------------" 334 335 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact" 336 run_cmd "tc -n $sw1 filter replace dev swp1 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass" 337 338 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact" 339 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass" 340 341 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 342 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb" 343 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb" 344 345 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 346 run_cmd "bridge -n $sw1 fdb replace $dmac dev vx0 self static dst 192.0.2.36 src_vni 10010" 347 348 run_cmd "ip -n $sw2 address replace 192.0.2.36/32 dev lo" 349 350 # The first filter matches on packets forwarded using the backup 351 # nexthop ID and the second filter matches on packets forwarded using a 352 # regular VXLAN FDB entry. 353 run_cmd "tc -n $sw2 qdisc replace dev vx0 clsact" 354 run_cmd "tc -n $sw2 filter replace dev vx0 ingress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac enc_key_id 10010 enc_dst_ip 192.0.2.34 action pass" 355 run_cmd "tc -n $sw2 filter replace dev vx0 ingress pref 1 handle 102 proto ip flower src_mac $smac dst_mac $dmac enc_key_id 10010 enc_dst_ip 192.0.2.36 action pass" 356 357 # Configure vx0 as the backup port of swp1 and check that packets are 358 # forwarded out of swp1 when it has a carrier and out of vx0 when swp1 359 # does not have a carrier. When packets are forwarded out of vx0, check 360 # that they are forwarded by the VXLAN FDB entry. 361 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 362 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 363 log_test $? 0 "vx0 configured as backup port of swp1" 364 365 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 366 tc_check_packets $sw1 "dev swp1 egress" 101 1 367 log_test $? 0 "Forwarding out of swp1" 368 tc_check_packets $sw1 "dev vx0 egress" 101 0 369 log_test $? 0 "No forwarding out of vx0" 370 371 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 372 log_test $? 0 "swp1 carrier off" 373 374 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 375 tc_check_packets $sw1 "dev swp1 egress" 101 1 376 log_test $? 0 "No forwarding out of swp1" 377 tc_check_packets $sw1 "dev vx0 egress" 101 1 378 log_test $? 0 "Forwarding out of vx0" 379 tc_check_packets $sw2 "dev vx0 ingress" 101 0 380 log_test $? 0 "No forwarding using backup nexthop ID" 381 tc_check_packets $sw2 "dev vx0 ingress" 102 1 382 log_test $? 0 "Forwarding using VXLAN FDB entry" 383 384 run_cmd "ip -n $sw1 link set dev swp1 carrier on" 385 log_test $? 0 "swp1 carrier on" 386 387 # Configure nexthop ID 10 as the backup nexthop ID of swp1 and check 388 # that when packets are forwarded out of vx0, they are forwarded using 389 # the backup nexthop ID. 390 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 391 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 10\"" 392 log_test $? 0 "nexthop ID 10 configured as backup nexthop ID of swp1" 393 394 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 395 tc_check_packets $sw1 "dev swp1 egress" 101 2 396 log_test $? 0 "Forwarding out of swp1" 397 tc_check_packets $sw1 "dev vx0 egress" 101 1 398 log_test $? 0 "No forwarding out of vx0" 399 400 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 401 log_test $? 0 "swp1 carrier off" 402 403 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 404 tc_check_packets $sw1 "dev swp1 egress" 101 2 405 log_test $? 0 "No forwarding out of swp1" 406 tc_check_packets $sw1 "dev vx0 egress" 101 2 407 log_test $? 0 "Forwarding out of vx0" 408 tc_check_packets $sw2 "dev vx0 ingress" 101 1 409 log_test $? 0 "Forwarding using backup nexthop ID" 410 tc_check_packets $sw2 "dev vx0 ingress" 102 1 411 log_test $? 0 "No forwarding using VXLAN FDB entry" 412 413 run_cmd "ip -n $sw1 link set dev swp1 carrier on" 414 log_test $? 0 "swp1 carrier on" 415 416 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 417 tc_check_packets $sw1 "dev swp1 egress" 101 3 418 log_test $? 0 "Forwarding out of swp1" 419 tc_check_packets $sw1 "dev vx0 egress" 101 2 420 log_test $? 0 "No forwarding out of vx0" 421 tc_check_packets $sw2 "dev vx0 ingress" 101 1 422 log_test $? 0 "No forwarding using backup nexthop ID" 423 tc_check_packets $sw2 "dev vx0 ingress" 102 1 424 log_test $? 0 "No forwarding using VXLAN FDB entry" 425 426 # Reset the backup nexthop ID to 0 and check that packets are no longer 427 # forwarded using the backup nexthop ID when swp1 does not have a 428 # carrier and are instead forwarded by the VXLAN FDB. 429 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 0" 430 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid\"" 431 log_test $? 1 "No backup nexthop ID configured for swp1" 432 433 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 434 tc_check_packets $sw1 "dev swp1 egress" 101 4 435 log_test $? 0 "Forwarding out of swp1" 436 tc_check_packets $sw1 "dev vx0 egress" 101 2 437 log_test $? 0 "No forwarding out of vx0" 438 tc_check_packets $sw2 "dev vx0 ingress" 101 1 439 log_test $? 0 "No forwarding using backup nexthop ID" 440 tc_check_packets $sw2 "dev vx0 ingress" 102 1 441 log_test $? 0 "No forwarding using VXLAN FDB entry" 442 443 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 444 log_test $? 0 "swp1 carrier off" 445 446 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 447 tc_check_packets $sw1 "dev swp1 egress" 101 4 448 log_test $? 0 "No forwarding out of swp1" 449 tc_check_packets $sw1 "dev vx0 egress" 101 3 450 log_test $? 0 "Forwarding out of vx0" 451 tc_check_packets $sw2 "dev vx0 ingress" 101 1 452 log_test $? 0 "No forwarding using backup nexthop ID" 453 tc_check_packets $sw2 "dev vx0 ingress" 102 2 454 log_test $? 0 "Forwarding using VXLAN FDB entry" 455} 456 457backup_nhid_invalid() 458{ 459 local dmac=00:11:22:33:44:55 460 local smac=00:aa:bb:cc:dd:ee 461 local tx_drop 462 463 echo 464 echo "Backup nexthop ID - invalid IDs" 465 echo "-------------------------------" 466 467 # Check that when traffic is redirected with an invalid nexthop ID, it 468 # is forwarded out of the VXLAN port, but dropped by the VXLAN driver 469 # and does not crash the host. 470 471 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact" 472 run_cmd "tc -n $sw1 filter replace dev swp1 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass" 473 474 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact" 475 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass" 476 # Drop all other Tx traffic to avoid changes to Tx drop counter. 477 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 2 handle 102 proto all matchall action drop" 478 479 tx_drop=$(ip -n $sw1 -s -j link show dev vx0 | jq '.[]["stats64"]["tx"]["dropped"]') 480 481 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 482 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb" 483 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb" 484 485 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 486 487 run_cmd "tc -n $sw2 qdisc replace dev vx0 clsact" 488 run_cmd "tc -n $sw2 filter replace dev vx0 ingress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac enc_key_id 10010 enc_dst_ip 192.0.2.34 action pass" 489 490 # First, check that redirection works. 491 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 492 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 493 log_test $? 0 "vx0 configured as backup port of swp1" 494 495 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 496 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 10\"" 497 log_test $? 0 "Valid nexthop as backup nexthop" 498 499 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 500 log_test $? 0 "swp1 carrier off" 501 502 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 503 tc_check_packets $sw1 "dev swp1 egress" 101 0 504 log_test $? 0 "No forwarding out of swp1" 505 tc_check_packets $sw1 "dev vx0 egress" 101 1 506 log_test $? 0 "Forwarding out of vx0" 507 tc_check_packets $sw2 "dev vx0 ingress" 101 1 508 log_test $? 0 "Forwarding using backup nexthop ID" 509 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $tx_drop'" 510 log_test $? 0 "No Tx drop increase" 511 512 # Use a non-existent nexthop ID. 513 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 20" 514 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 20\"" 515 log_test $? 0 "Non-existent nexthop as backup nexthop" 516 517 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 518 tc_check_packets $sw1 "dev swp1 egress" 101 0 519 log_test $? 0 "No forwarding out of swp1" 520 tc_check_packets $sw1 "dev vx0 egress" 101 2 521 log_test $? 0 "Forwarding out of vx0" 522 tc_check_packets $sw2 "dev vx0 ingress" 101 1 523 log_test $? 0 "No forwarding using backup nexthop ID" 524 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 1))'" 525 log_test $? 0 "Tx drop increased" 526 527 # Use a blckhole nexthop. 528 run_cmd "ip -n $sw1 nexthop replace id 30 blackhole" 529 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 30" 530 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 30\"" 531 log_test $? 0 "Blackhole nexthop as backup nexthop" 532 533 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 534 tc_check_packets $sw1 "dev swp1 egress" 101 0 535 log_test $? 0 "No forwarding out of swp1" 536 tc_check_packets $sw1 "dev vx0 egress" 101 3 537 log_test $? 0 "Forwarding out of vx0" 538 tc_check_packets $sw2 "dev vx0 ingress" 101 1 539 log_test $? 0 "No forwarding using backup nexthop ID" 540 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 2))'" 541 log_test $? 0 "Tx drop increased" 542 543 # Non-group FDB nexthop. 544 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 1" 545 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 1\"" 546 log_test $? 0 "Non-group FDB nexthop as backup nexthop" 547 548 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 549 tc_check_packets $sw1 "dev swp1 egress" 101 0 550 log_test $? 0 "No forwarding out of swp1" 551 tc_check_packets $sw1 "dev vx0 egress" 101 4 552 log_test $? 0 "Forwarding out of vx0" 553 tc_check_packets $sw2 "dev vx0 ingress" 101 1 554 log_test $? 0 "No forwarding using backup nexthop ID" 555 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 3))'" 556 log_test $? 0 "Tx drop increased" 557 558 # IPv6 address family nexthop. 559 run_cmd "ip -n $sw1 nexthop replace id 100 via 2001:db8:100::1 fdb" 560 run_cmd "ip -n $sw1 nexthop replace id 200 via 2001:db8:100::1 fdb" 561 run_cmd "ip -n $sw1 nexthop replace id 300 group 100/200 fdb" 562 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 300" 563 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 300\"" 564 log_test $? 0 "IPv6 address family nexthop as backup nexthop" 565 566 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1" 567 tc_check_packets $sw1 "dev swp1 egress" 101 0 568 log_test $? 0 "No forwarding out of swp1" 569 tc_check_packets $sw1 "dev vx0 egress" 101 5 570 log_test $? 0 "Forwarding out of vx0" 571 tc_check_packets $sw2 "dev vx0 ingress" 101 1 572 log_test $? 0 "No forwarding using backup nexthop ID" 573 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 4))'" 574 log_test $? 0 "Tx drop increased" 575} 576 577backup_nhid_ping() 578{ 579 local sw1_mac 580 local sw2_mac 581 582 echo 583 echo "Backup nexthop ID - ping" 584 echo "------------------------" 585 586 # Test bidirectional traffic when traffic is redirected in both VTEPs. 587 sw1_mac=$(ip -n $sw1 -j -p link show br0.10 | jq -r '.[]["address"]') 588 sw2_mac=$(ip -n $sw2 -j -p link show br0.10 | jq -r '.[]["address"]') 589 590 run_cmd "bridge -n $sw1 fdb replace $sw2_mac dev swp1 master static vlan 10" 591 run_cmd "bridge -n $sw2 fdb replace $sw1_mac dev swp1 master static vlan 10" 592 593 run_cmd "ip -n $sw1 neigh replace 192.0.2.66 lladdr $sw2_mac nud perm dev br0.10" 594 run_cmd "ip -n $sw2 neigh replace 192.0.2.65 lladdr $sw1_mac nud perm dev br0.10" 595 596 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 597 run_cmd "ip -n $sw2 nexthop replace id 1 via 192.0.2.33 fdb" 598 run_cmd "ip -n $sw1 nexthop replace id 10 group 1 fdb" 599 run_cmd "ip -n $sw2 nexthop replace id 10 group 1 fdb" 600 601 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 602 run_cmd "bridge -n $sw2 link set dev swp1 backup_port vx0" 603 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 604 run_cmd "bridge -n $sw2 link set dev swp1 backup_nhid 10" 605 606 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 607 run_cmd "ip -n $sw2 link set dev swp1 carrier off" 608 609 run_cmd "ip netns exec $sw1 ping -i 0.1 -c 10 -w $PING_TIMEOUT 192.0.2.66" 610 log_test $? 0 "Ping with backup nexthop ID" 611 612 # Reset the backup nexthop ID to 0 and check that ping fails. 613 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 0" 614 run_cmd "bridge -n $sw2 link set dev swp1 backup_nhid 0" 615 616 run_cmd "ip netns exec $sw1 ping -i 0.1 -c 10 -w $PING_TIMEOUT 192.0.2.66" 617 log_test $? 1 "Ping after disabling backup nexthop ID" 618} 619 620backup_nhid_add_del_loop() 621{ 622 while true; do 623 ip -n $sw1 nexthop del id 10 624 ip -n $sw1 nexthop replace id 10 group 1/2 fdb 625 done >/dev/null 2>&1 626} 627 628backup_nhid_torture() 629{ 630 local dmac=00:11:22:33:44:55 631 local smac=00:aa:bb:cc:dd:ee 632 local pid1 633 local pid2 634 local pid3 635 636 echo 637 echo "Backup nexthop ID - torture test" 638 echo "--------------------------------" 639 640 # Continuously send traffic through the backup nexthop while adding and 641 # deleting the group. The test is considered successful if nothing 642 # crashed. 643 644 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 645 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb" 646 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb" 647 648 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 649 650 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 651 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 652 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 653 654 backup_nhid_add_del_loop & 655 pid1=$! 656 ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 0 & 657 pid2=$! 658 659 sleep 30 660 kill -9 $pid1 $pid2 661 wait $pid1 $pid2 2>/dev/null 662 663 log_test 0 0 "Torture test" 664} 665 666################################################################################ 667# Usage 668 669usage() 670{ 671 cat <<EOF 672usage: ${0##*/} OPTS 673 674 -t <test> Test(s) to run (default: all) 675 (options: $TESTS) 676 -p Pause on fail 677 -P Pause after each test before cleanup 678 -v Verbose mode (show commands and output) 679 -w Timeout for ping 680EOF 681} 682 683################################################################################ 684# Main 685 686trap cleanup EXIT 687 688while getopts ":t:pPvhw:" opt; do 689 case $opt in 690 t) TESTS=$OPTARG;; 691 p) PAUSE_ON_FAIL=yes;; 692 P) PAUSE=yes;; 693 v) VERBOSE=$(($VERBOSE + 1));; 694 w) PING_TIMEOUT=$OPTARG;; 695 h) usage; exit 0;; 696 *) usage; exit 1;; 697 esac 698done 699 700# Make sure we don't pause twice. 701[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 702 703if [ "$(id -u)" -ne 0 ];then 704 echo "SKIP: Need root privileges" 705 exit $ksft_skip; 706fi 707 708if [ ! -x "$(command -v ip)" ]; then 709 echo "SKIP: Could not run test without ip tool" 710 exit $ksft_skip 711fi 712 713if [ ! -x "$(command -v bridge)" ]; then 714 echo "SKIP: Could not run test without bridge tool" 715 exit $ksft_skip 716fi 717 718if [ ! -x "$(command -v tc)" ]; then 719 echo "SKIP: Could not run test without tc tool" 720 exit $ksft_skip 721fi 722 723if [ ! -x "$(command -v mausezahn)" ]; then 724 echo "SKIP: Could not run test without mausezahn tool" 725 exit $ksft_skip 726fi 727 728if [ ! -x "$(command -v jq)" ]; then 729 echo "SKIP: Could not run test without jq tool" 730 exit $ksft_skip 731fi 732 733bridge link help 2>&1 | grep -q "backup_nhid" 734if [ $? -ne 0 ]; then 735 echo "SKIP: iproute2 bridge too old, missing backup nexthop ID support" 736 exit $ksft_skip 737fi 738 739# Start clean. 740cleanup 741 742for t in $TESTS 743do 744 setup; $t; cleanup; 745done 746 747if [ "$TESTS" != "none" ]; then 748 printf "\nTests passed: %3d\n" ${nsuccess} 749 printf "Tests failed: %3d\n" ${nfail} 750fi 751 752exit $ret 753