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