blob: 3b1bf1452cf844e816a351638d7197bc9b278cd1 [file] [log] [blame]
Paul Jakma010ebbb2014-09-16 11:53:49 +01001/*
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
Paul Jakma1eab26b2008-06-07 20:44:30 +000022#include <zebra.h>
23
24#include "vty.h"
25#include "stream.h"
26#include "privs.h"
27#include "memory.h"
Donald Sharp04907292016-01-07 10:03:01 -050028#include "filter.h"
Paul Jakma1eab26b2008-06-07 20:44:30 +000029
30#include "bgpd/bgpd.h"
31#include "bgpd/bgp_attr.h"
32#include "bgpd/bgp_open.h"
33#include "bgpd/bgp_debug.h"
Paul Jakma18ab08b2016-01-27 16:37:33 +000034#include "bgpd/bgp_route.h"
Paul Jakma518a4b72016-02-04 13:27:04 +000035#include "bgpd/bgp_packet.h"
Paul Jakma18ab08b2016-01-27 16:37:33 +000036#include "bgpd/bgp_mplsvpn.h"
37#include "bgpd/bgp_nexthop.h"
Paul Jakma1eab26b2008-06-07 20:44:30 +000038
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 */
50struct zebra_privs_t *bgpd_privs = NULL;
51struct thread_master *master = NULL;
52
53static int failed = 0;
54static int tty = 0;
55
56/* test segments to parse and validate, and use for other tests */
57static 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 },
Paul Jakma18ab08b2016-01-27 16:37:33 +0000315 { "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",
Paul Jakma1eab26b2008-06-07 20:44:30 +0000343 {
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400344 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
Paul Jakma1eab26b2008-06-07 20:44:30 +0000345 /* 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 },
Paul Jakma18ab08b2016-01-27 16:37:33 +0000354 (3 + 1 + 3*4 + 1 + 3 + 4 + 1),
355 SHOULD_ERR,
356 AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakma1eab26b2008-06-07 20:44:30 +0000357 },
Paul Jakma18ab08b2016-01-27 16:37:33 +0000358 { "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
Paul Jakma1eab26b2008-06-07 20:44:30 +0000517 /* 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 */
543static 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 },
Paul Jakma18ab08b2016-01-27 16:37:33 +0000623 { "IPv4-unreach-VPNv4",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400624 "IPv4/MPLS-labeled VPN MP Unreach, RD, 3 NLRIs",
Paul Jakma1eab26b2008-06-07 20:44:30 +0000625 {
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400626 /* AFI / SAFI */ 0x0, AFI_IP, SAFI_MPLS_LABELED_VPN,
Paul Jakma18ab08b2016-01-27 16:37:33 +0000627 /* 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 */
Paul Jakma1eab26b2008-06-07 20:44:30 +0000639 },
Paul Jakma18ab08b2016-01-27 16:37:33 +0000640 (3 + (1+3+8+2) + (1+3+8+3)),
Paul Jakma1eab26b2008-06-07 20:44:30 +0000641 SHOULD_PARSE,
Paul Jakma18ab08b2016-01-27 16:37:33 +0000642 AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakma1eab26b2008-06-07 20:44:30 +0000643 },
644 { NULL, NULL, {0}, 0, 0}
645};
646
Paul Jakma18ab08b2016-01-27 16:37:33 +0000647/* 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 */
651static void
652handle_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}
Paul Jakma1eab26b2008-06-07 20:44:30 +0000690
691/* basic parsing test */
692static void
693parse_test (struct peer *peer, struct test_segment *t, int type)
694{
Paul Jakma18ab08b2016-01-27 16:37:33 +0000695 int parse_ret = 0, nlri_ret = 0;
David Lamparteraeef13b2013-01-23 04:20:37 +0100696 struct attr attr = { };
697 struct bgp_nlri nlri = { };
Paul Jakma1dba2542012-05-01 16:20:33 +0100698 struct bgp_attr_parser_args attr_args = {
699 .peer = peer,
700 .length = t->len,
701 .total = 1,
702 .attr = &attr,
Paul Jakma18ab08b2016-01-27 16:37:33 +0000703 .type = type,
Paul Jakma1dba2542012-05-01 16:20:33 +0100704 .flags = BGP_ATTR_FLAG_OPTIONAL,
705 .startp = BGP_INPUT_PNT (peer),
706 };
Paul Jakma1eab26b2008-06-07 20:44:30 +0000707#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);
Paul Jakma1dba2542012-05-01 16:20:33 +0100716
Paul Jakma1eab26b2008-06-07 20:44:30 +0000717 if (type == BGP_ATTR_MP_REACH_NLRI)
Paul Jakma18ab08b2016-01-27 16:37:33 +0000718 parse_ret = bgp_mp_reach_parse (&attr_args, &nlri);
Paul Jakma1eab26b2008-06-07 20:44:30 +0000719 else
Paul Jakma18ab08b2016-01-27 16:37:33 +0000720 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)
Paul Jakma1eab26b2008-06-07 20:44:30 +0000726 {
Paul Jakma18ab08b2016-01-27 16:37:33 +0000727 if (type == BGP_ATTR_MP_REACH_NLRI)
Paul Jakma518a4b72016-02-04 13:27:04 +0000728 nlri_ret = bgp_nlri_parse (peer, &attr, &nlri);
Paul Jakma18ab08b2016-01-27 16:37:33 +0000729 else
Paul Jakma518a4b72016-02-04 13:27:04 +0000730 nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
Paul Jakma1eab26b2008-06-07 20:44:30 +0000731 }
732
Paul Jakma18ab08b2016-01-27 16:37:33 +0000733 handle_result (peer, t, parse_ret, nlri_ret);
Paul Jakma1eab26b2008-06-07 20:44:30 +0000734}
735
736static struct bgp *bgp;
737static as_t asn = 100;
738
739int
740main (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 ();
Paul Jakmac9e4f862012-06-14 10:42:39 +0100758 bgp_option_set (BGP_OPT_NO_LISTEN);
Paul Jakma18ab08b2016-01-27 16:37:33 +0000759 bgp_attr_init ();
760 bgp_address_init ();
Paul Jakma4b502fd2016-07-27 17:06:32 +0100761 bgp_scan_init ();
Paul Jakma1eab26b2008-06-07 20:44:30 +0000762
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);
David Lamparterc3138952015-04-21 10:02:23 +0200770 peer->host = (char *)"foo";
Paul Jakma18ab08b2016-01-27 16:37:33 +0000771 peer->status = Established;
Paul Jakma1eab26b2008-06-07 20:44:30 +0000772
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}