]> git.proxmox.com Git - mirror_frr.git/blob - tests/bgp_capability_test.c
lib, bgpd, tests: Refactor FILTER_X in zebra.h
[mirror_frr.git] / tests / bgp_capability_test.c
1 /*
2 * Copyright (C) 2007 Sun Microsystems, Inc.
3 *
4 * This file is part of Quagga.
5 *
6 * Quagga is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * Quagga is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Quagga; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "vty.h"
25 #include "stream.h"
26 #include "privs.h"
27 #include "memory.h"
28 #include "queue.h"
29 #include "filter.h"
30
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_open.h"
33 #include "bgpd/bgp_debug.h"
34 #include "bgpd/bgp_packet.h"
35
36 #define VT100_RESET "\x1b[0m"
37 #define VT100_RED "\x1b[31m"
38 #define VT100_GREEN "\x1b[32m"
39 #define VT100_YELLOW "\x1b[33m"
40
41
42 #define CAPABILITY 0
43 #define DYNCAP 1
44 #define OPT_PARAM 2
45
46 /* need these to link in libbgp */
47 struct zebra_privs_t *bgpd_privs = NULL;
48 struct thread_master *master = NULL;
49
50 static int failed = 0;
51 static int tty = 0;
52
53 /* test segments to parse and validate, and use for other tests */
54 static struct test_segment {
55 const char *name;
56 const char *desc;
57 const u_char data[1024];
58 int len;
59 #define SHOULD_PARSE 0
60 #define SHOULD_ERR -1
61 int parses; /* whether it should parse or not */
62 as_t peek_for; /* what peek_for_as4_capability should say */
63
64 /* AFI/SAFI validation */
65 int validate_afi;
66 afi_t afi;
67 safi_t safi;
68 #define VALID_AFI 1
69 #define INVALID_AFI 0
70 int afi_valid;
71 } test_segments [] =
72 {
73 /* 0 */
74 { "caphdr",
75 "capability header, and no more",
76 { CAPABILITY_CODE_REFRESH, 0x0 },
77 2, SHOULD_PARSE,
78 },
79 /* 1 */
80 { "nodata",
81 "header, no data but length says there is",
82 { 0x1, 0xa },
83 2, SHOULD_ERR,
84 },
85 /* 2 */
86 { "padded",
87 "valid, with padding",
88 { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
89 4, SHOULD_PARSE,
90 },
91 /* 3 */
92 { "minsize",
93 "violates minsize requirement",
94 { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
95 4, SHOULD_ERR,
96 },
97 { NULL, NULL, {0}, 0, 0},
98 };
99
100 static struct test_segment mp_segments[] =
101 {
102 { "MP4",
103 "MP IP/Uni",
104 { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
105 6, SHOULD_PARSE, 0,
106 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
107 },
108 { "MPv6",
109 "MP IPv6/Uni",
110 { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
111 6, SHOULD_PARSE, 0,
112 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
113 },
114 /* 5 */
115 { "MP2",
116 "MP IP/Multicast",
117 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
118 6, SHOULD_PARSE, 0,
119 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
120 },
121 /* 6 */
122 { "MP3",
123 "MP IP6/MPLS-labeled VPN",
124 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
125 6, SHOULD_PARSE, 0,
126 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
127 },
128 /* 7 */
129 { "MP5",
130 "MP IP6/MPLS-VPN",
131 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
132 6, SHOULD_PARSE, 0,
133 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
134 },
135 /* 8 */
136 { "MP6",
137 "MP IP4/MPLS-laveled VPN",
138 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
139 6, SHOULD_PARSE, 0,
140 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
141 },
142 /* 10 */
143 { "MP8",
144 "MP unknown AFI/SAFI",
145 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
146 6, SHOULD_PARSE, 0,
147 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
148 },
149 /* 11 */
150 { "MP-short",
151 "MP IP4/Unicast, length too short (< minimum)",
152 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
153 6, SHOULD_ERR,
154 },
155 /* 12 */
156 { "MP-overflow",
157 "MP IP4/Unicast, length too long",
158 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
159 6, SHOULD_ERR, 0,
160 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
161 },
162 { NULL, NULL, {0}, 0, 0}
163 };
164
165 static struct test_segment misc_segments[] =
166 {
167 /* 13 */
168 { "ORF",
169 "ORF, simple, single entry, single tuple",
170 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
171 /* mpc */ 0x0, 0x1, 0x0, 0x1,
172 /* num */ 0x1,
173 /* tuples */ 0x40, 0x3
174 },
175 9, SHOULD_PARSE,
176 },
177 /* 14 */
178 { "ORF-many",
179 "ORF, multi entry/tuple",
180 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
181 /* mpc */ 0x0, 0x1, 0x0, 0x1,
182 /* num */ 0x3,
183 /* tuples */ 0x40, ORF_MODE_BOTH,
184 0x80, ORF_MODE_RECEIVE,
185 0x80, ORF_MODE_SEND,
186 /* mpc */ 0x0, 0x2, 0x0, 0x1,
187 /* num */ 0x3,
188 /* tuples */ 0x40, ORF_MODE_BOTH,
189 0x80, ORF_MODE_RECEIVE,
190 0x80, ORF_MODE_SEND,
191 /* mpc */ 0x0, 0x2, 0x0, 0x2,
192 /* num */ 0x3,
193 /* tuples */ 0x40, ORF_MODE_RECEIVE,
194 0x80, ORF_MODE_SEND,
195 0x80, ORF_MODE_BOTH,
196 },
197 35, SHOULD_PARSE,
198 },
199 /* 15 */
200 { "ORFlo",
201 "ORF, multi entry/tuple, hdr length too short",
202 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
203 /* mpc */ 0x0, 0x1, 0x0, 0x1,
204 /* num */ 0x3,
205 /* tuples */ 0x40, 0x3,
206 0x80, 0x1,
207 0x80, 0x2,
208 /* mpc */ 0x0, 0x1, 0x0, 0x1,
209 /* num */ 0x3,
210 /* tuples */ 0x40, 0x3,
211 0x80, 0x1,
212 0x80, 0x2,
213 /* mpc */ 0x0, 0x2, 0x0, 0x2,
214 /* num */ 0x3,
215 /* tuples */ 0x40, 0x3,
216 0x80, 0x1,
217 0x80, 0x2,
218 },
219 35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
220 },
221 /* 16 */
222 { "ORFlu",
223 "ORF, multi entry/tuple, length too long",
224 { /* hdr */ 0x3, 0x22,
225 /* mpc */ 0x0, 0x1, 0x0, 0x1,
226 /* num */ 0x3,
227 /* tuples */ 0x40, 0x3,
228 0x80, 0x1,
229 0x80, 0x2,
230 /* mpc */ 0x0, 0x2, 0x0, 0x1,
231 /* num */ 0x3,
232 /* tuples */ 0x40, 0x3,
233 0x80, 0x1,
234 0x80, 0x2,
235 /* mpc */ 0x0, 0x2, 0x0, 0x2,
236 /* num */ 0x3,
237 /* tuples */ 0x40, 0x3,
238 0x80, 0x1,
239 0x80, 0x2,
240 },
241 35, SHOULD_ERR
242 },
243 /* 17 */
244 { "ORFnu",
245 "ORF, multi entry/tuple, entry number too long",
246 { /* hdr */ 0x3, 0x21,
247 /* mpc */ 0x0, 0x1, 0x0, 0x1,
248 /* num */ 0x3,
249 /* tuples */ 0x40, 0x3,
250 0x80, 0x1,
251 0x80, 0x2,
252 /* mpc */ 0x0, 0x2, 0x0, 0x1,
253 /* num */ 0x4,
254 /* tuples */ 0x40, 0x3,
255 0x80, 0x1,
256 0x80, 0x2,
257 /* mpc */ 0x0, 0x2, 0x0, 0x2,
258 /* num */ 0x3,
259 /* tuples */ 0x40, 0x3,
260 0x80, 0x1,
261 0x80, 0x2,
262 },
263 35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
264 },
265 /* 18 */
266 { "ORFno",
267 "ORF, multi entry/tuple, entry number too short",
268 { /* hdr */ 0x3, 0x21,
269 /* mpc */ 0x0, 0x1, 0x0, 0x1,
270 /* num */ 0x3,
271 /* tuples */ 0x40, 0x3,
272 0x80, 0x1,
273 0x80, 0x2,
274 /* mpc */ 0x0, 0x2, 0x0, 0x1,
275 /* num */ 0x1,
276 /* tuples */ 0x40, 0x3,
277 0x80, 0x1,
278 0x80, 0x2,
279 /* mpc */ 0x0, 0x2, 0x0, 0x2,
280 /* num */ 0x3,
281 /* tuples */ 0x40, 0x3,
282 0x80, 0x1,
283 0x80, 0x2,
284 },
285 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
286 },
287 /* 17 */
288 { "ORFpad",
289 "ORF, multi entry/tuple, padded to align",
290 { /* hdr */ 0x3, 0x22,
291 /* mpc */ 0x0, 0x1, 0x0, 0x1,
292 /* num */ 0x3,
293 /* tuples */ 0x40, 0x3,
294 0x80, 0x1,
295 0x80, 0x2,
296 /* mpc */ 0x0, 0x2, 0x0, 0x1,
297 /* num */ 0x3,
298 /* tuples */ 0x40, 0x3,
299 0x80, 0x1,
300 0x80, 0x2,
301 /* mpc */ 0x0, 0x2, 0x0, 0x2,
302 /* num */ 0x3,
303 /* tuples */ 0x40, 0x3,
304 0x80, 0x1,
305 0x80, 0x2,
306 0x00,
307 },
308 36, SHOULD_PARSE,
309 },
310 /* 19 */
311 { "AS4",
312 "AS4 capability",
313 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
314 6, SHOULD_PARSE, 2882400018,
315 },
316 { "AS4",
317 "AS4 capability: short",
318 { 0x41, 0x4, 0xab, 0xcd, 0xef }, /* AS: 2882400018 */
319 5, SHOULD_ERR,
320 },
321 { "AS4",
322 "AS4 capability: long",
323 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12 },
324 7, SHOULD_ERR, 2882400018,
325 },
326 { "GR",
327 "GR capability",
328 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
329 /* R-bit, time */ 0xf1, 0x12,
330 /* afi */ 0x0, 0x1,
331 /* safi */ 0x1,
332 /* flags */ 0xf,
333 /* afi */ 0x0, 0x2,
334 /* safi */ 0x1,
335 /* flags */ 0x0,
336 /* afi */ 0x0, 0x2,
337 /* safi */ 0x2,
338 /* flags */ 0x1,
339 },
340 16, SHOULD_PARSE,
341 },
342 { "GR-short",
343 "GR capability, but header length too short",
344 { /* hdr */ 0x40, 0xa,
345 /* R-bit, time */ 0xf1, 0x12,
346 /* afi */ 0x0, 0x1,
347 /* safi */ 0x1,
348 /* flags */ 0xf,
349 /* afi */ 0x0, 0x2,
350 /* safi */ 0x1,
351 /* flags */ 0x0,
352 /* afi */ 0x0, 0x2,
353 /* safi */ 0x2,
354 /* flags */ 0x1,
355 },
356 15 /* array is 16 though */, SHOULD_ERR,
357 },
358 { "GR-long",
359 "GR capability, but header length too long",
360 { /* hdr */ 0x40, 0xf,
361 /* R-bit, time */ 0xf1, 0x12,
362 /* afi */ 0x0, 0x1,
363 /* safi */ 0x1,
364 /* flags */ 0xf,
365 /* afi */ 0x0, 0x2,
366 /* safi */ 0x1,
367 /* flags */ 0x0,
368 /* afi */ 0x0, 0x2,
369 /* safi */ 0x2,
370 /* flags */ 0x01,
371 },
372 16, SHOULD_ERR,
373 },
374 { "GR-trunc",
375 "GR capability, but truncated",
376 { /* hdr */ 0x40, 0xf,
377 /* R-bit, time */ 0xf1, 0x12,
378 /* afi */ 0x0, 0x1,
379 /* safi */ 0x1,
380 /* flags */ 0xf,
381 /* afi */ 0x0, 0x2,
382 /* safi */ 0x1,
383 /* flags */ 0x0,
384 /* afi */ 0x0, 0x2,
385 /* safi */ 0x2,
386 /* flags */ 0x1,
387 },
388 15, SHOULD_ERR,
389 },
390 { "GR-empty",
391 "GR capability, but empty.",
392 { /* hdr */ 0x40, 0x0,
393 },
394 2, SHOULD_ERR,
395 },
396 { "MP-empty",
397 "MP capability, but empty.",
398 { /* hdr */ 0x1, 0x0,
399 },
400 2, SHOULD_ERR,
401 },
402 { "ORF-empty",
403 "ORF capability, but empty.",
404 { /* hdr */ 0x3, 0x0,
405 },
406 2, SHOULD_ERR,
407 },
408 { "AS4-empty",
409 "AS4 capability, but empty.",
410 { /* hdr */ 0x41, 0x0,
411 },
412 2, SHOULD_ERR,
413 },
414 { "dyn-empty",
415 "Dynamic capability, but empty.",
416 { /* hdr */ 0x42, 0x0,
417 },
418 2, SHOULD_PARSE,
419 },
420 { "dyn-old",
421 "Dynamic capability (deprecated version)",
422 { CAPABILITY_CODE_DYNAMIC, 0x0 },
423 2, SHOULD_PARSE,
424 },
425 { NULL, NULL, {0}, 0, 0}
426 };
427
428 /* DYNAMIC message */
429 struct test_segment dynamic_cap_msgs[] =
430 {
431 { "DynCap",
432 "Dynamic Capability Message, IP/Multicast",
433 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
434 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
435 },
436 { "DynCapLong",
437 "Dynamic Capability Message, IP/Multicast, truncated",
438 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
439 5, SHOULD_ERR,
440 },
441 { "DynCapPadded",
442 "Dynamic Capability Message, IP/Multicast, padded",
443 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
444 8, SHOULD_ERR, /* No way to tell padding from data.. */
445 },
446 { "DynCapMPCpadded",
447 "Dynamic Capability Message, IP/Multicast, cap data padded",
448 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
449 8, SHOULD_PARSE, /* You can though add padding to the capability data */
450 },
451 { "DynCapMPCoverflow",
452 "Dynamic Capability Message, IP/Multicast, cap data != length",
453 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
454 8, SHOULD_ERR,
455 },
456 { NULL, NULL, {0}, 0, 0}
457 };
458
459 /* Entire Optional-Parameters block */
460 struct test_segment opt_params[] =
461 {
462 { "Cap-singlets",
463 "One capability per Optional-Param",
464 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
465 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
466 0x02, 0x02, 0x80, 0x00, /* RR (old) */
467 0x02, 0x02, 0x02, 0x00, /* RR */
468 },
469 24, SHOULD_PARSE,
470 },
471 { "Cap-series",
472 "Series of capability, one Optional-Param",
473 { 0x02, 0x10,
474 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
475 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
476 0x80, 0x00, /* RR (old) */
477 0x02, 0x00, /* RR */
478 },
479 18, SHOULD_PARSE,
480 },
481 { "AS4more",
482 "AS4 capability after other caps (singlets)",
483 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
484 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
485 0x02, 0x02, 0x80, 0x00, /* RR (old) */
486 0x02, 0x02, 0x02, 0x00, /* RR */
487 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
488 },
489 32, SHOULD_PARSE, 196614,
490 },
491 { "AS4series",
492 "AS4 capability, in series of capabilities",
493 { 0x02, 0x16,
494 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
495 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
496 0x80, 0x00, /* RR (old) */
497 0x02, 0x00, /* RR */
498 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
499 },
500 24, SHOULD_PARSE, 196614,
501 },
502 { "AS4real",
503 "AS4 capability, in series of capabilities",
504 {
505 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
506 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
507 0x02, 0x02, 0x80, 0x00, /* RR old */
508 0x02, 0x02, 0x02, 0x00, /* RR */
509 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
510 },
511 32, SHOULD_PARSE, 196614,
512 },
513 { "AS4real2",
514 "AS4 capability, in series of capabilities",
515 {
516 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
517 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
518 0x02, 0x02, 0x80, 0x00,
519 0x02, 0x02, 0x02, 0x00,
520 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
521 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
522 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
523 0x02, 0x02, 0x42, 0x00,
524 },
525 58, SHOULD_PARSE, 64515,
526 },
527
528 { NULL, NULL, {0}, 0, 0}
529 };
530
531 /* basic parsing test */
532 static void
533 parse_test (struct peer *peer, struct test_segment *t, int type)
534 {
535 int ret;
536 int capability = 0;
537 as_t as4 = 0;
538 int oldfailed = failed;
539 int len = t->len;
540 #define RANDOM_FUZZ 35
541
542 stream_reset (peer->ibuf);
543 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
544 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
545
546 switch (type)
547 {
548 case CAPABILITY:
549 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
550 stream_putc (peer->ibuf, t->len);
551 break;
552 case DYNCAP:
553 /* for (i = 0; i < BGP_MARKER_SIZE; i++)
554 stream_putc (peer->, 0xff);
555 stream_putw (s, 0);
556 stream_putc (s, BGP_MSG_CAPABILITY);*/
557 break;
558 }
559 stream_write (peer->ibuf, t->data, t->len);
560
561 printf ("%s: %s\n", t->name, t->desc);
562
563 switch (type)
564 {
565 case CAPABILITY:
566 len += 2; /* to cover the OPT-Param header */
567 case OPT_PARAM:
568 printf ("len: %u\n", len);
569 /* peek_for_as4 wants getp at capibility*/
570 as4 = peek_for_as4_capability (peer, len);
571 printf ("peek_for_as4: as4 is %u\n", as4);
572 /* and it should leave getp as it found it */
573 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
574
575 ret = bgp_open_option_parse (peer, len, &capability);
576 break;
577 case DYNCAP:
578 ret = bgp_capability_receive (peer, t->len);
579 break;
580 default:
581 printf ("unknown type %u\n", type);
582 exit(1);
583 }
584
585 if (!ret && t->validate_afi)
586 {
587 safi_t safi = t->safi;
588
589 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
590 failed++;
591
592 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
593 t->afi, t->safi, safi,
594 peer->afc_recv[t->afi][safi],
595 peer->afc_nego[t->afi][safi]);
596
597 if (t->afi_valid == VALID_AFI)
598 {
599
600 if (!peer->afc_recv[t->afi][safi])
601 failed++;
602 if (!peer->afc_nego[t->afi][safi])
603 failed++;
604 }
605 }
606
607 if (as4 != t->peek_for)
608 {
609 printf ("as4 %u != %u\n", as4, t->peek_for);
610 failed++;
611 }
612
613 printf ("parsed?: %s\n", ret ? "no" : "yes");
614
615 if (ret != t->parses)
616 failed++;
617
618 if (tty)
619 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
620 : VT100_GREEN "OK" VT100_RESET);
621 else
622 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
623
624 if (failed)
625 printf (" (%u)", failed);
626
627 printf ("\n\n");
628 }
629
630 static struct bgp *bgp;
631 static as_t asn = 100;
632
633 int
634 main (void)
635 {
636 struct peer *peer;
637 int i, j;
638
639 conf_bgp_debug_neighbor_events = -1UL;
640 conf_bgp_debug_packet = -1UL;
641 conf_bgp_debug_as4 = -1UL;
642 term_bgp_debug_neighbor_events = -1UL;
643 term_bgp_debug_packet = -1UL;
644 term_bgp_debug_as4 = -1UL;
645
646 master = thread_master_create ();
647 bgp_master_init ();
648 vrf_init ();
649 bgp_option_set (BGP_OPT_NO_LISTEN);
650
651 if (fileno (stdout) >= 0)
652 tty = isatty (fileno (stdout));
653
654 if (bgp_get (&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
655 return -1;
656
657 peer = peer_create_accept (bgp);
658 peer->host = (char *) "foo";
659
660 for (i = AFI_IP; i < AFI_MAX; i++)
661 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
662 {
663 peer->afc[i][j] = 1;
664 peer->afc_adv[i][j] = 1;
665 }
666
667 i = 0;
668 while (mp_segments[i].name)
669 parse_test (peer, &mp_segments[i++], CAPABILITY);
670
671 /* These tests assume mp_segments tests set at least
672 * one of the afc_nego's
673 */
674 i = 0;
675 while (test_segments[i].name)
676 parse_test (peer, &test_segments[i++], CAPABILITY);
677
678 i = 0;
679 while (misc_segments[i].name)
680 parse_test (peer, &misc_segments[i++], CAPABILITY);
681
682 i = 0;
683 while (opt_params[i].name)
684 parse_test (peer, &opt_params[i++], OPT_PARAM);
685
686 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
687 peer->status = Established;
688
689 i = 0;
690 while (dynamic_cap_msgs[i].name)
691 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
692
693 printf ("failures: %d\n", failed);
694 return failed;
695 }