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 # Check that packets are forwarded out of vx0 when swp1 is 319 # administratively down and out of swp1 when it is administratively up 320 # again. 321 run_cmd "ip -n $sw1 link set dev swp1 down" 322 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 323 log_test $? 0 "swp1 administratively down" 324 325 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" 326 tc_check_packets $sw1 "dev swp1 egress" 101 3 327 log_test $? 0 "No forwarding out of swp1" 328 tc_check_packets $sw1 "dev vx0 egress" 101 2 329 log_test $? 0 "Forwarding out of vx0" 330 331 run_cmd "ip -n $sw1 link set dev swp1 up" 332 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding 333 log_test $? 0 "swp1 administratively up" 334 335 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" 336 tc_check_packets $sw1 "dev swp1 egress" 101 4 337 log_test $? 0 "Forwarding out of swp1" 338 tc_check_packets $sw1 "dev vx0 egress" 101 2 339 log_test $? 0 "No forwarding out of vx0" 340 341 # Remove vx0 as the backup port of swp1 and check that packets are no 342 # longer forwarded out of vx0 when swp1 does not have a carrier. 343 run_cmd "bridge -n $sw1 link set dev swp1 nobackup_port" 344 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 345 log_test $? 1 "vx0 not configured as backup port of swp1" 346 347 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" 348 tc_check_packets $sw1 "dev swp1 egress" 101 5 349 log_test $? 0 "Forwarding out of swp1" 350 tc_check_packets $sw1 "dev vx0 egress" 101 2 351 log_test $? 0 "No forwarding out of vx0" 352 353 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 354 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 355 log_test $? 0 "swp1 carrier off" 356 357 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" 358 tc_check_packets $sw1 "dev swp1 egress" 101 5 359 log_test $? 0 "No forwarding out of swp1" 360 tc_check_packets $sw1 "dev vx0 egress" 101 2 361 log_test $? 0 "No forwarding out of vx0" 362} 363 364backup_nhid() 365{ 366 local dmac=00:11:22:33:44:55 367 local smac=00:aa:bb:cc:dd:ee 368 369 echo 370 echo "Backup nexthop ID" 371 echo "-----------------" 372 373 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact" 374 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" 375 376 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact" 377 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" 378 379 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 380 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb" 381 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb" 382 383 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 384 run_cmd "bridge -n $sw1 fdb replace $dmac dev vx0 self static dst 192.0.2.36 src_vni 10010" 385 386 run_cmd "ip -n $sw2 address replace 192.0.2.36/32 dev lo" 387 388 # The first filter matches on packets forwarded using the backup 389 # nexthop ID and the second filter matches on packets forwarded using a 390 # regular VXLAN FDB entry. 391 run_cmd "tc -n $sw2 qdisc replace dev vx0 clsact" 392 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" 393 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" 394 395 # Configure vx0 as the backup port of swp1 and check that packets are 396 # forwarded out of swp1 when it has a carrier and out of vx0 when swp1 397 # does not have a carrier. When packets are forwarded out of vx0, check 398 # that they are forwarded by the VXLAN FDB entry. 399 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 400 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 401 log_test $? 0 "vx0 configured as backup port of swp1" 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 1 405 log_test $? 0 "Forwarding out of swp1" 406 tc_check_packets $sw1 "dev vx0 egress" 101 0 407 log_test $? 0 "No forwarding out of vx0" 408 409 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 410 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 411 log_test $? 0 "swp1 carrier off" 412 413 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" 414 tc_check_packets $sw1 "dev swp1 egress" 101 1 415 log_test $? 0 "No forwarding out of swp1" 416 tc_check_packets $sw1 "dev vx0 egress" 101 1 417 log_test $? 0 "Forwarding out of vx0" 418 tc_check_packets $sw2 "dev vx0 ingress" 101 0 419 log_test $? 0 "No forwarding using backup nexthop ID" 420 tc_check_packets $sw2 "dev vx0 ingress" 102 1 421 log_test $? 0 "Forwarding using VXLAN FDB entry" 422 423 run_cmd "ip -n $sw1 link set dev swp1 carrier on" 424 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding 425 log_test $? 0 "swp1 carrier on" 426 427 # Configure nexthop ID 10 as the backup nexthop ID of swp1 and check 428 # that when packets are forwarded out of vx0, they are forwarded using 429 # the backup nexthop ID. 430 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 431 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 10\"" 432 log_test $? 0 "nexthop ID 10 configured as backup nexthop ID of swp1" 433 434 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" 435 tc_check_packets $sw1 "dev swp1 egress" 101 2 436 log_test $? 0 "Forwarding out of swp1" 437 tc_check_packets $sw1 "dev vx0 egress" 101 1 438 log_test $? 0 "No forwarding out of vx0" 439 440 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 441 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 442 log_test $? 0 "swp1 carrier off" 443 444 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" 445 tc_check_packets $sw1 "dev swp1 egress" 101 2 446 log_test $? 0 "No forwarding out of swp1" 447 tc_check_packets $sw1 "dev vx0 egress" 101 2 448 log_test $? 0 "Forwarding out of vx0" 449 tc_check_packets $sw2 "dev vx0 ingress" 101 1 450 log_test $? 0 "Forwarding using backup nexthop ID" 451 tc_check_packets $sw2 "dev vx0 ingress" 102 1 452 log_test $? 0 "No forwarding using VXLAN FDB entry" 453 454 run_cmd "ip -n $sw1 link set dev swp1 carrier on" 455 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding 456 log_test $? 0 "swp1 carrier on" 457 458 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" 459 tc_check_packets $sw1 "dev swp1 egress" 101 3 460 log_test $? 0 "Forwarding out of swp1" 461 tc_check_packets $sw1 "dev vx0 egress" 101 2 462 log_test $? 0 "No forwarding out of vx0" 463 tc_check_packets $sw2 "dev vx0 ingress" 101 1 464 log_test $? 0 "No forwarding using backup nexthop ID" 465 tc_check_packets $sw2 "dev vx0 ingress" 102 1 466 log_test $? 0 "No forwarding using VXLAN FDB entry" 467 468 # Reset the backup nexthop ID to 0 and check that packets are no longer 469 # forwarded using the backup nexthop ID when swp1 does not have a 470 # carrier and are instead forwarded by the VXLAN FDB. 471 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 0" 472 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid\"" 473 log_test $? 1 "No backup nexthop ID configured for swp1" 474 475 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" 476 tc_check_packets $sw1 "dev swp1 egress" 101 4 477 log_test $? 0 "Forwarding out of swp1" 478 tc_check_packets $sw1 "dev vx0 egress" 101 2 479 log_test $? 0 "No forwarding out of vx0" 480 tc_check_packets $sw2 "dev vx0 ingress" 101 1 481 log_test $? 0 "No forwarding using backup nexthop ID" 482 tc_check_packets $sw2 "dev vx0 ingress" 102 1 483 log_test $? 0 "No forwarding using VXLAN FDB entry" 484 485 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 486 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 487 log_test $? 0 "swp1 carrier off" 488 489 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" 490 tc_check_packets $sw1 "dev swp1 egress" 101 4 491 log_test $? 0 "No forwarding out of swp1" 492 tc_check_packets $sw1 "dev vx0 egress" 101 3 493 log_test $? 0 "Forwarding out of vx0" 494 tc_check_packets $sw2 "dev vx0 ingress" 101 1 495 log_test $? 0 "No forwarding using backup nexthop ID" 496 tc_check_packets $sw2 "dev vx0 ingress" 102 2 497 log_test $? 0 "Forwarding using VXLAN FDB entry" 498} 499 500backup_nhid_invalid() 501{ 502 local dmac=00:11:22:33:44:55 503 local smac=00:aa:bb:cc:dd:ee 504 local tx_drop 505 506 echo 507 echo "Backup nexthop ID - invalid IDs" 508 echo "-------------------------------" 509 510 # Check that when traffic is redirected with an invalid nexthop ID, it 511 # is forwarded out of the VXLAN port, but dropped by the VXLAN driver 512 # and does not crash the host. 513 514 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact" 515 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" 516 517 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact" 518 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" 519 # Drop all other Tx traffic to avoid changes to Tx drop counter. 520 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 2 handle 102 proto all matchall action drop" 521 522 tx_drop=$(ip -n $sw1 -s -j link show dev vx0 | jq '.[]["stats64"]["tx"]["dropped"]') 523 524 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 525 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb" 526 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb" 527 528 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 529 530 run_cmd "tc -n $sw2 qdisc replace dev vx0 clsact" 531 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" 532 533 # First, check that redirection works. 534 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 535 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\"" 536 log_test $? 0 "vx0 configured as backup port of swp1" 537 538 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 539 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 10\"" 540 log_test $? 0 "Valid nexthop as backup nexthop" 541 542 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 543 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 544 log_test $? 0 "swp1 carrier off" 545 546 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" 547 tc_check_packets $sw1 "dev swp1 egress" 101 0 548 log_test $? 0 "No forwarding out of swp1" 549 tc_check_packets $sw1 "dev vx0 egress" 101 1 550 log_test $? 0 "Forwarding out of vx0" 551 tc_check_packets $sw2 "dev vx0 ingress" 101 1 552 log_test $? 0 "Forwarding using backup nexthop ID" 553 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $tx_drop'" 554 log_test $? 0 "No Tx drop increase" 555 556 # Use a non-existent nexthop ID. 557 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 20" 558 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 20\"" 559 log_test $? 0 "Non-existent nexthop as backup nexthop" 560 561 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" 562 tc_check_packets $sw1 "dev swp1 egress" 101 0 563 log_test $? 0 "No forwarding out of swp1" 564 tc_check_packets $sw1 "dev vx0 egress" 101 2 565 log_test $? 0 "Forwarding out of vx0" 566 tc_check_packets $sw2 "dev vx0 ingress" 101 1 567 log_test $? 0 "No forwarding using backup nexthop ID" 568 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 1))'" 569 log_test $? 0 "Tx drop increased" 570 571 # Use a blckhole nexthop. 572 run_cmd "ip -n $sw1 nexthop replace id 30 blackhole" 573 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 30" 574 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 30\"" 575 log_test $? 0 "Blackhole nexthop as backup nexthop" 576 577 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" 578 tc_check_packets $sw1 "dev swp1 egress" 101 0 579 log_test $? 0 "No forwarding out of swp1" 580 tc_check_packets $sw1 "dev vx0 egress" 101 3 581 log_test $? 0 "Forwarding out of vx0" 582 tc_check_packets $sw2 "dev vx0 ingress" 101 1 583 log_test $? 0 "No forwarding using backup nexthop ID" 584 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 2))'" 585 log_test $? 0 "Tx drop increased" 586 587 # Non-group FDB nexthop. 588 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 1" 589 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 1\"" 590 log_test $? 0 "Non-group FDB nexthop as backup nexthop" 591 592 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" 593 tc_check_packets $sw1 "dev swp1 egress" 101 0 594 log_test $? 0 "No forwarding out of swp1" 595 tc_check_packets $sw1 "dev vx0 egress" 101 4 596 log_test $? 0 "Forwarding out of vx0" 597 tc_check_packets $sw2 "dev vx0 ingress" 101 1 598 log_test $? 0 "No forwarding using backup nexthop ID" 599 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 3))'" 600 log_test $? 0 "Tx drop increased" 601 602 # IPv6 address family nexthop. 603 run_cmd "ip -n $sw1 nexthop replace id 100 via 2001:db8:100::1 fdb" 604 run_cmd "ip -n $sw1 nexthop replace id 200 via 2001:db8:100::1 fdb" 605 run_cmd "ip -n $sw1 nexthop replace id 300 group 100/200 fdb" 606 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 300" 607 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 300\"" 608 log_test $? 0 "IPv6 address family nexthop as backup nexthop" 609 610 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" 611 tc_check_packets $sw1 "dev swp1 egress" 101 0 612 log_test $? 0 "No forwarding out of swp1" 613 tc_check_packets $sw1 "dev vx0 egress" 101 5 614 log_test $? 0 "Forwarding out of vx0" 615 tc_check_packets $sw2 "dev vx0 ingress" 101 1 616 log_test $? 0 "No forwarding using backup nexthop ID" 617 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 4))'" 618 log_test $? 0 "Tx drop increased" 619} 620 621backup_nhid_ping() 622{ 623 local sw1_mac 624 local sw2_mac 625 626 echo 627 echo "Backup nexthop ID - ping" 628 echo "------------------------" 629 630 # Test bidirectional traffic when traffic is redirected in both VTEPs. 631 sw1_mac=$(ip -n $sw1 -j -p link show br0.10 | jq -r '.[]["address"]') 632 sw2_mac=$(ip -n $sw2 -j -p link show br0.10 | jq -r '.[]["address"]') 633 634 run_cmd "bridge -n $sw1 fdb replace $sw2_mac dev swp1 master static vlan 10" 635 run_cmd "bridge -n $sw2 fdb replace $sw1_mac dev swp1 master static vlan 10" 636 637 run_cmd "ip -n $sw1 neigh replace 192.0.2.66 lladdr $sw2_mac nud perm dev br0.10" 638 run_cmd "ip -n $sw2 neigh replace 192.0.2.65 lladdr $sw1_mac nud perm dev br0.10" 639 640 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 641 run_cmd "ip -n $sw2 nexthop replace id 1 via 192.0.2.33 fdb" 642 run_cmd "ip -n $sw1 nexthop replace id 10 group 1 fdb" 643 run_cmd "ip -n $sw2 nexthop replace id 10 group 1 fdb" 644 645 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 646 run_cmd "bridge -n $sw2 link set dev swp1 backup_port vx0" 647 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 648 run_cmd "bridge -n $sw2 link set dev swp1 backup_nhid 10" 649 650 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 651 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled 652 run_cmd "ip -n $sw2 link set dev swp1 carrier off" 653 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw2 swp1 disabled 654 655 run_cmd "ip netns exec $sw1 ping -i 0.1 -c 10 -w $PING_TIMEOUT 192.0.2.66" 656 log_test $? 0 "Ping with backup nexthop ID" 657 658 # Reset the backup nexthop ID to 0 and check that ping fails. 659 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 0" 660 run_cmd "bridge -n $sw2 link set dev swp1 backup_nhid 0" 661 662 run_cmd "ip netns exec $sw1 ping -i 0.1 -c 10 -w $PING_TIMEOUT 192.0.2.66" 663 log_test $? 1 "Ping after disabling backup nexthop ID" 664} 665 666backup_nhid_add_del_loop() 667{ 668 while true; do 669 ip -n $sw1 nexthop del id 10 670 ip -n $sw1 nexthop replace id 10 group 1/2 fdb 671 done >/dev/null 2>&1 672} 673 674backup_nhid_torture() 675{ 676 local dmac=00:11:22:33:44:55 677 local smac=00:aa:bb:cc:dd:ee 678 local pid1 679 local pid2 680 local pid3 681 682 echo 683 echo "Backup nexthop ID - torture test" 684 echo "--------------------------------" 685 686 # Continuously send traffic through the backup nexthop while adding and 687 # deleting the group. The test is considered successful if nothing 688 # crashed. 689 690 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb" 691 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb" 692 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb" 693 694 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10" 695 696 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0" 697 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10" 698 run_cmd "ip -n $sw1 link set dev swp1 carrier off" 699 700 backup_nhid_add_del_loop & 701 pid1=$! 702 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 & 703 pid2=$! 704 705 sleep 30 706 kill -9 $pid1 $pid2 707 wait $pid1 $pid2 2>/dev/null 708 709 log_test 0 0 "Torture test" 710} 711 712################################################################################ 713# Usage 714 715usage() 716{ 717 cat <<EOF 718usage: ${0##*/} OPTS 719 720 -t <test> Test(s) to run (default: all) 721 (options: $TESTS) 722 -p Pause on fail 723 -P Pause after each test before cleanup 724 -v Verbose mode (show commands and output) 725 -w Timeout for ping 726EOF 727} 728 729################################################################################ 730# Main 731 732trap cleanup EXIT 733 734while getopts ":t:pPvhw:" opt; do 735 case $opt in 736 t) TESTS=$OPTARG;; 737 p) PAUSE_ON_FAIL=yes;; 738 P) PAUSE=yes;; 739 v) VERBOSE=$(($VERBOSE + 1));; 740 w) PING_TIMEOUT=$OPTARG;; 741 h) usage; exit 0;; 742 *) usage; exit 1;; 743 esac 744done 745 746# Make sure we don't pause twice. 747[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 748 749if [ "$(id -u)" -ne 0 ];then 750 echo "SKIP: Need root privileges" 751 exit $ksft_skip; 752fi 753 754if [ ! -x "$(command -v ip)" ]; then 755 echo "SKIP: Could not run test without ip tool" 756 exit $ksft_skip 757fi 758 759if [ ! -x "$(command -v bridge)" ]; then 760 echo "SKIP: Could not run test without bridge tool" 761 exit $ksft_skip 762fi 763 764if [ ! -x "$(command -v tc)" ]; then 765 echo "SKIP: Could not run test without tc tool" 766 exit $ksft_skip 767fi 768 769if [ ! -x "$(command -v mausezahn)" ]; then 770 echo "SKIP: Could not run test without mausezahn tool" 771 exit $ksft_skip 772fi 773 774if [ ! -x "$(command -v jq)" ]; then 775 echo "SKIP: Could not run test without jq tool" 776 exit $ksft_skip 777fi 778 779bridge link help 2>&1 | grep -q "backup_nhid" 780if [ $? -ne 0 ]; then 781 echo "SKIP: iproute2 bridge too old, missing backup nexthop ID support" 782 exit $ksft_skip 783fi 784 785# Start clean. 786cleanup 787 788for t in $TESTS 789do 790 setup; $t; cleanup; 791done 792 793if [ "$TESTS" != "none" ]; then 794 printf "\nTests passed: %3d\n" ${nsuccess} 795 printf "Tests failed: %3d\n" ${nfail} 796fi 797 798exit $ret 799