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