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 28 SOCK1=unix://commsock1 29 SOCK2=unix://commsock2 30 SOCK3=unix://commsock3 31 IP1=10.0.0.1 32 IP2=10.0.0.2 33 IP61=fc00::1 34 IP62=fc00::2 35 IPBR1=10.0.0.11 36 IPBR2=10.0.0.12 37 IP6BR1=fc00::11 38 IP6BR2=fc00::12 39 40 DEBUG=${DEBUG:-false} 41 TIMEOUT=5 42 43 setup_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 62 test_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 78 test_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 88 test_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 98 setup_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 108 setup() 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 120 setup6() 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 132 setup_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 147 setup_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 160 setup_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 173 teardown_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 186 test_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 196 down_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 206 test_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 214 test_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 227 test_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 235 test_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 248 test_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 267 test_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 286 test_create_destroy() 287 { 288 289 rump_server_start $SOCK1 bridge 290 291 test_create_destroy_common $SOCK1 bridge0 292 } 293 294 test_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 313 test_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 331 test_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 353 test_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 374 BUS_SHMIF0=./bus0 375 BUS_SHMIF1=./bus1 376 BUS_SHMIF2=./bus2 377 378 unpack_file() 379 { 380 381 atf_check -s exit:0 uudecode $(atf_get_srcdir)/${1}.uue 382 } 383 384 reset_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 393 test_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 507 add_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 527 atf_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