]> git.proxmox.com Git - mirror_frr.git/blame - tests/bgpd/test_capability.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / tests / bgpd / test_capability.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
d62a17ae 2/*
46f4a4d2 3 * Copyright (C) 2007 Sun Microsystems, Inc.
46f4a4d2
PJ
4 */
5
ed6ef902
PJ
6#include <zebra.h>
7
1bf9f027 8#include "qobj.h"
ed6ef902
PJ
9#include "vty.h"
10#include "stream.h"
11#include "privs.h"
12#include "memory.h"
3f9c7369 13#include "queue.h"
039f3a34 14#include "filter.h"
cadc5f33 15#include "frr_pthread.h"
ed6ef902 16
cadc5f33 17#include "bgpd/bgpd.c"
ed6ef902
PJ
18#include "bgpd/bgp_open.h"
19#include "bgpd/bgp_debug.h"
1dba254e 20#include "bgpd/bgp_packet.h"
ed6ef902 21
e08286bc
PJ
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
0b2aa3a0
PJ
27#define CAPABILITY 0
28#define DYNCAP 1
29#define OPT_PARAM 2
ed6ef902
PJ
30
31/* need these to link in libbgp */
fcf6dce7 32struct zebra_privs_t bgpd_privs = {};
cd9d0537 33struct event_loop *master = NULL;
ed6ef902
PJ
34
35static int failed = 0;
e08286bc 36static int tty = 0;
ed6ef902
PJ
37
38/* test segments to parse and validate, and use for other tests */
39static struct test_segment {
d62a17ae 40 const char *name;
41 const char *desc;
d7c0a89a 42 const uint8_t data[1024];
d62a17ae 43 int len;
ed6ef902
PJ
44#define SHOULD_PARSE 0
45#define SHOULD_ERR -1
d62a17ae 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;
6bba65f2
RW
51 iana_afi_t afi;
52 iana_safi_t safi;
e08286bc
PJ
53#define VALID_AFI 1
54#define INVALID_AFI 0
d62a17ae 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},
e08286bc
PJ
90};
91
d62a17ae 92static 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,
6bba65f2
RW
101 IANA_AFI_IPV4,
102 IANA_SAFI_UNICAST,
d62a17ae 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,
6bba65f2
RW
113 IANA_AFI_IPV6,
114 IANA_SAFI_UNICAST,
d62a17ae 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,
6bba65f2
RW
126 IANA_AFI_IPV4,
127 IANA_SAFI_MULTICAST,
d62a17ae 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,
6bba65f2 139 IANA_AFI_IPV6,
d62a17ae 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,
6bba65f2 152 IANA_AFI_IPV6,
d62a17ae 153 IANA_SAFI_MPLS_VPN,
154 VALID_AFI,
155 },
156 /* 8 */
157 {
158 "MP6",
399aedd6 159 "MP IP4/MPLS-labeled VPN",
d62a17ae 160 {CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80},
161 6,
162 SHOULD_PARSE,
163 0,
164 1,
6bba65f2 165 IANA_AFI_IPV4,
d62a17ae 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,
6bba65f2
RW
199 IANA_AFI_IPV4,
200 IANA_SAFI_UNICAST,
d62a17ae 201 VALID_AFI,
202 },
203 {NULL, NULL, {0}, 0, 0}};
e08286bc 204
9d303b37 205static struct test_segment misc_segments[] =
d62a17ae 206 {
9d303b37 207 /* 13 */
d62a17ae 208 {
9d303b37
DL
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,
d62a17ae 217 },
9d303b37 218 /* 14 */
d62a17ae 219 {
9d303b37
DL
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,
d62a17ae 261 },
9d303b37 262 /* 15 */
d62a17ae 263 {
9d303b37
DL
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.. */
d62a17ae 306 },
9d303b37
DL
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 */
d62a17ae 350 {
9d303b37
DL
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 */
d62a17ae 393 },
9d303b37 394 /* 18 */
d62a17ae 395 {
9d303b37
DL
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 */
d62a17ae 438 },
9d303b37 439 /* 17 */
d62a17ae 440 {
9d303b37
DL
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,
d62a17ae 483 },
9d303b37 484 /* 19 */
d62a17ae 485 {
9d303b37
DL
486 "AS4",
487 "AS4 capability",
488 {0x41, 0x4, 0xab, 0xcd, 0xef,
489 0x12}, /* AS: 2882400018 */
490 6,
491 SHOULD_PARSE,
492 2882400018,
d62a17ae 493 },
494 {
9d303b37
DL
495 "AS4",
496 "AS4 capability: short",
497 {0x41, 0x4, 0xab, 0xcd, 0xef}, /* AS: 2882400018 */
498 5,
499 SHOULD_ERR,
d62a17ae 500 },
501 {
9d303b37
DL
502 "AS4",
503 "AS4 capability: long",
504 {0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12},
505 7,
506 SHOULD_ERR,
507 2882400018,
d62a17ae 508 },
509 {
9d303b37
DL
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,
d62a17ae 527 },
528 {
9d303b37
DL
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,
d62a17ae 546 },
547 {
9d303b37
DL
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,
d62a17ae 565 },
566 {
9d303b37
DL
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,
d62a17ae 584 },
585 {
9d303b37
DL
586 "GR-empty",
587 "GR capability, but empty.",
588 {
589 /* hdr */ 0x40, 0x0,
590 },
591 2,
592 SHOULD_ERR,
d62a17ae 593 },
9d303b37
DL
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 },
d864dd9e
EB
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 },
9d303b37 666 {NULL, NULL, {0}, 0, 0}};
ed6ef902 667
0b2aa3a0 668/* DYNAMIC message */
d62a17ae 669struct 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}};
0b2aa3a0
PJ
707
708/* Entire Optional-Parameters block */
d62a17ae 709struct 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}};
0b2aa3a0 804
ed6ef902 805/* basic parsing test */
d62a17ae 806static void parse_test(struct peer *peer, struct test_segment *t, int type)
ed6ef902 807{
d62a17ae 808 int ret;
809 int capability = 0;
810 as_t as4 = 0;
811 int oldfailed = failed;
812 int len = t->len;
0b2aa3a0 813#define RANDOM_FUZZ 35
e9aac3a2
QY
814
815 stream_reset(peer->curr);
816 stream_put(peer->curr, NULL, RANDOM_FUZZ);
817 stream_set_getp(peer->curr, RANDOM_FUZZ);
d62a17ae 818
819 switch (type) {
820 case CAPABILITY:
e9aac3a2
QY
821 stream_putc(peer->curr, BGP_OPEN_OPT_CAP);
822 stream_putc(peer->curr, t->len);
d62a17ae 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 }
e9aac3a2 831 stream_write(peer->curr, t->data, t->len);
d62a17ae 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 */
bd27ea43 838 _FALLTHROUGH
d62a17ae 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 */
e9aac3a2 845 assert(stream_get_getp(peer->curr) == RANDOM_FUZZ);
d62a17ae 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
e9aac3a2 857 if (ret != BGP_Stop && t->validate_afi) {
d62a17ae 858 afi_t afi;
859 safi_t safi;
860
861 /* Convert AFI, SAFI to internal values, check. */
6bba65f2 862 if (bgp_map_afi_safi_iana2int(t->afi, t->safi, &afi, &safi)) {
d62a17ae 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
becedef6
QY
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 */
e9aac3a2
QY
889 if (ret != -1)
890 ret = (ret == BGP_Stop) ? -1 : 0;
891
d62a17ae 892 printf("parsed?: %s\n", ret ? "no" : "yes");
893
e9aac3a2
QY
894 if (ret != t->parses) {
895 printf("t->parses: %d\nret: %d\n", t->parses, ret);
d62a17ae 896 failed++;
e9aac3a2 897 }
d62a17ae 898
899 if (tty)
9d303b37
DL
900 printf("%s",
901 (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
902 : VT100_GREEN "OK" VT100_RESET);
d62a17ae 903 else
904 printf("%s", (failed > oldfailed) ? "failed!" : "OK");
905
906 if (failed)
907 printf(" (%u)", failed);
908
909 printf("\n\n");
ed6ef902
PJ
910}
911
912static struct bgp *bgp;
913static as_t asn = 100;
914
d62a17ae 915int main(void)
ed6ef902 916{
d62a17ae 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();
ce50d11c 928 master = event_master_create(NULL);
733367c0 929 bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
ac2cb9bf 930 vrf_init(NULL, NULL, NULL, NULL);
d62a17ae 931 bgp_option_set(BGP_OPT_NO_LISTEN);
932
df54f053 933 frr_pthread_init();
cadc5f33 934 bgp_pthreads_init();
1ac267a2 935 bgp_pth_ka->running = true;
cadc5f33 936
d62a17ae 937 if (fileno(stdout) >= 0)
938 tty = isatty(fileno(stdout));
939
e55b0883
PG
940 if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT, NULL,
941 ASNOTATION_PLAIN) < 0)
d62a17ae 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
556beacf 953 peer->curr = stream_new(BGP_MAX_PACKET_SIZE);
e9aac3a2 954
d62a17ae 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;
ed6ef902 983}