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