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