1# $FreeBSD$ 2# 3# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4# 5# Copyright (c) 2020 The FreeBSD Foundation 6# 7# This software was developed by Kristof Provost under sponsorship 8# from the FreeBSD Foundation. 9# 10# Redistribution and use in source and binary forms, with or without 11# modification, are permitted provided that the following conditions 12# are met: 13# 1. Redistributions of source code must retain the above copyright 14# notice, this list of conditions and the following disclaimer. 15# 2. Redistributions in binary form must reproduce the above copyright 16# notice, this list of conditions and the following disclaimer in the 17# documentation and/or other materials provided with the distribution. 18# 19# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29# SUCH DAMAGE. 30 31. $(atf_get_srcdir)/../common/vnet.subr 32 33atf_test_case "bridge_transmit_ipv4_unicast" "cleanup" 34bridge_transmit_ipv4_unicast_head() 35{ 36 atf_set descr 'bridge_transmit_ipv4_unicast bridging test' 37 atf_set require.user root 38} 39 40bridge_transmit_ipv4_unicast_body() 41{ 42 vnet_init 43 44 epair_alcatraz=$(vnet_mkepair) 45 epair_singsing=$(vnet_mkepair) 46 47 vnet_mkjail alcatraz ${epair_alcatraz}b 48 vnet_mkjail singsing ${epair_singsing}b 49 50 jexec alcatraz ifconfig ${epair_alcatraz}b 192.0.2.1/24 up 51 jexec singsing ifconfig ${epair_singsing}b 192.0.2.2/24 up 52 53 bridge=$(vnet_mkbridge) 54 55 ifconfig ${bridge} up 56 ifconfig ${epair_alcatraz}a up 57 ifconfig ${epair_singsing}a up 58 ifconfig ${bridge} addm ${epair_alcatraz}a 59 ifconfig ${bridge} addm ${epair_singsing}a 60 61 atf_check -s exit:0 -o ignore jexec alcatraz ping -c 3 -t 1 192.0.2.2 62 atf_check -s exit:0 -o ignore jexec singsing ping -c 3 -t 1 192.0.2.1 63} 64 65bridge_transmit_ipv4_unicast_cleanup() 66{ 67 vnet_cleanup 68} 69 70atf_test_case "stp" "cleanup" 71stp_head() 72{ 73 atf_set descr 'Spanning tree test' 74 atf_set require.user root 75} 76 77stp_body() 78{ 79 vnet_init 80 81 epair_one=$(vnet_mkepair) 82 epair_two=$(vnet_mkepair) 83 bridge_a=$(vnet_mkbridge) 84 bridge_b=$(vnet_mkbridge) 85 86 vnet_mkjail a ${bridge_a} ${epair_one}a ${epair_two}a 87 vnet_mkjail b ${bridge_b} ${epair_one}b ${epair_two}b 88 89 jexec a ifconfig ${epair_one}a up 90 jexec a ifconfig ${epair_two}a up 91 jexec a ifconfig ${bridge_a} addm ${epair_one}a 92 jexec a ifconfig ${bridge_a} addm ${epair_two}a 93 94 jexec b ifconfig ${epair_one}b up 95 jexec b ifconfig ${epair_two}b up 96 jexec b ifconfig ${bridge_b} addm ${epair_one}b 97 jexec b ifconfig ${bridge_b} addm ${epair_two}b 98 99 jexec a ifconfig ${bridge_a} 192.0.2.1/24 100 101 # Enable spanning tree 102 jexec a ifconfig ${bridge_a} stp ${epair_one}a 103 jexec a ifconfig ${bridge_a} stp ${epair_two}a 104 jexec b ifconfig ${bridge_b} stp ${epair_one}b 105 jexec b ifconfig ${bridge_b} stp ${epair_two}b 106 107 jexec b ifconfig ${bridge_b} up 108 jexec a ifconfig ${bridge_a} up 109 110 # Give STP time to do its thing 111 sleep 5 112 113 a_discard=$(jexec a ifconfig ${bridge_a} | grep discarding) 114 b_discard=$(jexec b ifconfig ${bridge_b} | grep discarding) 115 116 if [ -z "${a_discard}" ] && [ -z "${b_discard}" ] 117 then 118 atf_fail "STP failed to detect bridging loop" 119 fi 120 121 # We must also have at least some forwarding interfaces 122 a_forwarding=$(jexec a ifconfig ${bridge_a} | grep forwarding) 123 b_forwarding=$(jexec b ifconfig ${bridge_b} | grep forwarding) 124 125 if [ -z "${a_forwarding}" ] && [ -z "${b_forwarding}" ] 126 then 127 atf_fail "STP failed to detect bridging loop" 128 fi 129} 130 131stp_cleanup() 132{ 133 vnet_cleanup 134} 135 136atf_test_case "stp_vlan" "cleanup" 137stp_vlan_head() 138{ 139 atf_set descr 'Spanning tree on VLAN test' 140 atf_set require.user root 141} 142 143stp_vlan_body() 144{ 145 vnet_init 146 147 epair_one=$(vnet_mkepair) 148 epair_two=$(vnet_mkepair) 149 bridge_a=$(vnet_mkbridge) 150 bridge_b=$(vnet_mkbridge) 151 152 vnet_mkjail a ${bridge_a} ${epair_one}a ${epair_two}a 153 vnet_mkjail b ${bridge_b} ${epair_one}b ${epair_two}b 154 155 jexec a ifconfig ${epair_one}a up 156 jexec a ifconfig ${epair_two}a up 157 vlan_a_one=$(jexec a ifconfig vlan create vlandev ${epair_one}a vlan 42) 158 vlan_a_two=$(jexec a ifconfig vlan create vlandev ${epair_two}a vlan 42) 159 jexec a ifconfig ${vlan_a_one} up 160 jexec a ifconfig ${vlan_a_two} up 161 jexec a ifconfig ${bridge_a} addm ${vlan_a_one} 162 jexec a ifconfig ${bridge_a} addm ${vlan_a_two} 163 164 jexec b ifconfig ${epair_one}b up 165 jexec b ifconfig ${epair_two}b up 166 vlan_b_one=$(jexec b ifconfig vlan create vlandev ${epair_one}b vlan 42) 167 vlan_b_two=$(jexec b ifconfig vlan create vlandev ${epair_two}b vlan 42) 168 jexec b ifconfig ${vlan_b_one} up 169 jexec b ifconfig ${vlan_b_two} up 170 jexec b ifconfig ${bridge_b} addm ${vlan_b_one} 171 jexec b ifconfig ${bridge_b} addm ${vlan_b_two} 172 173 jexec a ifconfig ${bridge_a} 192.0.2.1/24 174 175 # Enable spanning tree 176 jexec a ifconfig ${bridge_a} stp ${vlan_a_one} 177 jexec a ifconfig ${bridge_a} stp ${vlan_a_two} 178 jexec b ifconfig ${bridge_b} stp ${vlan_b_one} 179 jexec b ifconfig ${bridge_b} stp ${vlan_b_two} 180 181 jexec b ifconfig ${bridge_b} up 182 jexec a ifconfig ${bridge_a} up 183 184 # Give STP time to do its thing 185 sleep 5 186 187 a_discard=$(jexec a ifconfig ${bridge_a} | grep discarding) 188 b_discard=$(jexec b ifconfig ${bridge_b} | grep discarding) 189 190 if [ -z "${a_discard}" ] && [ -z "${b_discard}" ] 191 then 192 atf_fail "STP failed to detect bridging loop" 193 fi 194 195 # We must also have at least some forwarding interfaces 196 a_forwarding=$(jexec a ifconfig ${bridge_a} | grep forwarding) 197 b_forwarding=$(jexec b ifconfig ${bridge_b} | grep forwarding) 198 199 if [ -z "${a_forwarding}" ] && [ -z "${b_forwarding}" ] 200 then 201 atf_fail "STP failed to detect bridging loop" 202 fi 203} 204 205stp_vlan_cleanup() 206{ 207 vnet_cleanup 208} 209 210atf_test_case "static" "cleanup" 211static_head() 212{ 213 atf_set descr 'Bridge static address test' 214 atf_set require.user root 215} 216 217static_body() 218{ 219 vnet_init 220 221 epair=$(vnet_mkepair) 222 bridge=$(vnet_mkbridge) 223 224 vnet_mkjail one ${bridge} ${epair}a 225 226 ifconfig ${epair}b up 227 228 jexec one ifconfig ${bridge} up 229 jexec one ifconfig ${epair}a up 230 jexec one ifconfig ${bridge} addm ${epair}a 231 232 # Wrong interface 233 atf_check -s exit:1 -o ignore -e ignore \ 234 jexec one ifconfig ${bridge} static ${epair}b 00:01:02:03:04:05 235 236 # Bad address format 237 atf_check -s exit:1 -o ignore -e ignore \ 238 jexec one ifconfig ${bridge} static ${epair}a 00:01:02:03:04 239 240 # Correct add 241 atf_check -s exit:0 -o ignore \ 242 jexec one ifconfig ${bridge} static ${epair}a 00:01:02:03:04:05 243 244 # List addresses 245 atf_check -s exit:0 -o ignore \ 246 jexec one ifconfig ${bridge} addr 247 248 # Delete with bad address format 249 atf_check -s exit:1 -o ignore -e ignore \ 250 jexec one ifconfig ${bridge} deladdr 00:01:02:03:04 251 252 # Delete with unlisted address 253 atf_check -s exit:1 -o ignore -e ignore \ 254 jexec one ifconfig ${bridge} deladdr 00:01:02:03:04:06 255 256 # Correct delete 257 atf_check -s exit:0 -o ignore \ 258 jexec one ifconfig ${bridge} deladdr 00:01:02:03:04:05 259} 260 261static_cleanup() 262{ 263 vnet_cleanup 264} 265 266atf_test_case "span" "cleanup" 267span_head() 268{ 269 atf_set descr 'Bridge span test' 270 atf_set require.user root 271} 272 273span_body() 274{ 275 set -x 276 vnet_init 277 278 if [ "$(atf_config_get ci false)" = "true" ]; then 279 atf_skip "https://bugs.freebsd.org/260461" 280 fi 281 282 epair=$(vnet_mkepair) 283 epair_span=$(vnet_mkepair) 284 bridge=$(vnet_mkbridge) 285 286 vnet_mkjail one ${bridge} ${epair}a ${epair_span}a 287 288 ifconfig ${epair}b up 289 ifconfig ${epair_span}b up 290 291 jexec one ifconfig ${bridge} up 292 jexec one ifconfig ${epair}a up 293 jexec one ifconfig ${epair_span}a up 294 jexec one ifconfig ${bridge} addm ${epair}a 295 296 jexec one ifconfig ${bridge} span ${epair_span}a 297 jexec one ifconfig ${bridge} 192.0.2.1/24 298 299 # Send some traffic through the span 300 jexec one ping -c 1 -t 1 192.0.2.2 301 302 # Check that we see the traffic on the span interface 303 atf_check -s exit:0 \ 304 $(atf_get_srcdir)/../netpfil/common/pft_ping.py \ 305 --sendif ${epair}b \ 306 --to 192.0.2.2 \ 307 --recvif ${epair_span}b 308 309 jexec one ifconfig ${bridge} -span ${epair_span}a 310 311 # And no more traffic after we remove the span 312 atf_check -s exit:1 \ 313 $(atf_get_srcdir)/../netpfil/common/pft_ping.py \ 314 --sendif ${epair}b \ 315 --to 192.0.2.2 \ 316 --recvif ${epair_span}b 317} 318 319span_cleanup() 320{ 321 vnet_cleanup 322} 323 324atf_test_case "delete_with_members" "cleanup" 325delete_with_members_head() 326{ 327 atf_set descr 'Delete a bridge which still has member interfaces' 328 atf_set require.user root 329} 330 331delete_with_members_body() 332{ 333 vnet_init 334 335 bridge=$(vnet_mkbridge) 336 epair=$(vnet_mkepair) 337 338 ifconfig ${bridge} 192.0.2.1/24 up 339 ifconfig ${epair}a up 340 ifconfig ${bridge} addm ${epair}a 341 342 ifconfig ${bridge} destroy 343} 344 345delete_with_members_cleanup() 346{ 347 vnet_cleanup 348} 349 350atf_test_case "mac_conflict" "cleanup" 351mac_conflict_head() 352{ 353 atf_set descr 'Ensure that bridges in different jails get different mac addresses' 354 atf_set require.user root 355} 356 357mac_conflict_body() 358{ 359 vnet_init 360 361 epair=$(vnet_mkepair) 362 363 # Ensure the bridge module is loaded so jails can use it. 364 tmpbridge=$(vnet_mkbridge) 365 366 vnet_mkjail bridge_mac_conflict_one ${epair}a 367 vnet_mkjail bridge_mac_conflict_two ${epair}b 368 369 jexec bridge_mac_conflict_one ifconfig bridge create 370 jexec bridge_mac_conflict_one ifconfig bridge0 192.0.2.1/24 up \ 371 addm ${epair}a 372 jexec bridge_mac_conflict_one ifconfig ${epair}a up 373 374 jexec bridge_mac_conflict_two ifconfig bridge create 375 jexec bridge_mac_conflict_two ifconfig bridge0 192.0.2.2/24 up \ 376 addm ${epair}b 377 jexec bridge_mac_conflict_two ifconfig ${epair}b up 378 379 atf_check -s exit:0 -o ignore \ 380 jexec bridge_mac_conflict_one ping -c 3 192.0.2.2 381} 382 383mac_conflict_cleanup() 384{ 385 vnet_cleanup 386} 387 388atf_test_case "inherit_mac" "cleanup" 389inherit_mac_head() 390{ 391 atf_set descr 'Bridge inherit_mac test, #216510' 392 atf_set require.user root 393} 394 395inherit_mac_body() 396{ 397 vnet_init 398 399 bridge=$(vnet_mkbridge) 400 epair=$(vnet_mkepair) 401 vnet_mkjail one ${bridge} ${epair}a 402 403 jexec one sysctl net.link.bridge.inherit_mac=1 404 405 # Attempt to provoke the panic described in #216510 406 jexec one ifconfig ${bridge} 192.0.0.1/24 up 407 jexec one ifconfig ${bridge} addm ${epair}a 408} 409 410inherit_mac_cleanup() 411{ 412 vnet_cleanup 413} 414 415atf_test_case "stp_validation" "cleanup" 416stp_validation_head() 417{ 418 atf_set descr 'Check STP validation' 419 atf_set require.user root 420 atf_set require.progs scapy 421} 422 423stp_validation_body() 424{ 425 vnet_init 426 427 epair_one=$(vnet_mkepair) 428 epair_two=$(vnet_mkepair) 429 bridge=$(vnet_mkbridge) 430 431 ifconfig ${bridge} up 432 ifconfig ${bridge} addm ${epair_one}a addm ${epair_two}a 433 ifconfig ${bridge} stp ${epair_one}a stp ${epair_two}a 434 435 ifconfig ${epair_one}a up 436 ifconfig ${epair_one}b up 437 ifconfig ${epair_two}a up 438 ifconfig ${epair_two}b up 439 440 # Wait until the interfaces are no longer discarding 441 while ifconfig ${bridge} | grep 'state discarding' >/dev/null 442 do 443 sleep 1 444 done 445 446 # Now inject invalid STP BPDUs on epair_one and see if they're repeated 447 # on epair_two 448 atf_check -s exit:0 \ 449 $(atf_get_srcdir)/stp.py \ 450 --sendif ${epair_one}b \ 451 --recvif ${epair_two}b 452} 453 454stp_validation_cleanup() 455{ 456 vnet_cleanup 457} 458 459atf_test_case "gif" "cleanup" 460gif_head() 461{ 462 atf_set descr 'gif as a bridge member' 463 atf_set require.user root 464} 465 466gif_body() 467{ 468 vnet_init 469 470 epair=$(vnet_mkepair) 471 472 vnet_mkjail one ${epair}a 473 vnet_mkjail two ${epair}b 474 475 jexec one sysctl net.link.gif.max_nesting=2 476 jexec two sysctl net.link.gif.max_nesting=2 477 478 jexec one ifconfig ${epair}a 192.0.2.1/24 up 479 jexec two ifconfig ${epair}b 192.0.2.2/24 up 480 481 # Tunnel 482 gif_one=$(jexec one ifconfig gif create) 483 gif_two=$(jexec two ifconfig gif create) 484 485 jexec one ifconfig ${gif_one} tunnel 192.0.2.1 192.0.2.2 486 jexec one ifconfig ${gif_one} up 487 jexec two ifconfig ${gif_two} tunnel 192.0.2.2 192.0.2.1 488 jexec two ifconfig ${gif_two} up 489 490 bridge_one=$(jexec one ifconfig bridge create) 491 bridge_two=$(jexec two ifconfig bridge create) 492 jexec one ifconfig ${bridge_one} 198.51.100.1/24 up 493 jexec one ifconfig ${bridge_one} addm ${gif_one} 494 jexec two ifconfig ${bridge_two} 198.51.100.2/24 up 495 jexec two ifconfig ${bridge_two} addm ${gif_two} 496 497 # Sanity check 498 atf_check -s exit:0 -o ignore \ 499 jexec one ping -c 1 192.0.2.2 500 501 # Test tunnel 502 atf_check -s exit:0 -o ignore \ 503 jexec one ping -c 1 198.51.100.2 504 atf_check -s exit:0 -o ignore \ 505 jexec one ping -c 1 -s 1200 198.51.100.2 506 atf_check -s exit:0 -o ignore \ 507 jexec one ping -c 1 -s 2000 198.51.100.2 508 509 # Higher MTU on the tunnel than on the underlying interface 510 jexec one ifconfig ${epair}a mtu 1000 511 jexec two ifconfig ${epair}b mtu 1000 512 513 atf_check -s exit:0 -o ignore \ 514 jexec one ping -c 1 -s 1200 198.51.100.2 515 atf_check -s exit:0 -o ignore \ 516 jexec one ping -c 1 -s 2000 198.51.100.2 517} 518 519gif_cleanup() 520{ 521 vnet_cleanup 522} 523 524atf_test_case "mtu" "cleanup" 525mtu_head() 526{ 527 atf_set descr 'Bridge MTU changes' 528 atf_set require.user root 529} 530 531get_mtu() 532{ 533 intf=$1 534 535 ifconfig ${intf} ether | awk '$5 == "mtu" { print $6 }' 536} 537 538check_mtu() 539{ 540 intf=$1 541 expected=$2 542 543 mtu=$(get_mtu $intf) 544 if [ $mtu -ne $expected ]; 545 then 546 atf_fail "Expected MTU of $expected on $intf but found $mtu" 547 fi 548} 549 550mtu_body() 551{ 552 vnet_init 553 554 epair=$(vnet_mkepair) 555 gif=$(ifconfig gif create) 556 echo ${gif} >> created_interfaces.lst 557 bridge=$(vnet_mkbridge) 558 559 atf_check -s exit:0 \ 560 ifconfig ${bridge} addm ${epair}a 561 562 ifconfig ${gif} mtu 1500 563 atf_check -s exit:0 \ 564 ifconfig ${bridge} addm ${gif} 565 566 # Changing MTU changes it for all member interfaces 567 atf_check -s exit:0 \ 568 ifconfig ${bridge} mtu 2000 569 570 check_mtu ${bridge} 2000 571 check_mtu ${gif} 2000 572 check_mtu ${epair}a 2000 573 574 # Rejected MTUs mean none of the MTUs change 575 atf_check -s exit:1 -e ignore \ 576 ifconfig ${bridge} mtu 9000 577 578 check_mtu ${bridge} 2000 579 check_mtu ${gif} 2000 580 check_mtu ${epair}a 2000 581 582 # We're not allowed to change the MTU of a member interface 583 atf_check -s exit:1 -e ignore \ 584 ifconfig ${epair}a mtu 1900 585 check_mtu ${epair}a 2000 586 587 # Test adding an interface with a different MTU 588 new_epair=$(vnet_mkepair) 589 check_mtu ${new_epair}a 1500 590 atf_check -s exit:0 -e ignore \ 591 ifconfig ${bridge} addm ${new_epair}a 592 593 check_mtu ${bridge} 2000 594 check_mtu ${gif} 2000 595 check_mtu ${epair}a 2000 596 check_mtu ${new_epair}a 2000 597} 598 599mtu_cleanup() 600{ 601 vnet_cleanup 602} 603 604atf_init_test_cases() 605{ 606 atf_add_test_case "bridge_transmit_ipv4_unicast" 607 atf_add_test_case "stp" 608 atf_add_test_case "stp_vlan" 609 atf_add_test_case "static" 610 atf_add_test_case "span" 611 atf_add_test_case "inherit_mac" 612 atf_add_test_case "delete_with_members" 613 atf_add_test_case "mac_conflict" 614 atf_add_test_case "stp_validation" 615 atf_add_test_case "gif" 616 atf_add_test_case "mtu" 617} 618