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