Import Upstream version 1.2.2
[quagga-debian.git] / tests / bgp_mp_attr_test.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
17  * along with Quagga; see the file COPYING.  If not, write to the Free
18  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.  
20  */
21
22 #include <zebra.h>
23
24 #include "vty.h"
25 #include "stream.h"
26 #include "privs.h"
27 #include "memory.h"
28 #include "filter.h"
29
30 #include "bgpd/bgpd.h"
31 #include "bgpd/bgp_attr.h"
32 #include "bgpd/bgp_open.h"
33 #include "bgpd/bgp_debug.h"
34 #include "bgpd/bgp_route.h"
35 #include "bgpd/bgp_packet.h"
36 #include "bgpd/bgp_mplsvpn.h"
37 #include "bgpd/bgp_nexthop.h"
38
39 #define VT100_RESET "\x1b[0m"
40 #define VT100_RED "\x1b[31m"
41 #define VT100_GREEN "\x1b[32m"
42 #define VT100_YELLOW "\x1b[33m"
43
44
45 #define CAPABILITY 0
46 #define DYNCAP     1
47 #define OPT_PARAM  2
48
49 /* need these to link in libbgp */
50 struct zebra_privs_t *bgpd_privs = NULL;
51 struct thread_master *master = NULL;
52
53 static int failed = 0;
54 static int tty = 0;
55
56 /* test segments to parse and validate, and use for other tests */
57 static struct test_segment {
58   const char *name;
59   const char *desc;
60   const u_char data[1024];
61   int len;
62 #define SHOULD_PARSE    0
63 #define SHOULD_ERR      -1
64   int parses; /* whether it should parse or not */
65   
66   /* AFI/SAFI validation */
67   afi_t afi;
68   safi_t safi;
69 #define VALID_AFI 1
70 #define INVALID_AFI 0
71   int afi_valid;
72 } mp_reach_segments [] = 
73 {
74   { "IPv6",
75     "IPV6 MP Reach, global nexthop, 1 NLRI", 
76     {
77       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
78       /* nexthop bytes */       16,
79       /* Nexthop (global) */    0xff, 0xfe, 0x1,  0x2,
80                                 0xaa, 0xbb, 0xcc, 0xdd,
81                                 0x3,  0x4,  0x5,  0x6,
82                                 0xa1, 0xa2, 0xa3, 0xa4,
83       /* SNPA (defunct, MBZ) */ 0x0,
84       /* NLRI tuples */         32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
85     },
86     (4 + 16 + 1 + 5), 
87     SHOULD_PARSE,
88     AFI_IP6, SAFI_UNICAST, VALID_AFI,
89   },
90   { "IPv6-2",
91     "IPV6 MP Reach, global nexthop, 2 NLRIs", 
92     {
93       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
94       /* nexthop bytes */       16,
95       /* Nexthop (global) */    0xff, 0xfe, 0x1,  0x2,   /* ffee:102:... */
96                                 0xaa, 0xbb, 0xcc, 0xdd,
97                                 0x3,  0x4,  0x5,  0x6,
98                                 0xa1, 0xa2, 0xa3, 0xa4,
99       /* SNPA (defunct, MBZ) */ 0x0,
100       /* NLRI tuples */         32, 
101                                 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
102                                 64,
103                                 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
104                                 0x0,  0x2,  0x0, 0x3,
105     },
106     (4 + 16 + 1 + 5 + 9), 
107     SHOULD_PARSE,
108     AFI_IP6, SAFI_UNICAST, VALID_AFI,
109   },
110   { "IPv6-default",
111     "IPV6 MP Reach, global nexthop, 2 NLRIs + default", 
112     {
113       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
114       /* nexthop bytes */       16,
115       /* Nexthop (global) */    0xff, 0xfe, 0x1,  0x2,
116                                 0xaa, 0xbb, 0xcc, 0xdd,
117                                 0x3,  0x4,  0x5,  0x6,
118                                 0xa1, 0xa2, 0xa3, 0xa4,
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 + 16 + 1 + 5 + 9 + 1),
128     SHOULD_PARSE,
129     AFI_IP6, SAFI_UNICAST, VALID_AFI,
130   },
131   { "IPv6-lnh",
132     "IPV6 MP Reach, global+local nexthops, 2 NLRIs + default", 
133     {
134       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
135       /* nexthop bytes */       32,
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_PARSE,
154     AFI_IP6, SAFI_UNICAST, VALID_AFI,
155   },
156   { "IPv6-nhlen",
157     "IPV6 MP Reach, inappropriate nexthop length", 
158     {
159       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
160       /* nexthop bytes */       4,
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-nhlen2",
182     "IPV6 MP Reach, invalid nexthop length", 
183     {
184       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
185       /* nexthop bytes */       5,
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       /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
191                                 0x0,  0x0,  0x0,  0x0,
192                                 0x2,  0x10, 0x2,  0xff,
193                                 0x1,  0x2,  0x3,  0x4,
194       /* SNPA (defunct, MBZ) */ 0x0,
195       /* NLRI tuples */         32, 
196                                 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
197                                 64,
198                                 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
199                                 0x0,  0x2,  0x0, 0x3,
200                                 0x0, /* ::/0 */
201     },
202     (4 + 32 + 1 + 5 + 9 + 1),
203     SHOULD_ERR,
204     AFI_IP6, SAFI_UNICAST, VALID_AFI,
205   },
206   { "IPv6-nhlen3",
207     "IPV6 MP Reach, nexthop length overflow", 
208     {
209       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
210       /* nexthop bytes */       32,
211       /* Nexthop (global) */    0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
212                                 0xaa, 0xbb, 0xcc, 0xdd,
213                                 0x3,  0x4,  0x5,  0x6,
214                                 0xa1, 0xa2, 0xa3, 0xa4,
215     },
216     (4 + 16),
217     SHOULD_ERR,
218     AFI_IP6, SAFI_UNICAST, VALID_AFI,
219   },
220   { "IPv6-nhlen4",
221     "IPV6 MP Reach, nexthop length short", 
222     {
223       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
224       /* nexthop bytes */       16,
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 */         32, 
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                                 0x0, /* ::/0 */
240     },
241     (4 + 32 + 1 + 5 + 9 + 1),
242     SHOULD_ERR,
243     AFI_IP6, SAFI_UNICAST, VALID_AFI,
244   },
245   { "IPv6-nlri",
246     "IPV6 MP Reach, NLRI bitlen overflow", 
247     {
248       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
249       /* nexthop bytes */       32,
250       /* Nexthop (global) */    0xff, 0xfe, 0x1,  0x2,  /* fffe:102:... */
251                                 0xaa, 0xbb, 0xcc, 0xdd,
252                                 0x3,  0x4,  0x5,  0x6,
253                                 0xa1, 0xa2, 0xa3, 0xa4,
254       /* Nexthop (local) */     0xfe, 0x80, 0x0,  0x0,  /* fe80::210:2ff:.. */
255                                 0x0,  0x0,  0x0,  0x0,
256                                 0x2,  0x10, 0x2,  0xff,
257                                 0x1,  0x2,  0x3,  0x4,
258       /* SNPA (defunct, MBZ) */ 0x0,
259       /* NLRI tuples */         120, 
260                                 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
261                                 64,
262                                 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
263                                 0x0,  0x2,  0x0, 0x3,
264                                 0, /* ::/0 */
265     },
266     (4 + 32 + 1 + 5 + 9 + 1),
267     SHOULD_ERR,
268     AFI_IP6, SAFI_UNICAST, VALID_AFI,
269   },
270   { "IPv4",
271     "IPv4 MP Reach, 2 NLRIs + default", 
272     {
273       /* AFI / SAFI */          0x0, AFI_IP, SAFI_UNICAST,
274       /* nexthop bytes */       4,
275       /* Nexthop */             192, 168,   0,  1, 
276       /* SNPA (defunct, MBZ) */ 0x0,
277       /* NLRI tuples */         16, 10, 1,    /* 10.1/16 */
278                                 17, 10, 2, 3, /* 10.2.3/17 */
279                                 0, /* 0/0 */
280     },
281     (4 + 4 + 1 + 3 + 4 + 1),
282     SHOULD_PARSE,
283     AFI_IP, SAFI_UNICAST, VALID_AFI,
284   },
285   { "IPv4-nhlen",
286     "IPv4 MP Reach, nexthop lenth overflow", 
287     {
288       /* AFI / SAFI */          0x0, AFI_IP, SAFI_UNICAST,
289       /* nexthop bytes */       32,
290       /* Nexthop */             192, 168,   0,  1, 
291       /* SNPA (defunct, MBZ) */ 0x0,
292       /* NLRI tuples */         16, 10, 1,    /* 10.1/16 */
293                                 17, 10, 2, 3, /* 10.2.3/17 */
294                                 0, /* 0/0 */
295     },
296     (4 + 4 + 1 + 3 + 4 + 1),
297     SHOULD_ERR,
298     AFI_IP, SAFI_UNICAST, VALID_AFI,
299   },
300   { "IPv4-nlrilen",
301     "IPv4 MP Reach, nlri lenth overflow", 
302     {
303       /* AFI / SAFI */          0x0, AFI_IP, SAFI_UNICAST,
304       /* nexthop bytes */       4,
305       /* Nexthop */             192, 168,   0,  1, 
306       /* SNPA (defunct, MBZ) */ 0x0,
307       /* NLRI tuples */         16, 10, 1,    /* 10.1/16 */
308                                 30, 10, 
309                                 0, /* 0/0 */
310     },
311     (4 + 4 + 1 + 3 + 2 + 1),
312     SHOULD_ERR,
313     AFI_IP, SAFI_UNICAST, VALID_AFI,
314   },
315   { "IPv4-VPNv4",
316     "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs", 
317     {
318       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
319       /* nexthop bytes */       12,
320       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
321                                 0, 0, 0, 0,
322       /* Nexthop */             192, 168,   0,  1, 
323       /* SNPA (defunct, MBZ) */ 0x0,
324       /* NLRI tuples */         88 + 16,
325                                   0, 1, 2,   /* tag */
326                                   /* rd, 8 octets */
327                                     0, 0, /* RD_TYPE_AS */
328                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
329                                   10, 1,    /* 10.1/16 */
330                                 88 + 17,
331                                   0xff, 0, 0,   /* tag */
332                                   /* rd, 8 octets */
333                                     0, 0, /* RD_TYPE_IP */
334                                     192, 168, 0, 1, /* IPv4 */
335                                   10, 2, 3,  /* 10.2.3/17 */
336     },
337     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
338     SHOULD_PARSE,
339     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
340   },
341   { "IPv4-VPNv4-bogus-plen",
342     "IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len", 
343     {
344       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
345       /* nexthop bytes */       12,
346       /* RD */                  0, 0, 1, 2,
347                                 0, 0xff, 3, 4,
348       /* Nexthop */             192, 168,   0,  1, 
349       /* SNPA (defunct, MBZ) */ 0x0,
350       /* NLRI tuples */         16, 10, 1,    /* 10.1/16 */
351                                 17, 10, 2, 3,  /* 10.2.3/17 */
352                                 0, /* 0/0 */
353     },
354     (3 + 1 + 3*4 + 1 + 3 + 4 + 1),
355     SHOULD_ERR,
356     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
357   },
358   { "IPv4-VPNv4-plen1-short",
359     "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short", 
360     {
361       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
362       /* nexthop bytes */       12,
363       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
364                                 0, 0, 0, 0,
365       /* Nexthop */             192, 168,   0,  1, 
366       /* SNPA (defunct, MBZ) */ 0x0,
367       /* NLRI tuples */         88 + 1,
368                                   0, 1, 2,   /* tag */
369                                   /* rd, 8 octets */
370                                     0, 0, /* RD_TYPE_AS */
371                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
372                                   10, 1,    /* 10.1/16 */
373                                 88 + 17,
374                                   0xff, 0, 0,   /* tag */
375                                   /* rd, 8 octets */
376                                     0, 0, /* RD_TYPE_IP */
377                                     192, 168, 0, 1, /* IPv4 */
378                                   10, 2, 3,  /* 10.2.3/17 */
379     },
380     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
381     SHOULD_ERR,
382     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
383   },
384   { "IPv4-VPNv4-plen1-long",
385     "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long", 
386     {
387       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
388       /* nexthop bytes */       12,
389       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
390                                 0, 0, 0, 0,
391       /* Nexthop */             192, 168,   0,  1, 
392       /* SNPA (defunct, MBZ) */ 0x0,
393       /* NLRI tuples */         88 + 32,
394                                   0, 1, 2,   /* tag */
395                                   /* rd, 8 octets */
396                                     0, 0, /* RD_TYPE_AS */
397                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
398                                   10, 1,    /* 10.1/16 */
399                                 88 + 17,
400                                   0xff, 0, 0,   /* tag */
401                                   /* rd, 8 octets */
402                                     0, 0, /* RD_TYPE_IP */
403                                     192, 168, 0, 1, /* IPv4 */
404                                   10, 2, 3,  /* 10.2.3/17 */
405     },
406     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
407     SHOULD_ERR,
408     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
409   },
410   { "IPv4-VPNv4-plenn-long",
411     "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long", 
412     {
413       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
414       /* nexthop bytes */       12,
415       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
416                                 0, 0, 0, 0,
417       /* Nexthop */             192, 168,   0,  1, 
418       /* SNPA (defunct, MBZ) */ 0x0,
419       /* NLRI tuples */         88 + 16,
420                                   0, 1, 2,   /* tag */
421                                   /* rd, 8 octets */
422                                     0, 0, /* RD_TYPE_AS */
423                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
424                                   10, 1,    /* 10.1/16 */
425                                 88 + 17,
426                                   0xff, 0, 0,   /* tag */
427                                   /* rd, 8 octets */
428                                     0, 0, /* RD_TYPE_IP */
429                                     192, 168, 0, 1, /* IPv4 */
430                                   10, 2, 3,  /* 10.2.3/17 */
431                                 88 + 1, /* bogus */
432     },
433     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
434     SHOULD_ERR,
435     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
436   },
437   { "IPv4-VPNv4-plenn-short",
438     "IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short", 
439     {
440       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
441       /* nexthop bytes */       12,
442       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
443                                 0, 0, 0, 0,
444       /* Nexthop */             192, 168,   0,  1, 
445       /* SNPA (defunct, MBZ) */ 0x0,
446       /* NLRI tuples */         88 + 16,
447                                   0, 1, 2,   /* tag */
448                                   /* rd, 8 octets */
449                                     0, 0, /* RD_TYPE_AS */
450                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
451                                   10, 1,    /* 10.1/16 */
452                                 88 + 2,
453                                   0xff, 0, 0,   /* tag */
454                                   /* rd, 8 octets */
455                                     0, 0, /* RD_TYPE_IP */
456                                     192, 168, 0, 1, /* IPv4 */
457                                   10, 2, 3,  /* 10.2.3/17 */
458     },
459     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
460     SHOULD_ERR,
461     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
462   },
463   { "IPv4-VPNv4-bogus-rd-type",
464     "IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)", 
465     {
466       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
467       /* nexthop bytes */       12,
468       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
469                                 0, 0, 0, 0,
470       /* Nexthop */             192, 168,   0,  1, 
471       /* SNPA (defunct, MBZ) */ 0x0,
472       /* NLRI tuples */         88 + 16,
473                                   0, 1, 2,   /* tag */
474                                   /* rd, 8 octets */
475                                     0xff, 0, /* Bogus RD */
476                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
477                                   10, 1,    /* 10.1/16 */
478                                 88 + 17,
479                                   0xff, 0, 0,   /* tag */
480                                   /* rd, 8 octets */
481                                     0, 0, /* RD_TYPE_IP */
482                                     192, 168, 0, 1, /* IPv4 */
483                                   10, 2, 3,  /* 10.2.3/17 */
484     },
485     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3)),
486     SHOULD_PARSE,
487     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
488   },
489   { "IPv4-VPNv4-0-nlri",
490     "IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus", 
491     {
492       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
493       /* nexthop bytes */       12,
494       /* RD */                  0, 0, 0, 0, /* RD defined to be 0 */
495                                 0, 0, 0, 0,
496       /* Nexthop */             192, 168,   0,  1, 
497       /* SNPA (defunct, MBZ) */ 0x0,
498       /* NLRI tuples */         88 + 16,
499                                   0, 1, 2,   /* tag */
500                                   /* rd, 8 octets */
501                                     0, 0, /* RD_TYPE_AS */
502                                     0, 2, 0, 0xff, 3, 4, /* AS(2):val(4) */
503                                   10, 1,    /* 10.1/16 */
504                                 88 + 17,
505                                   0xff, 0, 0,   /* tag */
506                                   /* rd, 8 octets */
507                                     0, 0, /* RD_TYPE_IP */
508                                     192, 168, 0, 1, /* IPv4 */
509                                   10, 2, 3,  /* 10.2.3/17 */
510                                 0 /* 0/0, bogus for vpnv4 ?? */
511     },
512     (4 + 12 + 1 + (1+3+8+2) + (1+3+8+3) + 1),
513     SHOULD_ERR,
514     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
515   },
516
517   /* From bug #385 */
518   { "IPv6-bug",
519     "IPv6, global nexthop, 1 default NLRI", 
520     {
521       /* AFI / SAFI */          0x0, 0x2, 0x1,
522       /* nexthop bytes */       0x20,
523       /* Nexthop (global) */    0x20, 0x01, 0x04, 0x70, 
524                                 0x00, 0x01, 0x00, 0x06,
525                                 0x00, 0x00, 0x00, 0x00,
526                                 0x00, 0x00, 0x00, 0x01, 
527       /* Nexthop (local) */     0xfe, 0x80, 0x00, 0x00, 
528                                 0x00, 0x00, 0x00, 0x00,
529                                 0x02, 0x0c, 0xdb, 0xff, 
530                                 0xfe, 0xfe, 0xeb, 0x00,
531       /* SNPA (defunct, MBZ) */ 0,
532       /* NLRI tuples */         /* Should have 0 here for ::/0, but dont */
533     },
534     37,
535     SHOULD_ERR,
536     AFI_IP6, SAFI_UNICAST, VALID_AFI,
537   },
538   
539   { NULL, NULL, {0}, 0, 0}
540 };
541
542 /* MP_UNREACH_NLRI tests */
543 static struct test_segment mp_unreach_segments [] =
544 {
545   { "IPv6-unreach",
546     "IPV6 MP Unreach, 1 NLRI", 
547     {
548       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
549       /* NLRI tuples */         32, 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
550     },
551     (3 + 5), 
552     SHOULD_PARSE,
553     AFI_IP6, SAFI_UNICAST, VALID_AFI,
554   },
555   { "IPv6-unreach2",
556     "IPV6 MP Unreach, 2 NLRIs", 
557     {
558       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
559       /* NLRI tuples */         32, 
560                                 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
561                                 64,
562                                 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
563                                 0x0,  0x2,  0x0, 0x3,
564     },
565     (3 + 5 + 9), 
566     SHOULD_PARSE,
567     AFI_IP6, SAFI_UNICAST, VALID_AFI,
568   },
569   { "IPv6-unreach-default",
570     "IPV6 MP Unreach, 2 NLRIs + default", 
571     {
572       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
573       /* NLRI tuples */         32, 
574                                 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
575                                 64,
576                                 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
577                                 0x0,  0x2,  0x0, 0x3,
578                                 0x0, /* ::/0 */
579     },
580     (3 + 5 + 9 + 1),
581     SHOULD_PARSE,
582     AFI_IP6, SAFI_UNICAST, VALID_AFI,
583   },
584   { "IPv6-unreach-nlri",
585     "IPV6 MP Unreach, NLRI bitlen overflow", 
586     {
587       /* AFI / SAFI */          0x0, AFI_IP6, SAFI_UNICAST,
588       /* NLRI tuples */         120, 
589                                 0xff, 0xfe, 0x1, 0x2, /* fffe:102::/32 */
590                                 64,
591                                 0xff, 0xfe, 0x0, 0x1, /* fffe:1:2:3::/64 */
592                                 0x0,  0x2,  0x0, 0x3,
593                                 0, /* ::/0 */
594     },
595     (3 + 5 + 9 + 1),
596     SHOULD_ERR,
597     AFI_IP6, SAFI_UNICAST, VALID_AFI,
598   },
599   { "IPv4-unreach",
600     "IPv4 MP Unreach, 2 NLRIs + default", 
601     {
602       /* AFI / SAFI */          0x0, AFI_IP, SAFI_UNICAST,
603       /* NLRI tuples */         16, 10, 1,    /* 10.1/16 */
604                                 17, 10, 2, 3, /* 10.2.3/17 */
605                                 0, /* 0/0 */
606     },
607     (3 + 3 + 4 + 1),
608     SHOULD_PARSE,
609     AFI_IP, SAFI_UNICAST, VALID_AFI,
610   },
611   { "IPv4-unreach-nlrilen",
612     "IPv4 MP Unreach, nlri length overflow", 
613     {
614       /* AFI / SAFI */          0x0, AFI_IP, SAFI_UNICAST,
615       /* NLRI tuples */         16, 10, 1,    /* 10.1/16 */
616                                 30, 10, 
617                                 0, /* 0/0 */
618     },
619     (3 + 3 + 2 + 1),
620     SHOULD_ERR,
621     AFI_IP, SAFI_UNICAST, VALID_AFI,
622   },
623   { "IPv4-unreach-VPNv4",
624     "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs", 
625     {
626       /* AFI / SAFI */          0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
627       /* NLRI tuples */         88 + 16,
628                                   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,
634                                   0xff, 0, 0,   /* tag */
635                                   /* rd, 8 octets */
636                                     0, 0, /* RD_TYPE_IP */
637                                     192, 168, 0, 1, /* IPv4 */
638                                   10, 2, 3,  /* 10.2.3/17 */
639     },
640     (3 + (1+3+8+2) + (1+3+8+3)),
641     SHOULD_PARSE,
642     AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
643   },
644   { NULL, NULL, {0}, 0, 0}
645 };
646
647 /* nlri_parse indicates 0 on successful parse, and -1 otherwise.
648  * attr_parse indicates BGP_ATTR_PARSE_PROCEED/0 on success,
649  * and BGP_ATTR_PARSE_ERROR/-1 or lower negative ret on err.
650  */
651 static void
652 handle_result (struct peer *peer, struct test_segment *t,
653                int parse_ret, int nlri_ret)
654 {
655   int oldfailed = failed;
656   
657   if (!parse_ret)
658     {
659       safi_t safi = t->safi;
660       
661       if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
662         failed++;
663       
664       printf ("MP: %u/%u (%u): recv %u, nego %u\n",
665               t->afi, t->safi, safi,
666               peer->afc_recv[t->afi][safi],
667               peer->afc_nego[t->afi][safi]);
668     }
669   
670   printf ("mp attr parsed?: %s\n", parse_ret ? "no" : "yes");
671   if (!parse_ret)
672     printf ("nrli parsed?:  %s\n", nlri_ret ? "no" : "yes");
673   printf ("should parse?:  %s\n", t->parses ? "no" : "yes");
674   
675   if ((parse_ret != 0 || nlri_ret != 0) != (t->parses != 0))
676     failed++;
677   
678     
679   if (tty)
680     printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET 
681                                          : VT100_GREEN "OK" VT100_RESET);
682   else
683     printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
684   
685   if (failed)
686     printf (" (%u)", failed);
687   
688   printf ("\n\n");
689 }
690
691 /* basic parsing test */
692 static void
693 parse_test (struct peer *peer, struct test_segment *t, int type)
694 {
695   int parse_ret = 0, nlri_ret = 0;
696   struct attr attr = { };
697   struct bgp_nlri nlri = { };
698   struct bgp_attr_parser_args attr_args = {
699     .peer = peer,
700     .length = t->len,
701     .total = 1,
702     .attr = &attr,
703     .type = type,
704     .flags = BGP_ATTR_FLAG_OPTIONAL, 
705     .startp = BGP_INPUT_PNT (peer),
706   };
707 #define RANDOM_FUZZ 35
708   
709   stream_reset (peer->ibuf);
710   stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
711   stream_set_getp (peer->ibuf, RANDOM_FUZZ);
712   
713   stream_write (peer->ibuf, t->data, t->len);
714   
715   printf ("%s: %s\n", t->name, t->desc);
716   
717   if (type == BGP_ATTR_MP_REACH_NLRI)
718     parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
719   else
720     parse_ret = bgp_mp_unreach_parse (&attr_args, &nlri);
721   
722   if (parse_ret == 0 && t->afi_valid == VALID_AFI)
723     assert (nlri.afi == t->afi && nlri.safi == t->safi);
724   
725   if (!parse_ret)
726     {
727       if (type == BGP_ATTR_MP_REACH_NLRI)
728         nlri_ret = bgp_nlri_parse (peer, &attr, &nlri);
729       else
730         nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
731     }
732   
733   handle_result (peer, t, parse_ret, nlri_ret);
734 }
735
736 static struct bgp *bgp;
737 static as_t asn = 100;
738
739 int
740 main (void)
741 {
742   struct peer *peer;
743   int i, j;
744   
745   conf_bgp_debug_fsm = -1UL;
746   conf_bgp_debug_events = -1UL;
747   conf_bgp_debug_packet = -1UL;
748   conf_bgp_debug_normal = -1UL;
749   conf_bgp_debug_as4 = -1UL;
750   term_bgp_debug_fsm = -1UL;
751   term_bgp_debug_events = -1UL;
752   term_bgp_debug_packet = -1UL;
753   term_bgp_debug_normal = -1UL;
754   term_bgp_debug_as4 = -1UL;
755   
756   master = thread_master_create ();
757   bgp_master_init ();
758   bgp_option_set (BGP_OPT_NO_LISTEN);
759   bgp_attr_init ();
760   bgp_address_init ();
761   bgp_scan_init ();
762   
763   if (fileno (stdout) >= 0) 
764     tty = isatty (fileno (stdout));
765   
766   if (bgp_get (&bgp, &asn, NULL))
767     return -1;
768   
769   peer = peer_create_accept (bgp);
770   peer->host = (char *)"foo";
771   peer->status = Established;
772   
773   for (i = AFI_IP; i < AFI_MAX; i++)
774     for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
775       {
776         peer->afc[i][j] = 1;
777         peer->afc_adv[i][j] = 1;
778       }
779   
780   i = 0;
781   while (mp_reach_segments[i].name)
782     parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);
783
784   i = 0;
785   while (mp_unreach_segments[i].name)
786     parse_test (peer, &mp_unreach_segments[i++], BGP_ATTR_MP_UNREACH_NLRI);
787
788   printf ("failures: %d\n", failed);
789   return failed;
790 }