]> git.proxmox.com Git - mirror_frr.git/blame - tests/bgpd/test_capability.c
lib: handle frr_pthread_init/fini in libfrr init
[mirror_frr.git] / tests / bgpd / test_capability.c
CommitLineData
d62a17ae 1/*
46f4a4d2
PJ
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 *
896014f4
DL
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
46f4a4d2
PJ
19 */
20
ed6ef902
PJ
21#include <zebra.h>
22
1bf9f027 23#include "qobj.h"
ed6ef902
PJ
24#include "vty.h"
25#include "stream.h"
26#include "privs.h"
27#include "memory.h"
3f9c7369 28#include "queue.h"
039f3a34 29#include "filter.h"
cadc5f33 30#include "frr_pthread.h"
ed6ef902 31
cadc5f33 32#include "bgpd/bgpd.c"
ed6ef902
PJ
33#include "bgpd/bgp_open.h"
34#include "bgpd/bgp_debug.h"
1dba254e 35#include "bgpd/bgp_packet.h"
ed6ef902 36
e08286bc
PJ
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
0b2aa3a0
PJ
42#define CAPABILITY 0
43#define DYNCAP 1
44#define OPT_PARAM 2
ed6ef902
PJ
45
46/* need these to link in libbgp */
47struct zebra_privs_t *bgpd_privs = NULL;
48struct thread_master *master = NULL;
49
50static int failed = 0;
e08286bc 51static int tty = 0;
ed6ef902
PJ
52
53/* test segments to parse and validate, and use for other tests */
54static struct test_segment {
d62a17ae 55 const char *name;
56 const char *desc;
d7c0a89a 57 const uint8_t data[1024];
d62a17ae 58 int len;
ed6ef902
PJ
59#define SHOULD_PARSE 0
60#define SHOULD_ERR -1
d62a17ae 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;
6bba65f2
RW
66 iana_afi_t afi;
67 iana_safi_t safi;
e08286bc
PJ
68#define VALID_AFI 1
69#define INVALID_AFI 0
d62a17ae 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},
e08286bc
PJ
105};
106
d62a17ae 107static 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,
6bba65f2
RW
116 IANA_AFI_IPV4,
117 IANA_SAFI_UNICAST,
d62a17ae 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,
6bba65f2
RW
128 IANA_AFI_IPV6,
129 IANA_SAFI_UNICAST,
d62a17ae 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,
6bba65f2
RW
141 IANA_AFI_IPV4,
142 IANA_SAFI_MULTICAST,
d62a17ae 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,
6bba65f2 154 IANA_AFI_IPV6,
d62a17ae 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,
6bba65f2 167 IANA_AFI_IPV6,
d62a17ae 168 IANA_SAFI_MPLS_VPN,
169 VALID_AFI,
170 },
171 /* 8 */
172 {
173 "MP6",
399aedd6 174 "MP IP4/MPLS-labeled VPN",
d62a17ae 175 {CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80},
176 6,
177 SHOULD_PARSE,
178 0,
179 1,
6bba65f2 180 IANA_AFI_IPV4,
d62a17ae 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,
6bba65f2
RW
214 IANA_AFI_IPV4,
215 IANA_SAFI_UNICAST,
d62a17ae 216 VALID_AFI,
217 },
218 {NULL, NULL, {0}, 0, 0}};
e08286bc 219
9d303b37 220static struct test_segment misc_segments[] =
d62a17ae 221 {
9d303b37 222 /* 13 */
d62a17ae 223 {
9d303b37
DL
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,
d62a17ae 232 },
9d303b37 233 /* 14 */
d62a17ae 234 {
9d303b37
DL
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,
d62a17ae 276 },
9d303b37 277 /* 15 */
d62a17ae 278 {
9d303b37
DL
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.. */
d62a17ae 321 },
9d303b37
DL
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 */
d62a17ae 365 {
9d303b37
DL
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 */
d62a17ae 408 },
9d303b37 409 /* 18 */
d62a17ae 410 {
9d303b37
DL
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 */
d62a17ae 453 },
9d303b37 454 /* 17 */
d62a17ae 455 {
9d303b37
DL
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,
d62a17ae 498 },
9d303b37 499 /* 19 */
d62a17ae 500 {
9d303b37
DL
501 "AS4",
502 "AS4 capability",
503 {0x41, 0x4, 0xab, 0xcd, 0xef,
504 0x12}, /* AS: 2882400018 */
505 6,
506 SHOULD_PARSE,
507 2882400018,
d62a17ae 508 },
509 {
9d303b37
DL
510 "AS4",
511 "AS4 capability: short",
512 {0x41, 0x4, 0xab, 0xcd, 0xef}, /* AS: 2882400018 */
513 5,
514 SHOULD_ERR,
d62a17ae 515 },
516 {
9d303b37
DL
517 "AS4",
518 "AS4 capability: long",
519 {0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12},
520 7,
521 SHOULD_ERR,
522 2882400018,
d62a17ae 523 },
524 {
9d303b37
DL
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,
d62a17ae 542 },
543 {
9d303b37
DL
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,
d62a17ae 561 },
562 {
9d303b37
DL
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,
d62a17ae 580 },
581 {
9d303b37
DL
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,
d62a17ae 599 },
600 {
9d303b37
DL
601 "GR-empty",
602 "GR capability, but empty.",
603 {
604 /* hdr */ 0x40, 0x0,
605 },
606 2,
607 SHOULD_ERR,
d62a17ae 608 },
9d303b37
DL
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}};
ed6ef902 653
0b2aa3a0 654/* DYNAMIC message */
d62a17ae 655struct 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}};
0b2aa3a0
PJ
693
694/* Entire Optional-Parameters block */
d62a17ae 695struct 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}};
0b2aa3a0 790
ed6ef902 791/* basic parsing test */
d62a17ae 792static void parse_test(struct peer *peer, struct test_segment *t, int type)
ed6ef902 793{
d62a17ae 794 int ret;
795 int capability = 0;
796 as_t as4 = 0;
797 int oldfailed = failed;
798 int len = t->len;
0b2aa3a0 799#define RANDOM_FUZZ 35
e9aac3a2
QY
800
801 stream_reset(peer->curr);
802 stream_put(peer->curr, NULL, RANDOM_FUZZ);
803 stream_set_getp(peer->curr, RANDOM_FUZZ);
d62a17ae 804
805 switch (type) {
806 case CAPABILITY:
e9aac3a2
QY
807 stream_putc(peer->curr, BGP_OPEN_OPT_CAP);
808 stream_putc(peer->curr, t->len);
d62a17ae 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 }
e9aac3a2 817 stream_write(peer->curr, t->data, t->len);
d62a17ae 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 */
bd27ea43 824 _FALLTHROUGH
d62a17ae 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 */
e9aac3a2 831 assert(stream_get_getp(peer->curr) == RANDOM_FUZZ);
d62a17ae 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
e9aac3a2 843 if (ret != BGP_Stop && t->validate_afi) {
d62a17ae 844 afi_t afi;
845 safi_t safi;
846
847 /* Convert AFI, SAFI to internal values, check. */
6bba65f2 848 if (bgp_map_afi_safi_iana2int(t->afi, t->safi, &afi, &safi)) {
d62a17ae 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
becedef6
QY
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 */
e9aac3a2
QY
875 if (ret != -1)
876 ret = (ret == BGP_Stop) ? -1 : 0;
877
d62a17ae 878 printf("parsed?: %s\n", ret ? "no" : "yes");
879
e9aac3a2
QY
880 if (ret != t->parses) {
881 printf("t->parses: %d\nret: %d\n", t->parses, ret);
d62a17ae 882 failed++;
e9aac3a2 883 }
d62a17ae 884
885 if (tty)
9d303b37
DL
886 printf("%s",
887 (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
888 : VT100_GREEN "OK" VT100_RESET);
d62a17ae 889 else
890 printf("%s", (failed > oldfailed) ? "failed!" : "OK");
891
892 if (failed)
893 printf(" (%u)", failed);
894
895 printf("\n\n");
ed6ef902
PJ
896}
897
898static struct bgp *bgp;
899static as_t asn = 100;
900
d62a17ae 901int main(void)
ed6ef902 902{
d62a17ae 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);
ecbc5a37 916 vrf_init(NULL, NULL, NULL, NULL, NULL);
d62a17ae 917 bgp_option_set(BGP_OPT_NO_LISTEN);
918
cadc5f33 919 bgp_pthreads_init();
1ac267a2 920 bgp_pth_ka->running = true;
cadc5f33 921
d62a17ae 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
e9aac3a2
QY
937 peer->curr = stream_new(BGP_MAX_PACKET_SIZE);
938
d62a17ae 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;
ed6ef902 967}