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:
762: if (fileno (stdout) >= 0)
763: tty = isatty (fileno (stdout));
764:
765: if (bgp_get (&bgp, &asn, NULL))
766: return -1;
767:
768: peer = peer_create_accept (bgp);
769: peer->host = (char *)"foo";
770: peer->status = Established;
771:
772: for (i = AFI_IP; i < AFI_MAX; i++)
773: for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
774: {
775: peer->afc[i][j] = 1;
776: peer->afc_adv[i][j] = 1;
777: }
778:
779: i = 0;
780: while (mp_reach_segments[i].name)
781: parse_test (peer, &mp_reach_segments[i++], BGP_ATTR_MP_REACH_NLRI);
782:
783: i = 0;
784: while (mp_unreach_segments[i].name)
785: parse_test (peer, &mp_unreach_segments[i++], BGP_ATTR_MP_UNREACH_NLRI);
786:
787: printf ("failures: %d\n", failed);
788: return failed;
789: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>