]> git.proxmox.com Git - mirror_frr.git/blob - tests/bgp_mp_attr_test.c
BGP: Add dynamic update group support
[mirror_frr.git] / tests / bgp_mp_attr_test.c
1 #include <zebra.h>
2
3 #include "vty.h"
4 #include "stream.h"
5 #include "privs.h"
6 #include "memory.h"
7 #include "queue.h"
8
9 #include "bgpd/bgpd.h"
10 #include "bgpd/bgp_attr.h"
11 #include "bgpd/bgp_open.h"
12 #include "bgpd/bgp_debug.h"
13
14 #define VT100_RESET "\x1b[0m"
15 #define VT100_RED "\x1b[31m"
16 #define VT100_GREEN "\x1b[32m"
17 #define VT100_YELLOW "\x1b[33m"
18
19
20 #define CAPABILITY 0
21 #define DYNCAP 1
22 #define OPT_PARAM 2
23
24 /* need these to link in libbgp */
25 struct zebra_privs_t *bgpd_privs = NULL;
26 struct thread_master *master = NULL;
27
28 static int failed = 0;
29 static int tty = 0;
30
31 /* test segments to parse and validate, and use for other tests */
32 static struct test_segment {
33 const char *name;
34 const char *desc;
35 const u_char data[1024];
36 int len;
37 #define SHOULD_PARSE 0
38 #define SHOULD_ERR -1
39 int parses; /* whether it should parse or not */
40
41 /* AFI/SAFI validation */
42 afi_t afi;
43 safi_t safi;
44 #define VALID_AFI 1
45 #define INVALID_AFI 0
46 int afi_valid;
47 } mp_reach_segments [] =
48 {
49 { "IPv6",
50 "IPV6 MP Reach, global nexthop, 1 NLRI",
51 {
52 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
53 /* nexthop bytes */ 16,
54 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2,
55 0xaa, 0xbb, 0xcc, 0xdd,
56 0x3, 0x4, 0x5, 0x6,
57 0xa1, 0xa2, 0xa3, 0xa4,
58 /* SNPA (defunct, MBZ) */ 0x0,
59 /* NLRI tuples */ 32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
60 },
61 (4 + 16 + 1 + 5),
62 SHOULD_PARSE,
63 AFI_IP6, SAFI_UNICAST, VALID_AFI,
64 },
65 { "IPv6-2",
66 "IPV6 MP Reach, global nexthop, 2 NLRIs",
67 {
68 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
69 /* nexthop bytes */ 16,
70 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* ffee:102:... */
71 0xaa, 0xbb, 0xcc, 0xdd,
72 0x3, 0x4, 0x5, 0x6,
73 0xa1, 0xa2, 0xa3, 0xa4,
74 /* SNPA (defunct, MBZ) */ 0x0,
75 /* NLRI tuples */ 32,
76 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
77 64,
78 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
79 0x0, 0x2, 0x0, 0x3,
80 },
81 (4 + 16 + 1 + 5 + 9),
82 SHOULD_PARSE,
83 AFI_IP6, SAFI_UNICAST, VALID_AFI,
84 },
85 { "IPv6-default",
86 "IPV6 MP Reach, global nexthop, 2 NLRIs + default",
87 {
88 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
89 /* nexthop bytes */ 16,
90 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2,
91 0xaa, 0xbb, 0xcc, 0xdd,
92 0x3, 0x4, 0x5, 0x6,
93 0xa1, 0xa2, 0xa3, 0xa4,
94 /* SNPA (defunct, MBZ) */ 0x0,
95 /* NLRI tuples */ 32,
96 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
97 64,
98 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
99 0x0, 0x2, 0x0, 0x3,
100 0x0, /* ::/0 */
101 },
102 (4 + 16 + 1 + 5 + 9 + 1),
103 SHOULD_PARSE,
104 AFI_IP6, SAFI_UNICAST, VALID_AFI,
105 },
106 { "IPv6-lnh",
107 "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default",
108 {
109 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
110 /* nexthop bytes */ 32,
111 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* fffe:102:... */
112 0xaa, 0xbb, 0xcc, 0xdd,
113 0x3, 0x4, 0x5, 0x6,
114 0xa1, 0xa2, 0xa3, 0xa4,
115 /* Nexthop (local) */ 0xfe, 0x80, 0x0, 0x0, /* fe80::210:2ff:.. */
116 0x0, 0x0, 0x0, 0x0,
117 0x2, 0x10, 0x2, 0xff,
118 0x1, 0x2, 0x3, 0x4,
119 /* SNPA (defunct, MBZ) */ 0x0,
120 /* NLRI tuples */ 32,
121 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
122 64,
123 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
124 0x0, 0x2, 0x0, 0x3,
125 0x0, /* ::/0 */
126 },
127 (4 + 32 + 1 + 5 + 9 + 1),
128 SHOULD_PARSE,
129 AFI_IP6, SAFI_UNICAST, VALID_AFI,
130 },
131 { "IPv6-nhlen",
132 "IPV6 MP Reach, inappropriate nexthop length",
133 {
134 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
135 /* nexthop bytes */ 4,
136 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* fffe:102:... */
137 0xaa, 0xbb, 0xcc, 0xdd,
138 0x3, 0x4, 0x5, 0x6,
139 0xa1, 0xa2, 0xa3, 0xa4,
140 /* Nexthop (local) */ 0xfe, 0x80, 0x0, 0x0, /* fe80::210:2ff:.. */
141 0x0, 0x0, 0x0, 0x0,
142 0x2, 0x10, 0x2, 0xff,
143 0x1, 0x2, 0x3, 0x4,
144 /* SNPA (defunct, MBZ) */ 0x0,
145 /* NLRI tuples */ 32,
146 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
147 64,
148 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
149 0x0, 0x2, 0x0, 0x3,
150 0x0, /* ::/0 */
151 },
152 (4 + 32 + 1 + 5 + 9 + 1),
153 SHOULD_ERR,
154 AFI_IP6, SAFI_UNICAST, VALID_AFI,
155 },
156 { "IPv6-nhlen2",
157 "IPV6 MP Reach, invalid nexthop length",
158 {
159 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
160 /* nexthop bytes */ 5,
161 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* fffe:102:... */
162 0xaa, 0xbb, 0xcc, 0xdd,
163 0x3, 0x4, 0x5, 0x6,
164 0xa1, 0xa2, 0xa3, 0xa4,
165 /* Nexthop (local) */ 0xfe, 0x80, 0x0, 0x0, /* fe80::210:2ff:.. */
166 0x0, 0x0, 0x0, 0x0,
167 0x2, 0x10, 0x2, 0xff,
168 0x1, 0x2, 0x3, 0x4,
169 /* SNPA (defunct, MBZ) */ 0x0,
170 /* NLRI tuples */ 32,
171 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
172 64,
173 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
174 0x0, 0x2, 0x0, 0x3,
175 0x0, /* ::/0 */
176 },
177 (4 + 32 + 1 + 5 + 9 + 1),
178 SHOULD_ERR,
179 AFI_IP6, SAFI_UNICAST, VALID_AFI,
180 },
181 { "IPv6-nhlen3",
182 "IPV6 MP Reach, nexthop length overflow",
183 {
184 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
185 /* nexthop bytes */ 32,
186 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* fffe:102:... */
187 0xaa, 0xbb, 0xcc, 0xdd,
188 0x3, 0x4, 0x5, 0x6,
189 0xa1, 0xa2, 0xa3, 0xa4,
190 },
191 (4 + 16),
192 SHOULD_ERR,
193 AFI_IP6, SAFI_UNICAST, VALID_AFI,
194 },
195 { "IPv6-nhlen4",
196 "IPV6 MP Reach, nexthop length short",
197 {
198 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
199 /* nexthop bytes */ 16,
200 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* fffe:102:... */
201 0xaa, 0xbb, 0xcc, 0xdd,
202 0x3, 0x4, 0x5, 0x6,
203 0xa1, 0xa2, 0xa3, 0xa4,
204 /* Nexthop (local) */ 0xfe, 0x80, 0x0, 0x0, /* fe80::210:2ff:.. */
205 0x0, 0x0, 0x0, 0x0,
206 0x2, 0x10, 0x2, 0xff,
207 0x1, 0x2, 0x3, 0x4,
208 /* SNPA (defunct, MBZ) */ 0x0,
209 /* NLRI tuples */ 32,
210 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
211 64,
212 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
213 0x0, 0x2, 0x0, 0x3,
214 0x0, /* ::/0 */
215 },
216 (4 + 32 + 1 + 5 + 9 + 1),
217 SHOULD_ERR,
218 AFI_IP6, SAFI_UNICAST, VALID_AFI,
219 },
220 { "IPv6-nlri",
221 "IPV6 MP Reach, NLRI bitlen overflow",
222 {
223 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
224 /* nexthop bytes */ 32,
225 /* Nexthop (global) */ 0xff, 0xfe, 0x1, 0x2, /* fffe:102:... */
226 0xaa, 0xbb, 0xcc, 0xdd,
227 0x3, 0x4, 0x5, 0x6,
228 0xa1, 0xa2, 0xa3, 0xa4,
229 /* Nexthop (local) */ 0xfe, 0x80, 0x0, 0x0, /* fe80::210:2ff:.. */
230 0x0, 0x0, 0x0, 0x0,
231 0x2, 0x10, 0x2, 0xff,
232 0x1, 0x2, 0x3, 0x4,
233 /* SNPA (defunct, MBZ) */ 0x0,
234 /* NLRI tuples */ 120,
235 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
236 64,
237 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
238 0x0, 0x2, 0x0, 0x3,
239 0, /* ::/0 */
240 },
241 (4 + 32 + 1 + 5 + 9 + 1),
242 SHOULD_ERR,
243 AFI_IP6, SAFI_UNICAST, VALID_AFI,
244 },
245 { "IPv4",
246 "IPv4 MP Reach, 2 NLRIs + default",
247 {
248 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
249 /* nexthop bytes */ 4,
250 /* Nexthop */ 192, 168, 0, 1,
251 /* SNPA (defunct, MBZ) */ 0x0,
252 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
253 17, 10, 2, 3, /* 10.2.3/17 */
254 0, /* 0/0 */
255 },
256 (4 + 4 + 1 + 3 + 4 + 1),
257 SHOULD_PARSE,
258 AFI_IP, SAFI_UNICAST, VALID_AFI,
259 },
260 { "IPv4-nhlen",
261 "IPv4 MP Reach, nexthop lenth overflow",
262 {
263 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
264 /* nexthop bytes */ 32,
265 /* Nexthop */ 192, 168, 0, 1,
266 /* SNPA (defunct, MBZ) */ 0x0,
267 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
268 17, 10, 2, 3, /* 10.2.3/17 */
269 0, /* 0/0 */
270 },
271 (4 + 4 + 1 + 3 + 4 + 1),
272 SHOULD_ERR,
273 AFI_IP, SAFI_UNICAST, VALID_AFI,
274 },
275 { "IPv4-nlrilen",
276 "IPv4 MP Reach, nlri lenth overflow",
277 {
278 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
279 /* nexthop bytes */ 4,
280 /* Nexthop */ 192, 168, 0, 1,
281 /* SNPA (defunct, MBZ) */ 0x0,
282 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
283 30, 10,
284 0, /* 0/0 */
285 },
286 (4 + 4 + 1 + 3 + 2 + 1),
287 SHOULD_ERR,
288 AFI_IP, SAFI_UNICAST, VALID_AFI,
289 },
290 { "IPv4-MLVPN",
291 "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, 3 NLRIs",
292 {
293 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
294 /* nexthop bytes */ 12,
295 /* RD */ 0, 0, 1, 2,
296 0, 0xff, 3, 4,
297 /* Nexthop */ 192, 168, 0, 1,
298 /* SNPA (defunct, MBZ) */ 0x0,
299 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
300 17, 10, 2, 3, /* 10.2.3/17 */
301 0, /* 0/0 */
302 },
303 (4 + 12 + 1 + 3 + 4 + 1),
304 SHOULD_PARSE,
305 AFI_IP, SAFI_UNICAST, VALID_AFI,
306 },
307 /* From bug #385 */
308 { "IPv6-bug",
309 "IPv6, global nexthop, 1 default NLRI",
310 {
311 /* AFI / SAFI */ 0x0, 0x2, 0x1,
312 /* nexthop bytes */ 0x20,
313 /* Nexthop (global) */ 0x20, 0x01, 0x04, 0x70,
314 0x00, 0x01, 0x00, 0x06,
315 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x01,
317 /* Nexthop (local) */ 0xfe, 0x80, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00,
319 0x02, 0x0c, 0xdb, 0xff,
320 0xfe, 0xfe, 0xeb, 0x00,
321 /* SNPA (defunct, MBZ) */ 0,
322 /* NLRI tuples */ /* Should have 0 here for ::/0, but dont */
323 },
324 37,
325 SHOULD_ERR,
326 AFI_IP6, SAFI_UNICAST, VALID_AFI,
327 },
328
329 { NULL, NULL, {0}, 0, 0}
330 };
331
332 /* MP_UNREACH_NLRI tests */
333 static struct test_segment mp_unreach_segments [] =
334 {
335 { "IPv6-unreach",
336 "IPV6 MP Unreach, 1 NLRI",
337 {
338 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
339 /* NLRI tuples */ 32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
340 },
341 (3 + 5),
342 SHOULD_PARSE,
343 AFI_IP6, SAFI_UNICAST, VALID_AFI,
344 },
345 { "IPv6-unreach2",
346 "IPV6 MP Unreach, 2 NLRIs",
347 {
348 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
349 /* NLRI tuples */ 32,
350 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
351 64,
352 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
353 0x0, 0x2, 0x0, 0x3,
354 },
355 (3 + 5 + 9),
356 SHOULD_PARSE,
357 AFI_IP6, SAFI_UNICAST, VALID_AFI,
358 },
359 { "IPv6-unreach-default",
360 "IPV6 MP Unreach, 2 NLRIs + default",
361 {
362 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
363 /* NLRI tuples */ 32,
364 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
365 64,
366 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
367 0x0, 0x2, 0x0, 0x3,
368 0x0, /* ::/0 */
369 },
370 (3 + 5 + 9 + 1),
371 SHOULD_PARSE,
372 AFI_IP6, SAFI_UNICAST, VALID_AFI,
373 },
374 { "IPv6-unreach-nlri",
375 "IPV6 MP Unreach, NLRI bitlen overflow",
376 {
377 /* AFI / SAFI */ 0x0, AFI_IP6, SAFI_UNICAST,
378 /* NLRI tuples */ 120,
379 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
380 64,
381 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
382 0x0, 0x2, 0x0, 0x3,
383 0, /* ::/0 */
384 },
385 (3 + 5 + 9 + 1),
386 SHOULD_ERR,
387 AFI_IP6, SAFI_UNICAST, VALID_AFI,
388 },
389 { "IPv4-unreach",
390 "IPv4 MP Unreach, 2 NLRIs + default",
391 {
392 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
393 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
394 17, 10, 2, 3, /* 10.2.3/17 */
395 0, /* 0/0 */
396 },
397 (3 + 3 + 4 + 1),
398 SHOULD_PARSE,
399 AFI_IP, SAFI_UNICAST, VALID_AFI,
400 },
401 { "IPv4-unreach-nlrilen",
402 "IPv4 MP Unreach, nlri length overflow",
403 {
404 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_UNICAST,
405 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
406 30, 10,
407 0, /* 0/0 */
408 },
409 (3 + 3 + 2 + 1),
410 SHOULD_ERR,
411 AFI_IP, SAFI_UNICAST, VALID_AFI,
412 },
413 { "IPv4-unreach-MLVPN",
414 "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs",
415 {
416 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
417 /* nexthop bytes */ 12,
418 /* RD */ 0, 0, 1, 2,
419 0, 0xff, 3, 4,
420 /* Nexthop */ 192, 168, 0, 1,
421 /* SNPA (defunct, MBZ) */ 0x0,
422 /* NLRI tuples */ 16, 10, 1, /* 10.1/16 */
423 17, 10, 2, 3, /* 10.2.3/17 */
424 0, /* 0/0 */
425 },
426 (3 + 3 + 4 + 1),
427 SHOULD_PARSE,
428 AFI_IP, SAFI_UNICAST, VALID_AFI,
429 },
430 { NULL, NULL, {0}, 0, 0}
431 };
432
433
434 /* basic parsing test */
435 static void
436 parse_test (struct peer *peer, struct test_segment *t, int type)
437 {
438 int ret;
439 int oldfailed = failed;
440 struct attr attr = { };
441 struct bgp_nlri nlri = { };
442 struct bgp_attr_parser_args attr_args = {
443 .peer = peer,
444 .length = t->len,
445 .total = 1,
446 .attr = &attr,
447 .type = BGP_ATTR_MP_REACH_NLRI,
448 .flags = BGP_ATTR_FLAG_OPTIONAL,
449 .startp = BGP_INPUT_PNT (peer),
450 };
451 #define RANDOM_FUZZ 35
452
453 stream_reset (peer->ibuf);
454 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
455 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
456
457 stream_write (peer->ibuf, t->data, t->len);
458
459 printf ("%s: %s\n", t->name, t->desc);
460
461
462 if (type == BGP_ATTR_MP_REACH_NLRI)
463 ret = bgp_mp_reach_parse (&attr_args, &nlri);
464 else
465 ret = bgp_mp_unreach_parse (&attr_args, &nlri);
466
467 if (!ret)
468 {
469 safi_t safi = t->safi;
470
471 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
472 failed++;
473
474 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
475 t->afi, t->safi, safi,
476 peer->afc_recv[t->afi][safi],
477 peer->afc_nego[t->afi][safi]);
478 }
479
480 printf ("parsed?: %s\n", ret ? "no" : "yes");
481
482 if ((ret == 0) != (t->parses == 0))
483 failed++;
484
485 if (tty)
486 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
487 : VT100_GREEN "OK" VT100_RESET);
488 else
489 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
490
491 if (failed)
492 printf (" (%u)", failed);
493
494 printf ("\n\n");
495 }
496
497 static struct bgp *bgp;
498 static as_t asn = 100;
499
500 int
501 main (void)
502 {
503 struct peer *peer;
504 int i, j;
505
506 conf_bgp_debug_neighbor_events = -1UL;
507 conf_bgp_debug_packet = -1UL;
508 conf_bgp_debug_as4 = -1UL;
509 term_bgp_debug_neighbor_events = -1UL;
510 term_bgp_debug_packet = -1UL;
511 term_bgp_debug_as4 = -1UL;
512
513 master = thread_master_create ();
514 bgp_master_init ();
515 bgp_option_set (BGP_OPT_NO_LISTEN);
516
517 if (fileno (stdout) >= 0)
518 tty = isatty (fileno (stdout));
519
520 if (bgp_get (&bgp, &asn, NULL))
521 return -1;
522
523 peer = peer_create_accept (bgp);
524 peer->host = "foo";
525
526 for (i = AFI_IP; i < AFI_MAX; i++)
527 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
528 {
529 peer->afc[i][j] = 1;
530 peer->afc_adv[i][j] = 1;
531 }
532
533 i = 0;
534 while (mp_reach_segments[i].name)
535 parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);
536
537 i = 0;
538 while (mp_unreach_segments[i].name)
539 parse_test (peer, &mp_unreach_segments[i++], BGP_ATTR_MP_UNREACH_NLRI);
540
541 printf ("failures: %d\n", failed);
542 return failed;
543 }