]> git.proxmox.com Git - mirror_frr.git/blob - tests/bgpd/test_capability.c
*: Convert `struct event_master` to `struct event_loop`
[mirror_frr.git] / tests / bgpd / test_capability.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2007 Sun Microsystems, Inc.
4 */
5
6 #include <zebra.h>
7
8 #include "qobj.h"
9 #include "vty.h"
10 #include "stream.h"
11 #include "privs.h"
12 #include "memory.h"
13 #include "queue.h"
14 #include "filter.h"
15 #include "frr_pthread.h"
16
17 #include "bgpd/bgpd.c"
18 #include "bgpd/bgp_open.h"
19 #include "bgpd/bgp_debug.h"
20 #include "bgpd/bgp_packet.h"
21
22 #define VT100_RESET "\x1b[0m"
23 #define VT100_RED "\x1b[31m"
24 #define VT100_GREEN "\x1b[32m"
25 #define VT100_YELLOW "\x1b[33m"
26
27 #define CAPABILITY 0
28 #define DYNCAP 1
29 #define OPT_PARAM 2
30
31 /* need these to link in libbgp */
32 struct zebra_privs_t bgpd_privs = {};
33 struct event_loop *master = NULL;
34
35 static int failed = 0;
36 static int tty = 0;
37
38 /* test segments to parse and validate, and use for other tests */
39 static struct test_segment {
40 const char *name;
41 const char *desc;
42 const uint8_t data[1024];
43 int len;
44 #define SHOULD_PARSE 0
45 #define SHOULD_ERR -1
46 int parses; /* whether it should parse or not */
47 as_t peek_for; /* what peek_for_as4_capability should say */
48
49 /* AFI/SAFI validation */
50 int validate_afi;
51 iana_afi_t afi;
52 iana_safi_t safi;
53 #define VALID_AFI 1
54 #define INVALID_AFI 0
55 int afi_valid;
56 } test_segments[] = {
57 /* 0 */
58 {
59 "caphdr",
60 "capability header, and no more",
61 {CAPABILITY_CODE_REFRESH, 0x0},
62 2,
63 SHOULD_PARSE,
64 },
65 /* 1 */
66 {
67 "nodata",
68 "header, no data but length says there is",
69 {0x1, 0xa},
70 2,
71 SHOULD_ERR,
72 },
73 /* 2 */
74 {
75 "padded",
76 "valid, with padding",
77 {CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0},
78 4,
79 SHOULD_PARSE,
80 },
81 /* 3 */
82 {
83 "minsize",
84 "violates minsize requirement",
85 {CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0},
86 4,
87 SHOULD_ERR,
88 },
89 {NULL, NULL, {0}, 0, 0},
90 };
91
92 static struct test_segment mp_segments[] = {
93 {
94 "MP4",
95 "MP IP/Uni",
96 {0x1, 0x4, 0x0, 0x1, 0x0, 0x1},
97 6,
98 SHOULD_PARSE,
99 0,
100 1,
101 IANA_AFI_IPV4,
102 IANA_SAFI_UNICAST,
103 VALID_AFI,
104 },
105 {
106 "MPv6",
107 "MP IPv6/Uni",
108 {0x1, 0x4, 0x0, 0x2, 0x0, 0x1},
109 6,
110 SHOULD_PARSE,
111 0,
112 1,
113 IANA_AFI_IPV6,
114 IANA_SAFI_UNICAST,
115 VALID_AFI,
116 },
117 /* 5 */
118 {
119 "MP2",
120 "MP IP/Multicast",
121 {CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2},
122 6,
123 SHOULD_PARSE,
124 0,
125 1,
126 IANA_AFI_IPV4,
127 IANA_SAFI_MULTICAST,
128 VALID_AFI,
129 },
130 /* 6 */
131 {
132 "MP3",
133 "MP IP6/MPLS-labeled VPN",
134 {CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80},
135 6,
136 SHOULD_PARSE,
137 0,
138 1,
139 IANA_AFI_IPV6,
140 IANA_SAFI_MPLS_VPN,
141 VALID_AFI,
142 },
143 /* 7 */
144 {
145 "MP5",
146 "MP IP6/MPLS-VPN",
147 {CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4},
148 6,
149 SHOULD_PARSE,
150 0,
151 1,
152 IANA_AFI_IPV6,
153 IANA_SAFI_MPLS_VPN,
154 VALID_AFI,
155 },
156 /* 8 */
157 {
158 "MP6",
159 "MP IP4/MPLS-labeled VPN",
160 {CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80},
161 6,
162 SHOULD_PARSE,
163 0,
164 1,
165 IANA_AFI_IPV4,
166 IANA_SAFI_MPLS_VPN,
167 VALID_AFI,
168 },
169 /* 10 */
170 {
171 "MP8",
172 "MP unknown AFI/SAFI",
173 {CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81},
174 6,
175 SHOULD_PARSE,
176 0,
177 1,
178 0xa,
179 0x81,
180 INVALID_AFI, /* parses, but unknown */
181 },
182 /* 11 */
183 {
184 "MP-short",
185 "MP IP4/Unicast, length too short (< minimum)",
186 {CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1},
187 6,
188 SHOULD_ERR,
189 },
190 /* 12 */
191 {
192 "MP-overflow",
193 "MP IP4/Unicast, length too long",
194 {CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1},
195 6,
196 SHOULD_ERR,
197 0,
198 1,
199 IANA_AFI_IPV4,
200 IANA_SAFI_UNICAST,
201 VALID_AFI,
202 },
203 {NULL, NULL, {0}, 0, 0}};
204
205 static struct test_segment misc_segments[] =
206 {
207 /* 13 */
208 {
209 "ORF",
210 "ORF, simple, single entry, single tuple",
211 {/* hdr */ CAPABILITY_CODE_ORF, 0x7,
212 /* mpc */ 0x0, 0x1, 0x0, 0x1,
213 /* num */ 0x1,
214 /* tuples */ 0x40, 0x3},
215 9,
216 SHOULD_PARSE,
217 },
218 /* 14 */
219 {
220 "ORF-many",
221 "ORF, multi entry/tuple",
222 {
223 /* hdr */ CAPABILITY_CODE_ORF,
224 0x21,
225 /* mpc */ 0x0,
226 0x1,
227 0x0,
228 0x1,
229 /* num */ 0x3,
230 /* tuples */ 0x40,
231 ORF_MODE_BOTH,
232 0x80,
233 ORF_MODE_RECEIVE,
234 0x80,
235 ORF_MODE_SEND,
236 /* mpc */ 0x0,
237 0x2,
238 0x0,
239 0x1,
240 /* num */ 0x3,
241 /* tuples */ 0x40,
242 ORF_MODE_BOTH,
243 0x80,
244 ORF_MODE_RECEIVE,
245 0x80,
246 ORF_MODE_SEND,
247 /* mpc */ 0x0,
248 0x2,
249 0x0,
250 0x2,
251 /* num */ 0x3,
252 /* tuples */ 0x40,
253 ORF_MODE_RECEIVE,
254 0x80,
255 ORF_MODE_SEND,
256 0x80,
257 ORF_MODE_BOTH,
258 },
259 35,
260 SHOULD_PARSE,
261 },
262 /* 15 */
263 {
264 "ORFlo",
265 "ORF, multi entry/tuple, hdr length too short",
266 {
267 /* hdr */ CAPABILITY_CODE_ORF,
268 0x15,
269 /* mpc */ 0x0,
270 0x1,
271 0x0,
272 0x1,
273 /* num */ 0x3,
274 /* tuples */ 0x40,
275 0x3,
276 0x80,
277 0x1,
278 0x80,
279 0x2,
280 /* mpc */ 0x0,
281 0x1,
282 0x0,
283 0x1,
284 /* num */ 0x3,
285 /* tuples */ 0x40,
286 0x3,
287 0x80,
288 0x1,
289 0x80,
290 0x2,
291 /* mpc */ 0x0,
292 0x2,
293 0x0,
294 0x2,
295 /* num */ 0x3,
296 /* tuples */ 0x40,
297 0x3,
298 0x80,
299 0x1,
300 0x80,
301 0x2,
302 },
303 35,
304 SHOULD_ERR, /* It should error on invalid
305 Route-Refresh.. */
306 },
307 /* 16 */
308 {"ORFlu",
309 "ORF, multi entry/tuple, length too long",
310 {
311 /* hdr */ 0x3,
312 0x22,
313 /* mpc */ 0x0,
314 0x1,
315 0x0,
316 0x1,
317 /* num */ 0x3,
318 /* tuples */ 0x40,
319 0x3,
320 0x80,
321 0x1,
322 0x80,
323 0x2,
324 /* mpc */ 0x0,
325 0x2,
326 0x0,
327 0x1,
328 /* num */ 0x3,
329 /* tuples */ 0x40,
330 0x3,
331 0x80,
332 0x1,
333 0x80,
334 0x2,
335 /* mpc */ 0x0,
336 0x2,
337 0x0,
338 0x2,
339 /* num */ 0x3,
340 /* tuples */ 0x40,
341 0x3,
342 0x80,
343 0x1,
344 0x80,
345 0x2,
346 },
347 35,
348 SHOULD_ERR},
349 /* 17 */
350 {
351 "ORFnu",
352 "ORF, multi entry/tuple, entry number too long",
353 {
354 /* hdr */ 0x3,
355 0x21,
356 /* mpc */ 0x0,
357 0x1,
358 0x0,
359 0x1,
360 /* num */ 0x3,
361 /* tuples */ 0x40,
362 0x3,
363 0x80,
364 0x1,
365 0x80,
366 0x2,
367 /* mpc */ 0x0,
368 0x2,
369 0x0,
370 0x1,
371 /* num */ 0x4,
372 /* tuples */ 0x40,
373 0x3,
374 0x80,
375 0x1,
376 0x80,
377 0x2,
378 /* mpc */ 0x0,
379 0x2,
380 0x0,
381 0x2,
382 /* num */ 0x3,
383 /* tuples */ 0x40,
384 0x3,
385 0x80,
386 0x1,
387 0x80,
388 0x2,
389 },
390 35,
391 SHOULD_PARSE, /* parses, but last few tuples should be
392 gibberish */
393 },
394 /* 18 */
395 {
396 "ORFno",
397 "ORF, multi entry/tuple, entry number too short",
398 {
399 /* hdr */ 0x3,
400 0x21,
401 /* mpc */ 0x0,
402 0x1,
403 0x0,
404 0x1,
405 /* num */ 0x3,
406 /* tuples */ 0x40,
407 0x3,
408 0x80,
409 0x1,
410 0x80,
411 0x2,
412 /* mpc */ 0x0,
413 0x2,
414 0x0,
415 0x1,
416 /* num */ 0x1,
417 /* tuples */ 0x40,
418 0x3,
419 0x80,
420 0x1,
421 0x80,
422 0x2,
423 /* mpc */ 0x0,
424 0x2,
425 0x0,
426 0x2,
427 /* num */ 0x3,
428 /* tuples */ 0x40,
429 0x3,
430 0x80,
431 0x1,
432 0x80,
433 0x2,
434 },
435 35,
436 SHOULD_PARSE, /* Parses, but should get gibberish
437 afi/safis */
438 },
439 /* 17 */
440 {
441 "ORFpad",
442 "ORF, multi entry/tuple, padded to align",
443 {
444 /* hdr */ 0x3,
445 0x22,
446 /* mpc */ 0x0,
447 0x1,
448 0x0,
449 0x1,
450 /* num */ 0x3,
451 /* tuples */ 0x40,
452 0x3,
453 0x80,
454 0x1,
455 0x80,
456 0x2,
457 /* mpc */ 0x0,
458 0x2,
459 0x0,
460 0x1,
461 /* num */ 0x3,
462 /* tuples */ 0x40,
463 0x3,
464 0x80,
465 0x1,
466 0x80,
467 0x2,
468 /* mpc */ 0x0,
469 0x2,
470 0x0,
471 0x2,
472 /* num */ 0x3,
473 /* tuples */ 0x40,
474 0x3,
475 0x80,
476 0x1,
477 0x80,
478 0x2,
479 0x00,
480 },
481 36,
482 SHOULD_PARSE,
483 },
484 /* 19 */
485 {
486 "AS4",
487 "AS4 capability",
488 {0x41, 0x4, 0xab, 0xcd, 0xef,
489 0x12}, /* AS: 2882400018 */
490 6,
491 SHOULD_PARSE,
492 2882400018,
493 },
494 {
495 "AS4",
496 "AS4 capability: short",
497 {0x41, 0x4, 0xab, 0xcd, 0xef}, /* AS: 2882400018 */
498 5,
499 SHOULD_ERR,
500 },
501 {
502 "AS4",
503 "AS4 capability: long",
504 {0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12},
505 7,
506 SHOULD_ERR,
507 2882400018,
508 },
509 {
510 "GR",
511 "GR capability",
512 {
513 /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
514 /* R-bit, time */ 0xf1, 0x12,
515 /* afi */ 0x0, 0x1,
516 /* safi */ 0x1,
517 /* flags */ 0xf,
518 /* afi */ 0x0, 0x2,
519 /* safi */ 0x1,
520 /* flags */ 0x0,
521 /* afi */ 0x0, 0x2,
522 /* safi */ 0x2,
523 /* flags */ 0x1,
524 },
525 16,
526 SHOULD_PARSE,
527 },
528 {
529 "GR-short",
530 "GR capability, but header length too short",
531 {
532 /* hdr */ 0x40, 0xa,
533 /* R-bit, time */ 0xf1, 0x12,
534 /* afi */ 0x0, 0x1,
535 /* safi */ 0x1,
536 /* flags */ 0xf,
537 /* afi */ 0x0, 0x2,
538 /* safi */ 0x1,
539 /* flags */ 0x0,
540 /* afi */ 0x0, 0x2,
541 /* safi */ 0x2,
542 /* flags */ 0x1,
543 },
544 15 /* array is 16 though */,
545 SHOULD_ERR,
546 },
547 {
548 "GR-long",
549 "GR capability, but header length too long",
550 {
551 /* hdr */ 0x40, 0xf,
552 /* R-bit, time */ 0xf1, 0x12,
553 /* afi */ 0x0, 0x1,
554 /* safi */ 0x1,
555 /* flags */ 0xf,
556 /* afi */ 0x0, 0x2,
557 /* safi */ 0x1,
558 /* flags */ 0x0,
559 /* afi */ 0x0, 0x2,
560 /* safi */ 0x2,
561 /* flags */ 0x01,
562 },
563 16,
564 SHOULD_ERR,
565 },
566 {
567 "GR-trunc",
568 "GR capability, but truncated",
569 {
570 /* hdr */ 0x40, 0xf,
571 /* R-bit, time */ 0xf1, 0x12,
572 /* afi */ 0x0, 0x1,
573 /* safi */ 0x1,
574 /* flags */ 0xf,
575 /* afi */ 0x0, 0x2,
576 /* safi */ 0x1,
577 /* flags */ 0x0,
578 /* afi */ 0x0, 0x2,
579 /* safi */ 0x2,
580 /* flags */ 0x1,
581 },
582 15,
583 SHOULD_ERR,
584 },
585 {
586 "GR-empty",
587 "GR capability, but empty.",
588 {
589 /* hdr */ 0x40, 0x0,
590 },
591 2,
592 SHOULD_ERR,
593 },
594 {
595 "MP-empty",
596 "MP capability, but empty.",
597 {
598 /* hdr */ 0x1, 0x0,
599 },
600 2,
601 SHOULD_ERR,
602 },
603 {
604 "ORF-empty",
605 "ORF capability, but empty.",
606 {
607 /* hdr */ 0x3, 0x0,
608 },
609 2,
610 SHOULD_ERR,
611 },
612 {
613 "AS4-empty",
614 "AS4 capability, but empty.",
615 {
616 /* hdr */ 0x41, 0x0,
617 },
618 2,
619 SHOULD_ERR,
620 },
621 {
622 "dyn-empty",
623 "Dynamic capability, but empty.",
624 {
625 /* hdr */ 0x42, 0x0,
626 },
627 2,
628 SHOULD_PARSE,
629 },
630 {
631 "dyn-old",
632 "Dynamic capability (deprecated version)",
633 {CAPABILITY_CODE_DYNAMIC, 0x0},
634 2,
635 SHOULD_PARSE,
636 },
637 {
638 "Role",
639 "Role capability",
640 {
641 /* hdr */ 0x9, 0x1,
642 0x1,
643 },
644 3,
645 SHOULD_PARSE,
646 },
647 {
648 "Role-long",
649 "Role capability, but too long",
650 {
651 /* hdr */ 0x9, 0x4,
652 0x0, 0x0, 0x0, 0x1,
653 },
654 6,
655 SHOULD_ERR,
656 },
657 {
658 "Role-empty",
659 "Role capability, but empty.",
660 {
661 /* hdr */ 0x9, 0x0,
662 },
663 2,
664 SHOULD_ERR,
665 },
666 {NULL, NULL, {0}, 0, 0}};
667
668 /* DYNAMIC message */
669 struct test_segment dynamic_cap_msgs[] = {
670 {
671 "DynCap",
672 "Dynamic Capability Message, IP/Multicast",
673 {0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2},
674 7,
675 SHOULD_PARSE, /* horrible alignment, just as with ORF */
676 },
677 {
678 "DynCapLong",
679 "Dynamic Capability Message, IP/Multicast, truncated",
680 {0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2},
681 5,
682 SHOULD_ERR,
683 },
684 {
685 "DynCapPadded",
686 "Dynamic Capability Message, IP/Multicast, padded",
687 {0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0},
688 8,
689 SHOULD_ERR, /* No way to tell padding from data.. */
690 },
691 {
692 "DynCapMPCpadded",
693 "Dynamic Capability Message, IP/Multicast, cap data padded",
694 {0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0},
695 8,
696 SHOULD_PARSE, /* You can though add padding to the capability
697 data */
698 },
699 {
700 "DynCapMPCoverflow",
701 "Dynamic Capability Message, IP/Multicast, cap data != length",
702 {0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0},
703 8,
704 SHOULD_ERR,
705 },
706 {NULL, NULL, {0}, 0, 0}};
707
708 /* Entire Optional-Parameters block */
709 struct test_segment opt_params[] = {
710 {
711 "Cap-singlets",
712 "One capability per Optional-Param",
713 {
714 0x02, 0x06, 0x01, 0x04,
715 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
716 0x02, 0x06, 0x01, 0x04,
717 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
718 0x02, 0x02, 0x80, 0x00, /* RR (old) */
719 0x02, 0x02, 0x02, 0x00, /* RR */
720 },
721 24,
722 SHOULD_PARSE,
723 },
724 {
725 "Cap-series",
726 "Series of capability, one Optional-Param",
727 {
728 0x02, 0x10, 0x01, 0x04, 0x00, 0x01, 0x00,
729 0x01, /* MP IPv4/Uni */
730 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
731 0x80, 0x00, /* RR (old) */
732 0x02, 0x00, /* RR */
733 },
734 18,
735 SHOULD_PARSE,
736 },
737 {
738 "AS4more",
739 "AS4 capability after other caps (singlets)",
740 {
741 0x02, 0x06, 0x01, 0x04,
742 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
743 0x02, 0x06, 0x01, 0x04,
744 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
745 0x02, 0x02, 0x80, 0x00, /* RR (old) */
746 0x02, 0x02, 0x02, 0x00, /* RR */
747 0x02, 0x06, 0x41, 0x04,
748 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
749 },
750 32,
751 SHOULD_PARSE,
752 196614,
753 },
754 {
755 "AS4series",
756 "AS4 capability, in series of capabilities",
757 {
758 0x02, 0x16, 0x01, 0x04, 0x00, 0x01,
759 0x00, 0x01, /* MP IPv4/Uni */
760 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
761 0x80, 0x00, /* RR (old) */
762 0x02, 0x00, /* RR */
763 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
764 },
765 24,
766 SHOULD_PARSE,
767 196614,
768 },
769 {
770 "AS4real",
771 "AS4 capability, in series of capabilities",
772 {
773 0x02, 0x06, 0x01, 0x04,
774 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
775 0x02, 0x06, 0x01, 0x04,
776 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
777 0x02, 0x02, 0x80, 0x00, /* RR old */
778 0x02, 0x02, 0x02, 0x00, /* RR */
779 0x02, 0x06, 0x41, 0x04,
780 0x00, 0x03, 0x00, 0x06, /* AS4 */
781 },
782 32,
783 SHOULD_PARSE,
784 196614,
785 },
786 {
787 "AS4real2",
788 "AS4 capability, in series of capabilities",
789 {
790 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, 0x02,
791 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, 0x02, 0x02,
792 0x80, 0x00, 0x02, 0x02, 0x02, 0x00, 0x02, 0x06, 0x41,
793 0x04, 0x00, 0x00, 0xfc, 0x03, 0x02, 0x09, 0x82, 0x07,
794 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03, 0x02, 0x09,
795 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
796 0x02, 0x02, 0x42, 0x00,
797 },
798 58,
799 SHOULD_PARSE,
800 64515,
801 },
802
803 {NULL, NULL, {0}, 0, 0}};
804
805 /* basic parsing test */
806 static void parse_test(struct peer *peer, struct test_segment *t, int type)
807 {
808 int ret;
809 int capability = 0;
810 as_t as4 = 0;
811 int oldfailed = failed;
812 int len = t->len;
813 #define RANDOM_FUZZ 35
814
815 stream_reset(peer->curr);
816 stream_put(peer->curr, NULL, RANDOM_FUZZ);
817 stream_set_getp(peer->curr, RANDOM_FUZZ);
818
819 switch (type) {
820 case CAPABILITY:
821 stream_putc(peer->curr, BGP_OPEN_OPT_CAP);
822 stream_putc(peer->curr, t->len);
823 break;
824 case DYNCAP:
825 /* for (i = 0; i < BGP_MARKER_SIZE; i++)
826 stream_putc (peer->, 0xff);
827 stream_putw (s, 0);
828 stream_putc (s, BGP_MSG_CAPABILITY);*/
829 break;
830 }
831 stream_write(peer->curr, t->data, t->len);
832
833 printf("%s: %s\n", t->name, t->desc);
834
835 switch (type) {
836 case CAPABILITY:
837 len += 2; /* to cover the OPT-Param header */
838 _FALLTHROUGH
839 case OPT_PARAM:
840 printf("len: %u\n", len);
841 /* peek_for_as4 wants getp at capibility*/
842 as4 = peek_for_as4_capability(peer, len);
843 printf("peek_for_as4: as4 is %u\n", as4);
844 /* and it should leave getp as it found it */
845 assert(stream_get_getp(peer->curr) == RANDOM_FUZZ);
846
847 ret = bgp_open_option_parse(peer, len, &capability);
848 break;
849 case DYNCAP:
850 ret = bgp_capability_receive(peer, t->len);
851 break;
852 default:
853 printf("unknown type %u\n", type);
854 exit(1);
855 }
856
857 if (ret != BGP_Stop && t->validate_afi) {
858 afi_t afi;
859 safi_t safi;
860
861 /* Convert AFI, SAFI to internal values, check. */
862 if (bgp_map_afi_safi_iana2int(t->afi, t->safi, &afi, &safi)) {
863 if (t->afi_valid == VALID_AFI)
864 failed++;
865 }
866 printf("MP: %u(%u)/%u(%u): recv %u, nego %u\n", t->afi, afi,
867 t->safi, safi, peer->afc_recv[afi][safi],
868 peer->afc_nego[afi][safi]);
869
870 if (t->afi_valid == VALID_AFI) {
871
872 if (!peer->afc_recv[afi][safi])
873 failed++;
874 if (!peer->afc_nego[afi][safi])
875 failed++;
876 }
877 }
878
879 if (as4 != t->peek_for) {
880 printf("as4 %u != %u\n", as4, t->peek_for);
881 failed++;
882 }
883
884 /*
885 * Some of the functions used return BGP_Stop on error and some return
886 * -1. If we have -1, keep it; if we have BGP_Stop, transform it to the
887 * correct pass/fail code
888 */
889 if (ret != -1)
890 ret = (ret == BGP_Stop) ? -1 : 0;
891
892 printf("parsed?: %s\n", ret ? "no" : "yes");
893
894 if (ret != t->parses) {
895 printf("t->parses: %d\nret: %d\n", t->parses, ret);
896 failed++;
897 }
898
899 if (tty)
900 printf("%s",
901 (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
902 : VT100_GREEN "OK" VT100_RESET);
903 else
904 printf("%s", (failed > oldfailed) ? "failed!" : "OK");
905
906 if (failed)
907 printf(" (%u)", failed);
908
909 printf("\n\n");
910 }
911
912 static struct bgp *bgp;
913 static as_t asn = 100;
914
915 int main(void)
916 {
917 struct peer *peer;
918 int i, j;
919
920 conf_bgp_debug_neighbor_events = -1UL;
921 conf_bgp_debug_packet = -1UL;
922 conf_bgp_debug_as4 = -1UL;
923 term_bgp_debug_neighbor_events = -1UL;
924 term_bgp_debug_packet = -1UL;
925 term_bgp_debug_as4 = -1UL;
926
927 qobj_init();
928 master = event_master_create(NULL);
929 bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
930 vrf_init(NULL, NULL, NULL, NULL);
931 bgp_option_set(BGP_OPT_NO_LISTEN);
932
933 frr_pthread_init();
934 bgp_pthreads_init();
935 bgp_pth_ka->running = true;
936
937 if (fileno(stdout) >= 0)
938 tty = isatty(fileno(stdout));
939
940 if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT, NULL,
941 ASNOTATION_PLAIN) < 0)
942 return -1;
943
944 peer = peer_create_accept(bgp);
945 peer->host = (char *)"foo";
946
947 for (i = AFI_IP; i < AFI_MAX; i++)
948 for (j = SAFI_UNICAST; j < SAFI_MAX; j++) {
949 peer->afc[i][j] = 1;
950 peer->afc_adv[i][j] = 1;
951 }
952
953 peer->curr = stream_new(BGP_MAX_PACKET_SIZE);
954
955 i = 0;
956 while (mp_segments[i].name)
957 parse_test(peer, &mp_segments[i++], CAPABILITY);
958
959 /* These tests assume mp_segments tests set at least
960 * one of the afc_nego's
961 */
962 i = 0;
963 while (test_segments[i].name)
964 parse_test(peer, &test_segments[i++], CAPABILITY);
965
966 i = 0;
967 while (misc_segments[i].name)
968 parse_test(peer, &misc_segments[i++], CAPABILITY);
969
970 i = 0;
971 while (opt_params[i].name)
972 parse_test(peer, &opt_params[i++], OPT_PARAM);
973
974 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
975 peer->status = Established;
976
977 i = 0;
978 while (dynamic_cap_msgs[i].name)
979 parse_test(peer, &dynamic_cap_msgs[i++], DYNCAP);
980
981 printf("failures: %d\n", failed);
982 return failed;
983 }