1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright 2021 Lutz Donnerhacke 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 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 3. Neither the name of the copyright holder nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 31 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 #include <atf-c.h> 35 #include <errno.h> 36 #include <stdio.h> 37 38 #include <net/ethernet.h> 39 #include <netinet/in.h> 40 #include <netinet/ip.h> 41 #include <netinet/ip6.h> 42 43 #include "util.h" 44 #include <netgraph/ng_bridge.h> 45 46 static void get_tablesize(char const *source, struct ng_mesg *msg, void *ctx); 47 struct gettable 48 { 49 u_int32_t tok; 50 int cnt; 51 }; 52 53 struct frame4 54 { 55 struct ether_header eh; 56 struct ip ip; 57 char data[64]; 58 }; 59 struct frame6 60 { 61 struct ether_header eh; 62 struct ip6_hdr ip; 63 char data[64]; 64 }; 65 66 static struct frame4 msg4 = { 67 .ip.ip_v = 4, 68 .ip.ip_hl = 5, 69 .ip.ip_ttl = 1, 70 .ip.ip_p = 254, 71 .ip.ip_src = {htonl(0x0a00dead)}, 72 .ip.ip_dst = {htonl(0x0a00beef)}, 73 .ip.ip_len = 32, 74 .eh.ether_type = ETHERTYPE_IP, 75 .eh.ether_shost = {2, 4, 6}, 76 .eh.ether_dhost = {2, 4, 6}, 77 }; 78 79 80 ATF_TC(basic); 81 ATF_TC_HEAD(basic, conf) 82 { 83 atf_tc_set_md_var(conf, "require.user", "root"); 84 } 85 86 ATF_TC_BODY(basic, dummy) 87 { 88 ng_counter_t r; 89 struct gettable rm; 90 91 ng_init(); 92 ng_errors(PASS); 93 ng_shutdown("bridge:"); 94 ng_errors(FAIL); 95 96 ng_mkpeer(".", "a", "bridge", "link0"); 97 ng_name("a", "bridge"); 98 ng_connect(".", "b", "bridge:", "link1"); 99 ng_connect(".", "c", "bridge:", "link2"); 100 101 /* do not bounce back */ 102 ng_register_data("a", get_data0); 103 ng_counter_clear(r); 104 msg4.eh.ether_shost[5] = 1; 105 ng_send_data("a", &msg4, sizeof(msg4)); 106 ng_handle_events(50, &r); 107 ATF_CHECK(r[0] == 0); 108 109 /* send to others */ 110 ng_register_data("b", get_data1); 111 ng_register_data("c", get_data2); 112 ng_counter_clear(r); 113 msg4.eh.ether_shost[5] = 1; 114 ng_send_data("a", &msg4, sizeof(msg4)); 115 ng_handle_events(50, &r); 116 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1); 117 118 ng_counter_clear(r); 119 msg4.eh.ether_shost[5] = 2; 120 ng_send_data("b", &msg4, sizeof(msg4)); 121 ng_handle_events(50, &r); 122 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1); 123 124 ng_counter_clear(r); 125 msg4.eh.ether_shost[5] = 3; 126 ng_send_data("c", &msg4, sizeof(msg4)); 127 ng_handle_events(50, &r); 128 ATF_CHECK(r[0] == 1 && r[1] == 1 && r[2] == 0); 129 130 /* send to learned unicast */ 131 ng_counter_clear(r); 132 msg4.eh.ether_shost[5] = 1; 133 msg4.eh.ether_dhost[5] = 3; 134 ng_send_data("a", &msg4, sizeof(msg4)); 135 ng_handle_events(50, &r); 136 ATF_CHECK(r[0] == 0 && r[1] == 0 && r[2] == 1); 137 138 /* inspect mac table */ 139 ng_register_msg(get_tablesize); 140 rm.tok = ng_send_msg("bridge:", "gettable"); 141 rm.cnt = 0; 142 ng_handle_events(50, &rm); 143 ATF_CHECK(rm.cnt == 3); 144 145 /* remove a link */ 146 ng_rmhook(".", "b"); 147 ng_counter_clear(r); 148 msg4.eh.ether_shost[5] = 1; 149 msg4.eh.ether_dhost[5] = 0; 150 ng_send_data("a", &msg4, sizeof(msg4)); 151 ng_handle_events(50, &r); 152 ATF_CHECK(r[0] == 0 && r[1] == 0 && r[2] == 1); 153 154 /* inspect mac table */ 155 ng_register_msg(get_tablesize); 156 rm.tok = ng_send_msg("bridge:", "gettable"); 157 rm.cnt = 0; 158 ng_handle_events(50, &rm); 159 ATF_CHECK(rm.cnt == 2); 160 161 ng_shutdown("bridge:"); 162 } 163 164 ATF_TC(persistence); 165 ATF_TC_HEAD(persistence, conf) 166 { 167 atf_tc_set_md_var(conf, "require.user", "root"); 168 } 169 170 ATF_TC_BODY(persistence, dummy) 171 { 172 ng_init(); 173 ng_errors(PASS); 174 ng_shutdown("bridge:"); 175 ng_errors(FAIL); 176 177 ng_mkpeer(".", "a", "bridge", "link0"); 178 ng_name("a", "bridge"); 179 180 ng_send_msg("bridge:", "setpersistent"); 181 ng_rmhook(".", "a"); 182 183 ng_shutdown("bridge:"); 184 } 185 186 ATF_TC(loop); 187 ATF_TC_HEAD(loop, conf) 188 { 189 atf_tc_set_md_var(conf, "require.user", "root"); 190 } 191 192 ATF_TC_BODY(loop, dummy) 193 { 194 ng_counter_t r; 195 int i; 196 197 ng_init(); 198 ng_errors(PASS); 199 ng_shutdown("bridge1:"); 200 ng_shutdown("bridge2:"); 201 ng_errors(FAIL); 202 203 ng_mkpeer(".", "a", "bridge", "link0"); 204 ng_name("a", "bridge1"); 205 ng_mkpeer(".", "b", "bridge", "link1"); 206 ng_name("b", "bridge2"); 207 208 ng_register_data("a", get_data0); 209 ng_register_data("b", get_data1); 210 211 /*- 212 * Open loop 213 * 214 * /-- bridge1 215 * . < | 216 * \-- bridge2 217 */ 218 ng_connect("bridge1:", "link11", "bridge2:", "link11"); 219 220 ng_counter_clear(r); 221 msg4.eh.ether_shost[5] = 1; 222 ng_send_data("a", &msg4, sizeof(msg4)); 223 ng_handle_events(50, &r); 224 ATF_CHECK(r[0] == 0 && r[1] == 1); 225 226 /*- 227 * Closed loop, DANGEROUS! 228 * 229 * /-- bridge1 -\ 230 * . < | | 231 * \-- bridge2 -/ 232 */ 233 ng_connect("bridge1:", "link12", "bridge2:", "link12"); 234 235 ng_counter_clear(r); 236 msg4.eh.ether_shost[5] = 1; 237 ng_errors(PASS); 238 ng_send_data("a", &msg4, sizeof(msg4)); 239 ATF_CHECK_ERRNO(ELOOP, errno != 0); /* loop might be detected */ 240 ng_errors(FAIL); 241 for (i = 0; i < 10; i++) /* don't run forever */ 242 if (!ng_handle_event(50, &r)) 243 break; 244 ATF_CHECK(r[0] == 0 && r[1] == 1); 245 246 ng_shutdown("bridge1:"); 247 ng_shutdown("bridge2:"); 248 } 249 250 ATF_TC(many_unicasts); 251 ATF_TC_HEAD(many_unicasts, conf) 252 { 253 atf_tc_set_md_var(conf, "require.user", "root"); 254 } 255 256 ATF_TC_BODY(many_unicasts, dummy) 257 { 258 ng_counter_t r; 259 int i; 260 const int HOOKS = 1000; 261 struct gettable rm; 262 263 ng_init(); 264 ng_errors(PASS); 265 ng_shutdown("bridge:"); 266 ng_errors(FAIL); 267 268 ng_mkpeer(".", "a", "bridge", "link0"); 269 ng_name("a", "bridge"); 270 ng_register_data("a", get_data0); 271 272 /* learn MAC */ 273 ng_counter_clear(r); 274 msg4.eh.ether_shost[3] = 0xff; 275 ng_send_data("a", &msg4, sizeof(msg4)); 276 ng_handle_events(50, &r); 277 ATF_CHECK(r[0] == 0); 278 279 /* use learned MAC as destination */ 280 msg4.eh.ether_shost[3] = 0; 281 msg4.eh.ether_dhost[3] = 0xff; 282 283 /* now send */ 284 ng_counter_clear(r); 285 for (i = 1; i <= HOOKS; i++) 286 { 287 char hook[20]; 288 289 snprintf(hook, sizeof(hook), "link%d", i); 290 ng_connect(".", hook, "bridge:", hook); 291 ng_register_data(hook, get_data2); 292 293 msg4.eh.ether_shost[4] = i >> 8; 294 msg4.eh.ether_shost[5] = i & 0xff; 295 ng_errors(PASS); 296 ng_send_data(hook, &msg4, sizeof(msg4)); 297 ng_errors(FAIL); 298 if (errno != 0) 299 break; 300 ng_handle_events(50, &r); 301 } 302 ATF_CHECK(r[0] == HOOKS && r[2] == 0); 303 304 /* inspect mac table */ 305 ng_register_msg(get_tablesize); 306 rm.cnt = 0; 307 ng_errors(PASS); 308 rm.tok = ng_send_msg("bridge:", "gettable"); 309 ng_errors(FAIL); 310 if (rm.tok == (u_int32_t)-1) 311 { 312 ATF_CHECK_ERRNO(ENOBUFS, 1); 313 atf_tc_expect_fail("response too large"); 314 } 315 ng_handle_events(50, &rm); 316 ATF_CHECK(rm.cnt == HOOKS + 1); 317 atf_tc_expect_pass(); 318 319 ng_shutdown("bridge:"); 320 } 321 322 ATF_TC(many_broadcasts); 323 ATF_TC_HEAD(many_broadcasts, conf) 324 { 325 atf_tc_set_md_var(conf, "require.user", "root"); 326 } 327 328 ATF_TC_BODY(many_broadcasts, dummy) 329 { 330 ng_counter_t r; 331 int i; 332 const int HOOKS = 1000; 333 334 ng_init(); 335 ng_errors(PASS); 336 ng_shutdown("bridge:"); 337 ng_errors(FAIL); 338 339 ng_mkpeer(".", "a", "bridge", "link0"); 340 ng_name("a", "bridge"); 341 ng_register_data("a", get_data0); 342 343 /* learn MAC */ 344 ng_counter_clear(r); 345 msg4.eh.ether_shost[3] = 0xff; 346 ng_send_data("a", &msg4, sizeof(msg4)); 347 ng_handle_events(50, &r); 348 ATF_CHECK(r[0] == 0); 349 350 /* use broadcast MAC */ 351 msg4.eh.ether_shost[3] = 0; 352 memset(msg4.eh.ether_dhost, 0xff, sizeof(msg4.eh.ether_dhost)); 353 354 /* now send */ 355 ng_counter_clear(r); 356 for (i = 1; i <= HOOKS; i++) 357 { 358 char hook[20]; 359 360 snprintf(hook, sizeof(hook), "link%d", i); 361 ng_connect(".", hook, "bridge:", hook); 362 ng_register_data(hook, get_data3); 363 364 msg4.eh.ether_shost[4] = i >> 8; 365 msg4.eh.ether_shost[5] = i & 0xff; 366 ng_errors(PASS); 367 ng_send_data(hook, &msg4, sizeof(msg4)); 368 ng_errors(FAIL); 369 if (errno != 0) 370 break; 371 ng_handle_events(50, &r); 372 } 373 ATF_CHECK(r[0] > 100 && r[3] > 100); 374 if (i < HOOKS) 375 atf_tc_expect_fail("netgraph queue full (%d)", i); 376 ATF_CHECK(r[0] == HOOKS); 377 atf_tc_expect_pass(); 378 379 ng_shutdown("bridge:"); 380 } 381 382 ATF_TC(uplink_private); 383 ATF_TC_HEAD(uplink_private, conf) 384 { 385 atf_tc_set_md_var(conf, "require.user", "root"); 386 } 387 388 ATF_TC_BODY(uplink_private, dummy) 389 { 390 ng_counter_t r; 391 struct gettable rm; 392 393 ng_init(); 394 ng_errors(PASS); 395 ng_shutdown("bridge:"); 396 397 ng_mkpeer(".", "u1", "bridge", "uplink1"); 398 if (errno > 0) 399 atf_tc_skip("uplinks are not supported."); 400 ng_errors(FAIL); 401 ng_name("u1", "bridge"); 402 ng_register_data("u1", get_data1); 403 ng_connect(".", "u2", "bridge:", "uplink2"); 404 ng_register_data("u2", get_data2); 405 ng_connect(".", "l0", "bridge:", "link0"); 406 ng_register_data("l0", get_data0); 407 ng_connect(".", "l3", "bridge:", "link3"); 408 ng_register_data("l3", get_data3); 409 410 /* unknown unicast 0 from uplink1 */ 411 ng_counter_clear(r); 412 msg4.eh.ether_shost[5] = 1; 413 ng_send_data("u1", &msg4, sizeof(msg4)); 414 ng_handle_events(50, &r); 415 ATF_CHECK(r[0] == 0 && r[1] == 0 && r[2] == 1 && r[3] == 0); 416 417 /* unknown unicast 2 from link0 */ 418 ng_counter_clear(r); 419 msg4.eh.ether_shost[5] = 0; 420 msg4.eh.ether_dhost[5] = 2; 421 ng_send_data("l0", &msg4, sizeof(msg4)); 422 ng_handle_events(50, &r); 423 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 0); 424 425 /* known unicast 0 from uplink2 */ 426 ng_counter_clear(r); 427 msg4.eh.ether_shost[5] = 2; 428 msg4.eh.ether_dhost[5] = 0; 429 ng_send_data("u2", &msg4, sizeof(msg4)); 430 ng_handle_events(50, &r); 431 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 0 && r[3] == 0); 432 433 /* known unicast 0 from link3 */ 434 ng_counter_clear(r); 435 msg4.eh.ether_shost[5] = 3; 436 msg4.eh.ether_dhost[5] = 0; 437 ng_send_data("l3", &msg4, sizeof(msg4)); 438 ng_handle_events(50, &r); 439 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 0 && r[3] == 0); 440 441 /* (un)known unicast 2 from uplink1 */ 442 ng_counter_clear(r); 443 msg4.eh.ether_shost[5] = 1; 444 msg4.eh.ether_dhost[5] = 2; 445 ng_send_data("u1", &msg4, sizeof(msg4)); 446 ng_handle_events(50, &r); 447 ATF_CHECK(r[0] == 0 && r[1] == 0 && r[2] == 1 && r[3] == 0); 448 449 /* (un)known unicast 2 from link0 */ 450 ng_counter_clear(r); 451 msg4.eh.ether_shost[5] = 0; 452 ng_send_data("l0", &msg4, sizeof(msg4)); 453 ng_handle_events(50, &r); 454 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 0); 455 456 /* unknown multicast 2 from uplink1 */ 457 ng_counter_clear(r); 458 msg4.eh.ether_shost[5] = 1; 459 msg4.eh.ether_dhost[0] = 0xff; 460 ng_send_data("u1", &msg4, sizeof(msg4)); 461 ng_handle_events(50, &r); 462 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1 && r[3] == 1); 463 464 /* unknown multicast 2 from link0 */ 465 ng_counter_clear(r); 466 msg4.eh.ether_shost[5] = 0; 467 ng_send_data("l0", &msg4, sizeof(msg4)); 468 ng_handle_events(50, &r); 469 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 1); 470 471 /* broadcast from uplink1 */ 472 ng_counter_clear(r); 473 msg4.eh.ether_shost[5] = 1; 474 memset(msg4.eh.ether_dhost, 0xff, sizeof(msg4.eh.ether_dhost)); 475 ng_send_data("u1", &msg4, sizeof(msg4)); 476 ng_handle_events(50, &r); 477 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1 && r[3] == 1); 478 479 /* broadcast from link0 */ 480 ng_counter_clear(r); 481 msg4.eh.ether_shost[5] = 0; 482 ng_send_data("l0", &msg4, sizeof(msg4)); 483 ng_handle_events(50, &r); 484 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 1); 485 486 /* inspect mac table */ 487 ng_register_msg(get_tablesize); 488 rm.tok = ng_send_msg("bridge:", "gettable"); 489 rm.cnt = 0; 490 ng_handle_events(50, &rm); 491 ATF_CHECK(rm.cnt == 2); 492 493 ng_shutdown("bridge:"); 494 } 495 496 ATF_TC(uplink_classic); 497 ATF_TC_HEAD(uplink_classic, conf) 498 { 499 atf_tc_set_md_var(conf, "require.user", "root"); 500 } 501 502 ATF_TC_BODY(uplink_classic, dummy) 503 { 504 ng_counter_t r; 505 struct gettable rm; 506 507 ng_init(); 508 ng_errors(PASS); 509 ng_shutdown("bridge:"); 510 511 ng_mkpeer(".", "l0", "bridge", "link0"); 512 if (errno > 0) 513 atf_tc_skip("uplinks are not supported."); 514 ng_errors(FAIL); 515 ng_name("l0", "bridge"); 516 ng_register_data("l0", get_data0); 517 ng_connect(".", "u1", "bridge:", "uplink1"); 518 ng_register_data("u1", get_data1); 519 ng_connect(".", "u2", "bridge:", "uplink2"); 520 ng_register_data("u2", get_data2); 521 ng_connect(".", "l3", "bridge:", "link3"); 522 ng_register_data("l3", get_data3); 523 524 /* unknown unicast 0 from uplink1 */ 525 ng_counter_clear(r); 526 msg4.eh.ether_shost[5] = 1; 527 ng_send_data("u1", &msg4, sizeof(msg4)); 528 ng_handle_events(50, &r); 529 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1 && r[3] == 1); 530 531 /* unknown unicast 2 from link0 */ 532 ng_counter_clear(r); 533 msg4.eh.ether_shost[5] = 0; 534 msg4.eh.ether_dhost[5] = 2; 535 ng_send_data("l0", &msg4, sizeof(msg4)); 536 ng_handle_events(50, &r); 537 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 1); 538 539 /* known unicast 0 from uplink2 */ 540 ng_counter_clear(r); 541 msg4.eh.ether_shost[5] = 2; 542 msg4.eh.ether_dhost[5] = 0; 543 ng_send_data("u2", &msg4, sizeof(msg4)); 544 ng_handle_events(50, &r); 545 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 0 && r[3] == 0); 546 547 /* known unicast 0 from link3 */ 548 ng_counter_clear(r); 549 msg4.eh.ether_shost[5] = 3; 550 msg4.eh.ether_dhost[5] = 0; 551 ng_send_data("l3", &msg4, sizeof(msg4)); 552 ng_handle_events(50, &r); 553 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 0 && r[3] == 0); 554 555 /* (un)known unicast 2 from uplink1 */ 556 ng_counter_clear(r); 557 msg4.eh.ether_shost[5] = 1; 558 msg4.eh.ether_dhost[5] = 2; 559 ng_send_data("u1", &msg4, sizeof(msg4)); 560 ng_handle_events(50, &r); 561 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1 && r[3] == 1); 562 563 /* (un)known unicast 2 from link0 */ 564 ng_counter_clear(r); 565 msg4.eh.ether_shost[5] = 0; 566 ng_send_data("l0", &msg4, sizeof(msg4)); 567 ng_handle_events(50, &r); 568 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 1); 569 570 /* unknown multicast 2 from uplink1 */ 571 ng_counter_clear(r); 572 msg4.eh.ether_shost[5] = 1; 573 msg4.eh.ether_dhost[0] = 0xff; 574 ng_send_data("u1", &msg4, sizeof(msg4)); 575 ng_handle_events(50, &r); 576 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1 && r[3] == 1); 577 578 /* unknown multicast 2 from link0 */ 579 ng_counter_clear(r); 580 msg4.eh.ether_shost[5] = 0; 581 ng_send_data("l0", &msg4, sizeof(msg4)); 582 ng_handle_events(50, &r); 583 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 1); 584 585 /* broadcast from uplink1 */ 586 ng_counter_clear(r); 587 msg4.eh.ether_shost[5] = 1; 588 memset(msg4.eh.ether_dhost, 0xff, sizeof(msg4.eh.ether_dhost)); 589 ng_send_data("u1", &msg4, sizeof(msg4)); 590 ng_handle_events(50, &r); 591 ATF_CHECK(r[0] == 1 && r[1] == 0 && r[2] == 1 && r[3] == 1); 592 593 /* broadcast from link0 */ 594 ng_counter_clear(r); 595 msg4.eh.ether_shost[5] = 0; 596 ng_send_data("l0", &msg4, sizeof(msg4)); 597 ng_handle_events(50, &r); 598 ATF_CHECK(r[0] == 0 && r[1] == 1 && r[2] == 1 && r[3] == 1); 599 600 /* inspect mac table */ 601 ng_register_msg(get_tablesize); 602 rm.tok = ng_send_msg("bridge:", "gettable"); 603 rm.cnt = 0; 604 ng_handle_events(50, &rm); 605 ATF_CHECK(rm.cnt == 2); 606 607 ng_shutdown("bridge:"); 608 } 609 610 ATF_TP_ADD_TCS(bridge) 611 { 612 ATF_TP_ADD_TC(bridge, basic); 613 ATF_TP_ADD_TC(bridge, loop); 614 ATF_TP_ADD_TC(bridge, persistence); 615 ATF_TP_ADD_TC(bridge, many_unicasts); 616 ATF_TP_ADD_TC(bridge, many_broadcasts); 617 ATF_TP_ADD_TC(bridge, uplink_private); 618 ATF_TP_ADD_TC(bridge, uplink_classic); 619 620 return atf_no_error(); 621 } 622 623 static void 624 get_tablesize(char const *source, struct ng_mesg *msg, void *ctx) 625 { 626 struct gettable *rm = ctx; 627 struct ng_bridge_host_ary *gt = (void *)msg->data; 628 629 fprintf(stderr, "Response from %s to query %d\n", source, msg->header.token); 630 if (rm->tok == msg->header.token) 631 rm->cnt = gt->numHosts; 632 } 633