1# $NetBSD: t_bridge.sh,v 1.21 2024/09/03 08:01:38 ozaki-r Exp $ 2# 3# Copyright (c) 2014 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28SOCK1=unix://commsock1 29SOCK2=unix://commsock2 30SOCK3=unix://commsock3 31IP1=10.0.0.1 32IP2=10.0.0.2 33IP61=fc00::1 34IP62=fc00::2 35IPBR1=10.0.0.11 36IPBR2=10.0.0.12 37IP6BR1=fc00::11 38IP6BR2=fc00::12 39 40DEBUG=${DEBUG:-false} 41TIMEOUT=5 42 43setup_endpoint() 44{ 45 sock=${1} 46 addr=${2} 47 bus=${3} 48 mode=${4} 49 50 rump_server_add_iface $sock shmif0 $bus 51 export RUMP_SERVER=${sock} 52 if [ $mode = "ipv6" ]; then 53 atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr} 54 else 55 atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00 56 fi 57 58 atf_check -s exit:0 rump.ifconfig shmif0 up 59 $DEBUG && rump.ifconfig shmif0 60} 61 62test_endpoint() 63{ 64 sock=${1} 65 addr=${2} 66 bus=${3} 67 mode=${4} 68 69 export RUMP_SERVER=${sock} 70 atf_check -s exit:0 -o match:shmif0 rump.ifconfig 71 if [ $mode = "ipv6" ]; then 72 atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${addr} 73 else 74 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${addr} 75 fi 76} 77 78test_setup() 79{ 80 test_endpoint $SOCK1 $IP1 bus1 ipv4 81 test_endpoint $SOCK3 $IP2 bus2 ipv4 82 83 export RUMP_SERVER=$SOCK2 84 atf_check -s exit:0 -o match:shmif0 rump.ifconfig 85 atf_check -s exit:0 -o match:shmif1 rump.ifconfig 86} 87 88test_setup6() 89{ 90 test_endpoint $SOCK1 $IP61 bus1 ipv6 91 test_endpoint $SOCK3 $IP62 bus2 ipv6 92 93 export RUMP_SERVER=$SOCK2 94 atf_check -s exit:0 -o match:shmif0 rump.ifconfig 95 atf_check -s exit:0 -o match:shmif1 rump.ifconfig 96} 97 98setup_bridge_server() 99{ 100 101 rump_server_add_iface $SOCK2 shmif0 bus1 102 rump_server_add_iface $SOCK2 shmif1 bus2 103 export RUMP_SERVER=$SOCK2 104 atf_check -s exit:0 rump.ifconfig shmif0 up 105 atf_check -s exit:0 rump.ifconfig shmif1 up 106} 107 108setup() 109{ 110 111 rump_server_start $SOCK1 bridge 112 rump_server_start $SOCK2 bridge 113 rump_server_start $SOCK3 bridge 114 115 setup_endpoint $SOCK1 $IP1 bus1 ipv4 116 setup_endpoint $SOCK3 $IP2 bus2 ipv4 117 setup_bridge_server 118} 119 120setup6() 121{ 122 123 rump_server_start $SOCK1 netinet6 bridge 124 rump_server_start $SOCK2 netinet6 bridge 125 rump_server_start $SOCK3 netinet6 bridge 126 127 setup_endpoint $SOCK1 $IP61 bus1 ipv6 128 setup_endpoint $SOCK3 $IP62 bus2 ipv6 129 setup_bridge_server 130} 131 132setup_bridge() 133{ 134 export RUMP_SERVER=$SOCK2 135 rump_server_add_iface $SOCK2 bridge0 136 atf_check -s exit:0 rump.ifconfig bridge0 up 137 138 export LD_PRELOAD=/usr/lib/librumphijack.so 139 atf_check -s exit:0 /sbin/brconfig bridge0 add shmif0 140 atf_check -s exit:0 /sbin/brconfig bridge0 add shmif1 141 /sbin/brconfig bridge0 142 unset LD_PRELOAD 143 rump.ifconfig shmif0 144 rump.ifconfig shmif1 145} 146 147setup_member_ip() 148{ 149 export RUMP_SERVER=$SOCK2 150 export LD_PRELOAD=/usr/lib/librumphijack.so 151 atf_check -s exit:0 rump.ifconfig shmif0 $IPBR1/24 152 atf_check -s exit:0 rump.ifconfig shmif1 $IPBR2/24 153 atf_check -s exit:0 rump.ifconfig -w 10 154 /sbin/brconfig bridge0 155 unset LD_PRELOAD 156 rump.ifconfig shmif0 157 rump.ifconfig shmif1 158} 159 160setup_member_ip6() 161{ 162 export RUMP_SERVER=$SOCK2 163 export LD_PRELOAD=/usr/lib/librumphijack.so 164 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6BR1 165 atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6BR2 166 atf_check -s exit:0 rump.ifconfig -w 10 167 /sbin/brconfig bridge0 168 unset LD_PRELOAD 169 rump.ifconfig shmif0 170 rump.ifconfig shmif1 171} 172 173teardown_bridge() 174{ 175 export RUMP_SERVER=$SOCK2 176 export LD_PRELOAD=/usr/lib/librumphijack.so 177 /sbin/brconfig bridge0 178 atf_check -s exit:0 /sbin/brconfig bridge0 delete shmif0 179 atf_check -s exit:0 /sbin/brconfig bridge0 delete shmif1 180 /sbin/brconfig bridge0 181 unset LD_PRELOAD 182 rump.ifconfig shmif0 183 rump.ifconfig shmif1 184} 185 186test_setup_bridge() 187{ 188 export RUMP_SERVER=$SOCK2 189 export LD_PRELOAD=/usr/lib/librumphijack.so 190 atf_check -s exit:0 -o match:shmif0 /sbin/brconfig bridge0 191 atf_check -s exit:0 -o match:shmif1 /sbin/brconfig bridge0 192 /sbin/brconfig bridge0 193 unset LD_PRELOAD 194} 195 196down_up_interfaces() 197{ 198 export RUMP_SERVER=$SOCK1 199 rump.ifconfig shmif0 down 200 rump.ifconfig shmif0 up 201 export RUMP_SERVER=$SOCK3 202 rump.ifconfig shmif0 down 203 rump.ifconfig shmif0 up 204} 205 206test_ping_failure() 207{ 208 export RUMP_SERVER=$SOCK1 209 atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2 210 export RUMP_SERVER=$SOCK3 211 atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1 212} 213 214test_ping_success() 215{ 216 export RUMP_SERVER=$SOCK1 217 rump.ifconfig -v shmif0 218 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2 219 rump.ifconfig -v shmif0 220 221 export RUMP_SERVER=$SOCK3 222 rump.ifconfig -v shmif0 223 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1 224 rump.ifconfig -v shmif0 225} 226 227test_ping6_failure() 228{ 229 export RUMP_SERVER=$SOCK1 230 atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62 231 export RUMP_SERVER=$SOCK3 232 atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61 233} 234 235test_ping6_success() 236{ 237 export RUMP_SERVER=$SOCK1 238 rump.ifconfig -v shmif0 239 atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62 240 rump.ifconfig -v shmif0 241 242 export RUMP_SERVER=$SOCK3 243 rump.ifconfig -v shmif0 244 atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61 245 rump.ifconfig -v shmif0 246} 247 248test_ping_member() 249{ 250 export RUMP_SERVER=$SOCK1 251 rump.ifconfig -v shmif0 252 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1 253 rump.ifconfig -v shmif0 254 # Test for PR#48104 255 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2 256 rump.ifconfig -v shmif0 257 258 export RUMP_SERVER=$SOCK3 259 rump.ifconfig -v shmif0 260 # Test for PR#48104 261 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1 262 rump.ifconfig -v shmif0 263 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2 264 rump.ifconfig -v shmif0 265} 266 267test_ping6_member() 268{ 269 export RUMP_SERVER=$SOCK1 270 rump.ifconfig -v shmif0 271 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1 272 rump.ifconfig -v shmif0 273 # Test for PR#48104 274 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2 275 rump.ifconfig -v shmif0 276 277 export RUMP_SERVER=$SOCK3 278 rump.ifconfig -v shmif0 279 # Test for PR#48104 280 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1 281 rump.ifconfig -v shmif0 282 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2 283 rump.ifconfig -v shmif0 284} 285 286test_create_destroy() 287{ 288 289 rump_server_start $SOCK1 bridge 290 291 test_create_destroy_common $SOCK1 bridge0 292} 293 294test_ipv4() 295{ 296 setup 297 test_setup 298 299 # Enable once PR kern/49219 is fixed 300 #test_ping_failure 301 302 setup_bridge 303 sleep 1 304 test_setup_bridge 305 test_ping_success 306 307 teardown_bridge 308 test_ping_failure 309 310 rump_server_destroy_ifaces 311} 312 313test_ipv6() 314{ 315 setup6 316 test_setup6 317 318 test_ping6_failure 319 320 setup_bridge 321 sleep 1 322 test_setup_bridge 323 test_ping6_success 324 325 teardown_bridge 326 test_ping6_failure 327 328 rump_server_destroy_ifaces 329} 330 331test_member_ipv4() 332{ 333 setup 334 test_setup 335 336 # Enable once PR kern/49219 is fixed 337 #test_ping_failure 338 339 setup_bridge 340 sleep 1 341 test_setup_bridge 342 test_ping_success 343 344 setup_member_ip 345 test_ping_member 346 347 teardown_bridge 348 test_ping_failure 349 350 rump_server_destroy_ifaces 351} 352 353test_member_ipv6() 354{ 355 setup6 356 test_setup6 357 358 test_ping6_failure 359 360 setup_bridge 361 sleep 1 362 test_setup_bridge 363 test_ping6_success 364 365 setup_member_ip6 366 test_ping6_member 367 368 teardown_bridge 369 test_ping6_failure 370 371 rump_server_destroy_ifaces 372} 373 374BUS_SHMIF0=./bus0 375BUS_SHMIF1=./bus1 376BUS_SHMIF2=./bus2 377 378unpack_file() 379{ 380 381 atf_check -s exit:0 uudecode $(atf_get_srcdir)/${1}.uue 382} 383 384reset_if_stats() 385{ 386 387 for ifname in shmif0 shmif1 shmif2 388 do 389 atf_check -s exit:0 -o ignore rump.ifconfig -z $ifname 390 done 391} 392 393test_protection() 394{ 395 396 unpack_file unicast.pcap 397 unpack_file broadcast.pcap 398 399 rump_server_start $SOCK1 bridge 400 rump_server_add_iface $SOCK1 shmif0 $BUS_SHMIF0 401 rump_server_add_iface $SOCK1 shmif1 $BUS_SHMIF1 402 rump_server_add_iface $SOCK1 shmif2 $BUS_SHMIF2 403 404 export RUMP_SERVER=$SOCK1 405 atf_check -s exit:0 rump.ifconfig shmif0 up 406 atf_check -s exit:0 rump.ifconfig shmif1 up 407 atf_check -s exit:0 rump.ifconfig shmif2 up 408 409 atf_check -s exit:0 rump.ifconfig bridge0 create 410 atf_check -s exit:0 rump.ifconfig bridge0 up 411 412 atf_check -s exit:0 $HIJACKING brconfig bridge0 add shmif0 add shmif1 add shmif2 413 $DEBUG && rump.ifconfig 414 415 # Protected interfaces: - 416 # Learning: - 417 # Input: unicast through shmif0 418 # Output: shmif1, shmif2 419 reset_if_stats 420 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0} 421 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0 422 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1 423 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif2 424 $DEBUG && rump.ifconfig -v bridge0 425 426 # Protected interfaces: - 427 # Learning: - 428 # Input: broadcast through shmif0 429 # Output: shmif1, shmif2 430 reset_if_stats 431 atf_check -s exit:0 -o ignore shmif_pcapin broadcast.pcap ${BUS_SHMIF0} 432 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0 433 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1 434 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif2 435 $DEBUG && rump.ifconfig -v bridge0 436 437 # Protect shmif0 and shmif2 438 atf_check -s exit:0 $HIJACKING brconfig bridge0 protect shmif0 439 atf_check -s exit:0 $HIJACKING brconfig bridge0 protect shmif2 440 atf_check -s exit:0 \ 441 -o match:"shmif0.+PROTECTED" \ 442 -o match:"shmif2.+PROTECTED" \ 443 -o not-match:"shmif1.+PROTECTED" \ 444 $HIJACKING brconfig bridge0 445 446 # Protected interfaces: shmif0 shmif2 447 # Learning: - 448 # Input: unicast through shmif0 449 # Output: shmif1 450 reset_if_stats 451 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0} 452 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0 453 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1 454 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif2 455 $DEBUG && rump.ifconfig -v bridge0 456 457 # Protected interfaces: shmif0 shmif2 458 # Learning: - 459 # Input: broadcast through shmif0 460 # Output: shmif1 461 reset_if_stats 462 atf_check -s exit:0 -o ignore shmif_pcapin broadcast.pcap ${BUS_SHMIF0} 463 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0 464 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1 465 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif2 466 $DEBUG && rump.ifconfig -v bridge0 467 468 # Insert a route 00:aa:aa:aa:aa:aa shmif2 to test forwarding path of known-unicast-frame 469 atf_check -s exit:0 $HIJACKING brconfig bridge0 static shmif2 00:aa:aa:aa:aa:aa 470 atf_check -s exit:0 -o match:'00:aa:aa:aa:aa:aa shmif2 0 flags=1<STATIC>' \ 471 $HIJACKING brconfig bridge0 472 $DEBUG && $HIJACKING brconfig bridge0 473 474 # Protected interfaces: shmif0 shmif2 475 # Learning: 00:aa:aa:aa:aa:aa shmif2 476 # Input: broadcast through shmif0 477 # Output: - 478 reset_if_stats 479 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0} 480 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0 481 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif1 482 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif2 483 $DEBUG && rump.ifconfig -v bridge0 484 485 # Unprotect shmif2 486 atf_check -s exit:0 $HIJACKING brconfig bridge0 -protect shmif2 487 atf_check -s exit:0 \ 488 -o match:"shmif0.+PROTECTED" \ 489 -o not-match:"shmif2.+PROTECTED" \ 490 -o not-match:"shmif1.+PROTECTED" \ 491 $HIJACKING brconfig bridge0 492 493 # Protected interfaces: shmif0 494 # Learning: 00:aa:aa:aa:aa:aa shmif2 495 # Input: broadcast through shmif0 496 # Output: shmif2 497 reset_if_stats 498 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0} 499 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0 500 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif1 501 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif2 502 $DEBUG && rump.ifconfig -v bridge0 503 504 rump_server_destroy_ifaces 505} 506 507add_test() 508{ 509 local name=$1 510 local desc="$2" 511 512 atf_test_case "bridge_${name}" cleanup 513 eval "bridge_${name}_head() { 514 atf_set descr \"${desc}\" 515 atf_set require.progs rump_server 516 } 517 bridge_${name}_body() { 518 test_${name} 519 } 520 bridge_${name}_cleanup() { 521 \$DEBUG && dump 522 cleanup 523 }" 524 atf_add_test_case "bridge_${name}" 525} 526 527atf_init_test_cases() 528{ 529 530 add_test create_destroy "Tests creating/destroying bridge interfaces" 531 add_test ipv4 "Does basic if_bridge tests (IPv4)" 532 add_test ipv6 "Does basic if_bridge tests (IPv6)" 533 add_test member_ipv4 "Tests if_bridge with members with an IP address (IPv4)" 534 add_test member_ipv6 "Tests if_bridge with members with an IP address (IPv6)" 535 add_test protection "Tests interface protection" 536} 537