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