]> git.proxmox.com Git - mirror_frr.git/blob - tests/bgpd/test_mp_attr.c
af9e5791b70a51e046a5ce2c394654d166ec6c99
[mirror_frr.git] / tests / bgpd / test_mp_attr.c
1 /*
2 * Copyright (C) 2008 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
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_attr.h"
33 #include "bgpd/bgp_open.h"
34 #include "bgpd/bgp_debug.h"
35 #include "bgpd/bgp_route.h"
36 #include "bgpd/bgp_packet.h"
37 #include "bgpd/bgp_mplsvpn.h"
38 #include "bgpd/bgp_nexthop.h"
39 #include "bgpd/bgp_vty.h"
40 #include "bgpd/bgp_network.h"
41
42 #define VT100_RESET "\x1b[0m"
43 #define VT100_RED "\x1b[31m"
44 #define VT100_GREEN "\x1b[32m"
45 #define VT100_YELLOW "\x1b[33m"
46
47 #define CAPABILITY 0
48 #define DYNCAP 1
49 #define OPT_PARAM 2
50
51 /* need these to link in libbgp */
52 struct zebra_privs_t *bgpd_privs = NULL;
53 struct thread_master *master = NULL;
54
55 static int failed = 0;
56 static int tty = 0;
57
58 /* test segments to parse and validate, and use for other tests */
59 static struct test_segment {
60 const char *name;
61 const char *desc;
62 const uint8_t data[1024];
63 int len;
64 #define SHOULD_PARSE 0
65 #define SHOULD_ERR -1
66 int parses; /* whether it should parse or not */
67 } mp_reach_segments[] = {
68 {
69 "IPv6",
70 "IPV6 MP Reach, global nexthop, 1 NLRI",
71 {
72 /* AFI / SAFI */ 0x0,
73 AFI_IP6,
74 SAFI_UNICAST,
75 /* nexthop bytes */ 16,
76 /* Nexthop (global) */ 0xff,
77 0xfe,
78 0x1,
79 0x2,
80 0xaa,
81 0xbb,
82 0xcc,
83 0xdd,
84 0x3,
85 0x4,
86 0x5,
87 0x6,
88 0xa1,
89 0xa2,
90 0xa3,
91 0xa4,
92 /* SNPA (defunct, MBZ) */ 0x0,
93 /* NLRI tuples */ 32,
94 0xff,
95 0xfe,
96 0x1,
97 0x2, /* fffe:102::/32 */
98 },
99 (4 + 16 + 1 + 5),
100 SHOULD_PARSE,
101 },
102 {
103 "IPv6-2",
104 "IPV6 MP Reach, global nexthop, 2 NLRIs",
105 {
106 /* AFI / SAFI */ 0x0,
107 AFI_IP6,
108 SAFI_UNICAST,
109 /* nexthop bytes */ 16,
110 /* Nexthop (global) */ 0xff,
111 0xfe,
112 0x1,
113 0x2, /* ffee:102:... */
114 0xaa,
115 0xbb,
116 0xcc,
117 0xdd,
118 0x3,
119 0x4,
120 0x5,
121 0x6,
122 0xa1,
123 0xa2,
124 0xa3,
125 0xa4,
126 /* SNPA (defunct, MBZ) */ 0x0,
127 /* NLRI tuples */ 32,
128 0xff,
129 0xfe,
130 0x1,
131 0x2, /* fffe:102::/32 */
132 64,
133 0xff,
134 0xfe,
135 0x0,
136 0x1, /* fffe:1:2:3::/64 */
137 0x0,
138 0x2,
139 0x0,
140 0x3,
141 },
142 (4 + 16 + 1 + 5 + 9),
143 SHOULD_PARSE,
144 },
145 {
146 "IPv6-default",
147 "IPV6 MP Reach, global nexthop, 2 NLRIs + default",
148 {
149 /* AFI / SAFI */ 0x0,
150 AFI_IP6,
151 SAFI_UNICAST,
152 /* nexthop bytes */ 16,
153 /* Nexthop (global) */ 0xff,
154 0xfe,
155 0x1,
156 0x2,
157 0xaa,
158 0xbb,
159 0xcc,
160 0xdd,
161 0x3,
162 0x4,
163 0x5,
164 0x6,
165 0xa1,
166 0xa2,
167 0xa3,
168 0xa4,
169 /* SNPA (defunct, MBZ) */ 0x0,
170 /* NLRI tuples */ 32,
171 0xff,
172 0xfe,
173 0x1,
174 0x2, /* fffe:102::/32 */
175 64,
176 0xff,
177 0xfe,
178 0x0,
179 0x1, /* fffe:1:2:3::/64 */
180 0x0,
181 0x2,
182 0x0,
183 0x3,
184 0x0, /* ::/0 */
185 },
186 (4 + 16 + 1 + 5 + 9 + 1),
187 SHOULD_PARSE,
188 },
189 {
190 "IPv6-lnh",
191 "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default",
192 {
193 /* AFI / SAFI */ 0x0,
194 AFI_IP6,
195 SAFI_UNICAST,
196 /* nexthop bytes */ 32,
197 /* Nexthop (global) */ 0xff,
198 0xfe,
199 0x1,
200 0x2, /* fffe:102:... */
201 0xaa,
202 0xbb,
203 0xcc,
204 0xdd,
205 0x3,
206 0x4,
207 0x5,
208 0x6,
209 0xa1,
210 0xa2,
211 0xa3,
212 0xa4,
213 /* Nexthop (local) */ 0xfe,
214 0x80,
215 0x0,
216 0x0, /* fe80::210:2ff:.. */
217 0x0,
218 0x0,
219 0x0,
220 0x0,
221 0x2,
222 0x10,
223 0x2,
224 0xff,
225 0x1,
226 0x2,
227 0x3,
228 0x4,
229 /* SNPA (defunct, MBZ) */ 0x0,
230 /* NLRI tuples */ 32,
231 0xff,
232 0xfe,
233 0x1,
234 0x2, /* fffe:102::/32 */
235 64,
236 0xff,
237 0xfe,
238 0x0,
239 0x1, /* fffe:1:2:3::/64 */
240 0x0,
241 0x2,
242 0x0,
243 0x3,
244 0x0, /* ::/0 */
245 },
246 (4 + 32 + 1 + 5 + 9 + 1),
247 SHOULD_PARSE,
248 },
249 {
250 "IPv6-nhlen",
251 "IPV6 MP Reach, inappropriate nexthop length",
252 {
253 /* AFI / SAFI */ 0x0,
254 AFI_IP6,
255 SAFI_UNICAST,
256 /* nexthop bytes */ 4,
257 /* Nexthop (global) */ 0xff,
258 0xfe,
259 0x1,
260 0x2, /* fffe:102:... */
261 0xaa,
262 0xbb,
263 0xcc,
264 0xdd,
265 0x3,
266 0x4,
267 0x5,
268 0x6,
269 0xa1,
270 0xa2,
271 0xa3,
272 0xa4,
273 /* Nexthop (local) */ 0xfe,
274 0x80,
275 0x0,
276 0x0, /* fe80::210:2ff:.. */
277 0x0,
278 0x0,
279 0x0,
280 0x0,
281 0x2,
282 0x10,
283 0x2,
284 0xff,
285 0x1,
286 0x2,
287 0x3,
288 0x4,
289 /* SNPA (defunct, MBZ) */ 0x0,
290 /* NLRI tuples */ 32,
291 0xff,
292 0xfe,
293 0x1,
294 0x2, /* fffe:102::/32 */
295 64,
296 0xff,
297 0xfe,
298 0x0,
299 0x1, /* fffe:1:2:3::/64 */
300 0x0,
301 0x2,
302 0x0,
303 0x3,
304 0x0, /* ::/0 */
305 },
306 (4 + 32 + 1 + 5 + 9 + 1),
307 SHOULD_ERR,
308 },
309 {
310 "IPv6-nhlen2",
311 "IPV6 MP Reach, invalid nexthop length",
312 {
313 /* AFI / SAFI */ 0x0,
314 AFI_IP6,
315 SAFI_UNICAST,
316 /* nexthop bytes */ 5,
317 /* Nexthop (global) */ 0xff,
318 0xfe,
319 0x1,
320 0x2, /* fffe:102:... */
321 0xaa,
322 0xbb,
323 0xcc,
324 0xdd,
325 0x3,
326 0x4,
327 0x5,
328 0x6,
329 0xa1,
330 0xa2,
331 0xa3,
332 0xa4,
333 /* Nexthop (local) */ 0xfe,
334 0x80,
335 0x0,
336 0x0, /* fe80::210:2ff:.. */
337 0x0,
338 0x0,
339 0x0,
340 0x0,
341 0x2,
342 0x10,
343 0x2,
344 0xff,
345 0x1,
346 0x2,
347 0x3,
348 0x4,
349 /* SNPA (defunct, MBZ) */ 0x0,
350 /* NLRI tuples */ 32,
351 0xff,
352 0xfe,
353 0x1,
354 0x2, /* fffe:102::/32 */
355 64,
356 0xff,
357 0xfe,
358 0x0,
359 0x1, /* fffe:1:2:3::/64 */
360 0x0,
361 0x2,
362 0x0,
363 0x3,
364 0x0, /* ::/0 */
365 },
366 (4 + 32 + 1 + 5 + 9 + 1),
367 SHOULD_ERR,
368 },
369 {
370 "IPv6-nhlen3",
371 "IPV6 MP Reach, nexthop length overflow",
372 {
373 /* AFI / SAFI */ 0x0,
374 AFI_IP6,
375 SAFI_UNICAST,
376 /* nexthop bytes */ 32,
377 /* Nexthop (global) */ 0xff,
378 0xfe,
379 0x1,
380 0x2, /* fffe:102:... */
381 0xaa,
382 0xbb,
383 0xcc,
384 0xdd,
385 0x3,
386 0x4,
387 0x5,
388 0x6,
389 0xa1,
390 0xa2,
391 0xa3,
392 0xa4,
393 },
394 (4 + 16),
395 SHOULD_ERR,
396 },
397 {
398 "IPv6-nhlen4",
399 "IPV6 MP Reach, nexthop length short",
400 {
401 /* AFI / SAFI */ 0x0,
402 AFI_IP6,
403 SAFI_UNICAST,
404 /* nexthop bytes */ 16,
405 /* Nexthop (global) */ 0xff,
406 0xfe,
407 0x1,
408 0x2, /* fffe:102:... */
409 0xaa,
410 0xbb,
411 0xcc,
412 0xdd,
413 0x3,
414 0x4,
415 0x5,
416 0x6,
417 0xa1,
418 0xa2,
419 0xa3,
420 0xa4,
421 /* Nexthop (local) */ 0xfe,
422 0x80,
423 0x0,
424 0x0, /* fe80::210:2ff:.. */
425 0x0,
426 0x0,
427 0x0,
428 0x0,
429 0x2,
430 0x10,
431 0x2,
432 0xff,
433 0x1,
434 0x2,
435 0x3,
436 0x4,
437 /* SNPA (defunct, MBZ) */ 0x0,
438 /* NLRI tuples */ 32,
439 0xff,
440 0xfe,
441 0x1,
442 0x2, /* fffe:102::/32 */
443 64,
444 0xff,
445 0xfe,
446 0x0,
447 0x1, /* fffe:1:2:3::/64 */
448 0x0,
449 0x2,
450 0x0,
451 0x3,
452 0x0, /* ::/0 */
453 },
454 (4 + 32 + 1 + 5 + 9 + 1),
455 SHOULD_ERR,
456 },
457 {
458 "IPv6-nlri",
459 "IPV6 MP Reach, NLRI bitlen overflow",
460 {
461 /* AFI / SAFI */ 0x0,
462 AFI_IP6,
463 SAFI_UNICAST,
464 /* nexthop bytes */ 32,
465 /* Nexthop (global) */ 0xff,
466 0xfe,
467 0x1,
468 0x2, /* fffe:102:... */
469 0xaa,
470 0xbb,
471 0xcc,
472 0xdd,
473 0x3,
474 0x4,
475 0x5,
476 0x6,
477 0xa1,
478 0xa2,
479 0xa3,
480 0xa4,
481 /* Nexthop (local) */ 0xfe,
482 0x80,
483 0x0,
484 0x0, /* fe80::210:2ff:.. */
485 0x0,
486 0x0,
487 0x0,
488 0x0,
489 0x2,
490 0x10,
491 0x2,
492 0xff,
493 0x1,
494 0x2,
495 0x3,
496 0x4,
497 /* SNPA (defunct, MBZ) */ 0x0,
498 /* NLRI tuples */ 120,
499 0xff,
500 0xfe,
501 0x1,
502 0x2, /* fffe:102::/32 */
503 64,
504 0xff,
505 0xfe,
506 0x0,
507 0x1, /* fffe:1:2:3::/64 */
508 0x0,
509 0x2,
510 0x0,
511 0x3,
512 0, /* ::/0 */
513 },
514 (4 + 32 + 1 + 5 + 9 + 1),
515 SHOULD_ERR,
516 },
517 {
518 "IPv4",
519 "IPv4 MP Reach, 2 NLRIs + default",
520 {
521 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
522 /* nexthop bytes */ 4,
523 /* Nexthop */ 192, 168, 0, 1,
524 /* SNPA (defunct, MBZ) */ 0x0,
525 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
526 17, 10, 2, 3, /* 10.2.3/17 */
527 0, /* 0/0 */
528 },
529 (4 + 4 + 1 + 3 + 4 + 1),
530 SHOULD_PARSE,
531 },
532 {
533 "IPv4-nhlen",
534 "IPv4 MP Reach, nexthop lenth overflow",
535 {
536 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
537 /* nexthop bytes */ 32,
538 /* Nexthop */ 192, 168, 0, 1,
539 /* SNPA (defunct, MBZ) */ 0x0,
540 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
541 17, 10, 2, 3, /* 10.2.3/17 */
542 0, /* 0/0 */
543 },
544 (4 + 4 + 1 + 3 + 4 + 1),
545 SHOULD_ERR,
546 },
547 {
548 "IPv4-nlrilen",
549 "IPv4 MP Reach, nlri lenth overflow",
550 {
551 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
552 /* nexthop bytes */ 4,
553 /* Nexthop */ 192, 168, 0, 1,
554 /* SNPA (defunct, MBZ) */ 0x0,
555 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
556 30, 10, 0, /* 0/0 */
557 },
558 (4 + 4 + 1 + 3 + 2 + 1),
559 SHOULD_ERR,
560 },
561 {
562 "IPv4-VPNv4",
563 "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs",
564 {
565 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
566 /* nexthop bytes */ 12,
567 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
568 0, 0, 0, 0,
569 /* Nexthop */ 192, 168, 0, 1,
570 /* SNPA (defunct, MBZ) */ 0x0,
571 /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */
572 /* rd, 8 octets */
573 0, 0, /* RD_TYPE_AS */
574 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
575 10, 1, /* 10.1/16 */
576 88 + 17, 0xff, 0, 0, /* tag */
577 /* rd, 8 octets */
578 0, 0, /* RD_TYPE_IP */
579 192, 168, 0, 1, /* IPv4 */
580 10, 2, 3, /* 10.2.3/17 */
581 },
582 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3)),
583 SHOULD_PARSE,
584 },
585 {
586 "IPv4-VPNv4-bogus-plen",
587 "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len",
588 {
589 /* AFI / SAFI */ 0x0,
590 AFI_IP,
591 IANA_SAFI_MPLS_VPN,
592 /* nexthop bytes */ 12,
593 /* RD */ 0,
594 0,
595 1,
596 2,
597 0,
598 0xff,
599 3,
600 4,
601 /* Nexthop */ 192,
602 168,
603 0,
604 1,
605 /* SNPA (defunct, MBZ) */ 0x0,
606 /* NLRI tuples */ 16,
607 10,
608 1, /* 10.1/16 */
609 17,
610 10,
611 2,
612 3, /* 10.2.3/17 */
613 0, /* 0/0 */
614 },
615 (3 + 1 + 3 * 4 + 1 + 3 + 4 + 1),
616 SHOULD_ERR,
617 },
618 {
619 "IPv4-VPNv4-plen1-short",
620 "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short",
621 {
622 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
623 /* nexthop bytes */ 12,
624 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
625 0, 0, 0, 0,
626 /* Nexthop */ 192, 168, 0, 1,
627 /* SNPA (defunct, MBZ) */ 0x0,
628 /* NLRI tuples */ 88 + 1, 0, 1, 2, /* tag */
629 /* rd, 8 octets */
630 0, 0, /* RD_TYPE_AS */
631 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
632 10, 1, /* 10.1/16 */
633 88 + 17, 0xff, 0, 0, /* tag */
634 /* rd, 8 octets */
635 0, 0, /* RD_TYPE_IP */
636 192, 168, 0, 1, /* IPv4 */
637 10, 2, 3, /* 10.2.3/17 */
638 },
639 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3)),
640 SHOULD_ERR,
641 },
642 {
643 "IPv4-VPNv4-plen1-long",
644 "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long",
645 {
646 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
647 /* nexthop bytes */ 12,
648 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
649 0, 0, 0, 0,
650 /* Nexthop */ 192, 168, 0, 1,
651 /* SNPA (defunct, MBZ) */ 0x0,
652 /* NLRI tuples */ 88 + 32, 0, 1, 2, /* tag */
653 /* rd, 8 octets */
654 0, 0, /* RD_TYPE_AS */
655 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
656 10, 1, /* 10.1/16 */
657 88 + 17, 0xff, 0, 0, /* tag */
658 /* rd, 8 octets */
659 0, 0, /* RD_TYPE_IP */
660 192, 168, 0, 1, /* IPv4 */
661 10, 2, 3, /* 10.2.3/17 */
662 },
663 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3)),
664 SHOULD_ERR,
665 },
666 {
667 "IPv4-VPNv4-plenn-long",
668 "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long",
669 {
670 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
671 /* nexthop bytes */ 12,
672 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
673 0, 0, 0, 0,
674 /* Nexthop */ 192, 168, 0, 1,
675 /* SNPA (defunct, MBZ) */ 0x0,
676 /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */
677 /* rd, 8 octets */
678 0, 0, /* RD_TYPE_AS */
679 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
680 10, 1, /* 10.1/16 */
681 88 + 17, 0xff, 0, 0, /* tag */
682 /* rd, 8 octets */
683 0, 0, /* RD_TYPE_IP */
684 192, 168, 0, 1, /* IPv4 */
685 10, 2, 3, /* 10.2.3/17 */
686 88 + 1, /* bogus */
687 },
688 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3) + 1),
689 SHOULD_ERR,
690 },
691 {
692 "IPv4-VPNv4-plenn-short",
693 "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short",
694 {
695 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
696 /* nexthop bytes */ 12,
697 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
698 0, 0, 0, 0,
699 /* Nexthop */ 192, 168, 0, 1,
700 /* SNPA (defunct, MBZ) */ 0x0,
701 /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */
702 /* rd, 8 octets */
703 0, 0, /* RD_TYPE_AS */
704 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
705 10, 1, /* 10.1/16 */
706 88 + 2, 0xff, 0, 0, /* tag */
707 /* rd, 8 octets */
708 0, 0, /* RD_TYPE_IP */
709 192, 168, 0, 1, /* IPv4 */
710 10, 2, 3, /* 10.2.3/17 */
711 },
712 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3)),
713 SHOULD_ERR,
714 },
715 {
716 "IPv4-VPNv4-bogus-rd-type",
717 "IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)",
718 {
719 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
720 /* nexthop bytes */ 12,
721 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
722 0, 0, 0, 0,
723 /* Nexthop */ 192, 168, 0, 1,
724 /* SNPA (defunct, MBZ) */ 0x0,
725 /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */
726 /* rd, 8 octets */
727 0xff, 0, /* Bogus RD */
728 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
729 10, 1, /* 10.1/16 */
730 88 + 17, 0xff, 0, 0, /* tag */
731 /* rd, 8 octets */
732 0, 0, /* RD_TYPE_IP */
733 192, 168, 0, 1, /* IPv4 */
734 10, 2, 3, /* 10.2.3/17 */
735 },
736 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3)),
737 SHOULD_PARSE,
738 },
739 {
740 "IPv4-VPNv4-0-nlri",
741 "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus",
742 {
743 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
744 /* nexthop bytes */ 12,
745 /* RD */ 0, 0, 0, 0, /* RD defined to be 0 */
746 0, 0, 0, 0,
747 /* Nexthop */ 192, 168, 0, 1,
748 /* SNPA (defunct, MBZ) */ 0x0,
749 /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */
750 /* rd, 8 octets */
751 0, 0, /* RD_TYPE_AS */
752 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
753 10, 1, /* 10.1/16 */
754 88 + 17, 0xff, 0, 0, /* tag */
755 /* rd, 8 octets */
756 0, 0, /* RD_TYPE_IP */
757 192, 168, 0, 1, /* IPv4 */
758 10, 2, 3, /* 10.2.3/17 */
759 0 /* 0/0, bogus for vpnv4 ?? */
760 },
761 (4 + 12 + 1 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3) + 1),
762 SHOULD_ERR,
763 },
764
765 /* From bug #385 */
766 {
767 "IPv6-bug",
768 "IPv6, global nexthop, 1 default NLRI",
769 {
770 /* AFI / SAFI */ 0x0,
771 0x2,
772 0x1,
773 /* nexthop bytes */ 0x20,
774 /* Nexthop (global) */ 0x20,
775 0x01,
776 0x04,
777 0x70,
778 0x00,
779 0x01,
780 0x00,
781 0x06,
782 0x00,
783 0x00,
784 0x00,
785 0x00,
786 0x00,
787 0x00,
788 0x00,
789 0x01,
790 /* Nexthop (local) */ 0xfe,
791 0x80,
792 0x00,
793 0x00,
794 0x00,
795 0x00,
796 0x00,
797 0x00,
798 0x02,
799 0x0c,
800 0xdb,
801 0xff,
802 0xfe,
803 0xfe,
804 0xeb,
805 0x00,
806 /* SNPA (defunct, MBZ) */ 0,
807 /* NLRI tuples */ /* Should have 0 here for ::/0, but
808 dont */
809 },
810 37,
811 SHOULD_ERR,
812 },
813 {
814 .name = "IPv4",
815 .desc = "IPV4 MP Reach, flowspec, 1 NLRI",
816 .data = {
817 /* AFI / SAFI */ 0x0,
818 AFI_IP,
819 IANA_SAFI_FLOWSPEC,
820 0x00, /* no NH */
821 0x00,
822 0x06, /* FS Length */
823 0x01, /* FS dest prefix ID */
824 0x1e, /* IP */
825 0x1e,
826 0x28,
827 0x28,
828 0x0
829 },
830 .len = 12,
831 .parses = SHOULD_PARSE,
832 },
833 {NULL, NULL, {0}, 0, 0}};
834
835 /* MP_UNREACH_NLRI tests */
836 static struct test_segment mp_unreach_segments[] = {
837 {
838 "IPv6-unreach",
839 "IPV6 MP Unreach, 1 NLRI",
840 {
841 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
842 /* NLRI tuples */ 32, 0xff, 0xfe, 0x1,
843 0x2, /* fffe:102::/32 */
844 },
845 (3 + 5),
846 SHOULD_PARSE,
847 },
848 {
849 "IPv6-unreach2",
850 "IPV6 MP Unreach, 2 NLRIs",
851 {
852 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
853 /* NLRI tuples */ 32, 0xff, 0xfe, 0x1,
854 0x2, /* fffe:102::/32 */
855 64, 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
856 0x0, 0x2, 0x0, 0x3,
857 },
858 (3 + 5 + 9),
859 SHOULD_PARSE,
860 },
861 {
862 "IPv6-unreach-default",
863 "IPV6 MP Unreach, 2 NLRIs + default",
864 {
865 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
866 /* NLRI tuples */ 32, 0xff, 0xfe, 0x1,
867 0x2, /* fffe:102::/32 */
868 64, 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
869 0x0, 0x2, 0x0, 0x3, 0x0, /* ::/0 */
870 },
871 (3 + 5 + 9 + 1),
872 SHOULD_PARSE,
873 },
874 {
875 "IPv6-unreach-nlri",
876 "IPV6 MP Unreach, NLRI bitlen overflow",
877 {
878 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
879 /* NLRI tuples */ 120, 0xff, 0xfe, 0x1,
880 0x2, /* fffe:102::/32 */
881 64, 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
882 0x0, 0x2, 0x0, 0x3, 0, /* ::/0 */
883 },
884 (3 + 5 + 9 + 1),
885 SHOULD_ERR,
886 },
887 {
888 "IPv4-unreach",
889 "IPv4 MP Unreach, 2 NLRIs + default",
890 {
891 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
892 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
893 17, 10, 2, 3, /* 10.2.3/17 */
894 0, /* 0/0 */
895 },
896 (3 + 3 + 4 + 1),
897 SHOULD_PARSE,
898 },
899 {
900 "IPv4-unreach-nlrilen",
901 "IPv4 MP Unreach, nlri length overflow",
902 {
903 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
904 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
905 30, 10, 0, /* 0/0 */
906 },
907 (3 + 3 + 2 + 1),
908 SHOULD_ERR,
909 },
910 {
911 "IPv4-unreach-VPNv4",
912 "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs",
913 {
914 /* AFI / SAFI */ 0x0, AFI_IP, IANA_SAFI_MPLS_VPN,
915 /* NLRI tuples */ 88 + 16, 0, 1, 2, /* tag */
916 /* rd, 8 octets */
917 0, 0, /* RD_TYPE_AS */
918 0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
919 10, 1, /* 10.1/16 */
920 88 + 17, 0xff, 0, 0, /* tag */
921 /* rd, 8 octets */
922 0, 0, /* RD_TYPE_IP */
923 192, 168, 0, 1, /* IPv4 */
924 10, 2, 3, /* 10.2.3/17 */
925 },
926 (3 + (1 + 3 + 8 + 2) + (1 + 3 + 8 + 3)),
927 SHOULD_PARSE,
928 },
929 {
930 .name = "IPv4",
931 .desc = "IPV4 MP Unreach, flowspec, 1 NLRI",
932 .data = {
933 /* AFI / SAFI */ 0x0,
934 AFI_IP,
935 IANA_SAFI_FLOWSPEC,
936 0x06, /* FS Length */
937 0x01, /* FS dest prefix ID */
938 0x1e, /* IP */
939 0x1e,
940 0x28,
941 0x28,
942 0x0
943 },
944 .len = 10,
945 .parses = SHOULD_PARSE,
946 },
947 {NULL, NULL, {0}, 0, 0}};
948
949 static struct test_segment mp_prefix_sid[] = {
950 {
951 "PREFIX-SID",
952 "PREFIX-SID Test 1",
953 {
954 0x01, 0x00, 0x07,
955 0x00, 0x00, 0x00, 0x00,
956 0x00, 0x00, 0x02,
957 0x03, 0x00, 0x08, 0x00,
958 0x00, 0x0a, 0x1b, 0xfe,
959 0x00, 0x00, 0x0a
960 },
961 .len = 21,
962 .parses = SHOULD_PARSE,
963 },
964 {NULL, NULL, { 0 }, 0, 0},
965 };
966
967 /* nlri_parse indicates 0 on successful parse, and -1 otherwise.
968 * attr_parse indicates BGP_ATTR_PARSE_PROCEED/0 on success,
969 * and BGP_ATTR_PARSE_ERROR/-1 or lower negative ret on err.
970 */
971 static void handle_result(struct peer *peer, struct test_segment *t,
972 int parse_ret, int nlri_ret)
973 {
974 int oldfailed = failed;
975
976 printf("mp attr parsed?: %s\n", parse_ret ? "no" : "yes");
977 if (!parse_ret)
978 printf("nrli parsed?: %s\n", nlri_ret ? "no" : "yes");
979 printf("should parse?: %s\n", t->parses ? "no" : "yes");
980
981 if ((parse_ret != 0 || nlri_ret != 0) != (t->parses != 0))
982 failed++;
983
984
985 if (tty)
986 printf("%s",
987 (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
988 : VT100_GREEN "OK" VT100_RESET);
989 else
990 printf("%s", (failed > oldfailed) ? "failed!" : "OK");
991
992 if (failed)
993 printf(" (%u)", failed);
994
995 printf("\n\n");
996 }
997
998 /* basic parsing test */
999 static void parse_test(struct peer *peer, struct test_segment *t, int type)
1000 {
1001 int parse_ret = 0, nlri_ret = 0;
1002 struct attr attr = {};
1003 struct bgp_nlri nlri = {};
1004 struct bgp_attr_parser_args attr_args = {
1005 .peer = peer,
1006 .length = t->len,
1007 .total = 1,
1008 .attr = &attr,
1009 .type = type,
1010 .flags = BGP_ATTR_FLAG_OPTIONAL,
1011 .startp = BGP_INPUT_PNT(peer),
1012 };
1013 #define RANDOM_FUZZ 35
1014 stream_reset(peer->curr);
1015 stream_put(peer->curr, NULL, RANDOM_FUZZ);
1016 stream_set_getp(peer->curr, RANDOM_FUZZ);
1017
1018 stream_write(peer->curr, t->data, t->len);
1019
1020 printf("%s: %s\n", t->name, t->desc);
1021
1022 switch (type) {
1023 case BGP_ATTR_MP_REACH_NLRI:
1024 parse_ret = bgp_mp_reach_parse(&attr_args, &nlri);
1025 break;
1026 case BGP_ATTR_MP_UNREACH_NLRI:
1027 parse_ret = bgp_mp_unreach_parse(&attr_args, &nlri);
1028 break;
1029 case BGP_ATTR_PREFIX_SID:
1030 parse_ret = bgp_attr_prefix_sid(t->len, &attr_args, &nlri);
1031 break;
1032 default:
1033 printf("unknown type");
1034 return;
1035 }
1036 if (!parse_ret) {
1037 iana_afi_t pkt_afi;
1038 iana_safi_t pkt_safi;
1039
1040 /* Convert AFI, SAFI to internal values, check. */
1041 if (bgp_map_afi_safi_int2iana(nlri.afi, nlri.safi, &pkt_afi,
1042 &pkt_safi))
1043 assert(0);
1044
1045 printf("MP: %u(%u)/%u(%u): recv %u, nego %u\n", nlri.afi,
1046 pkt_afi, nlri.safi, pkt_safi,
1047 peer->afc_recv[nlri.afi][nlri.safi],
1048 peer->afc_nego[nlri.afi][nlri.safi]);
1049 }
1050
1051 if (!parse_ret) {
1052 if (type == BGP_ATTR_MP_REACH_NLRI)
1053 nlri_ret = bgp_nlri_parse(peer, &attr, &nlri, 0);
1054 else if (type == BGP_ATTR_MP_UNREACH_NLRI)
1055 nlri_ret = bgp_nlri_parse(peer, &attr, &nlri, 1);
1056 }
1057 handle_result(peer, t, parse_ret, nlri_ret);
1058 }
1059
1060 static struct bgp *bgp;
1061 static as_t asn = 100;
1062
1063 int main(void)
1064 {
1065 struct interface ifp;
1066 struct peer *peer;
1067 int i, j;
1068
1069 conf_bgp_debug_neighbor_events = -1UL;
1070 conf_bgp_debug_packet = -1UL;
1071 conf_bgp_debug_as4 = -1UL;
1072 conf_bgp_debug_flowspec = -1UL;
1073 term_bgp_debug_neighbor_events = -1UL;
1074 term_bgp_debug_packet = -1UL;
1075 term_bgp_debug_as4 = -1UL;
1076 term_bgp_debug_flowspec = -1UL;
1077
1078 qobj_init();
1079 cmd_init(0);
1080 bgp_vty_init();
1081 master = thread_master_create("test mp attr");
1082 bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
1083 vrf_init(NULL, NULL, NULL, NULL, NULL);
1084 bgp_option_set(BGP_OPT_NO_LISTEN);
1085 bgp_attr_init();
1086
1087 if (fileno(stdout) >= 0)
1088 tty = isatty(fileno(stdout));
1089
1090 if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT) < 0)
1091 return -1;
1092
1093 peer = peer_create_accept(bgp);
1094 peer->host = (char *)"foo";
1095 peer->status = Established;
1096 peer->curr = stream_new(BGP_MAX_PACKET_SIZE);
1097
1098 ifp.ifindex = 0;
1099 peer->nexthop.ifp = &ifp;
1100
1101 for (i = AFI_IP; i < AFI_MAX; i++)
1102 for (j = SAFI_UNICAST; j < SAFI_MAX; j++) {
1103 peer->afc[i][j] = 1;
1104 peer->afc_adv[i][j] = 1;
1105 }
1106
1107 i = 0;
1108 while (mp_reach_segments[i].name)
1109 parse_test(peer, &mp_reach_segments[i++],
1110 BGP_ATTR_MP_REACH_NLRI);
1111
1112 i = 0;
1113 while (mp_unreach_segments[i].name)
1114 parse_test(peer, &mp_unreach_segments[i++],
1115 BGP_ATTR_MP_UNREACH_NLRI);
1116
1117 i = 0;
1118 while (mp_prefix_sid[i].name)
1119 parse_test(peer, &mp_prefix_sid[i++],
1120 BGP_ATTR_PREFIX_SID);
1121 printf("failures: %d\n", failed);
1122 return failed;
1123 }