Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/netgraph/bridge.c
39483 views
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
634