]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/netgraph/bridge.c
sqlite3: Vendor import of sqlite3 3.45.1
[FreeBSD/FreeBSD.git] / tests / sys / netgraph / bridge.c
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 }