blob: 0c4533be12301c11e63bf01092360ada4ce6c6ca [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* MPLS-VPN
2 Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "command.h"
24#include "prefix.h"
25#include "log.h"
26#include "memory.h"
27#include "stream.h"
Donald Sharp04907292016-01-07 10:03:01 -050028#include "filter.h"
paul718e3742002-12-13 20:15:29 +000029
30#include "bgpd/bgpd.h"
31#include "bgpd/bgp_table.h"
32#include "bgpd/bgp_route.h"
33#include "bgpd/bgp_attr.h"
34#include "bgpd/bgp_mplsvpn.h"
35
paul94f2b392005-06-28 12:44:16 +000036static u_int16_t
paul718e3742002-12-13 20:15:29 +000037decode_rd_type (u_char *pnt)
38{
39 u_int16_t v;
40
41 v = ((u_int16_t) *pnt++ << 8);
42 v |= (u_int16_t) *pnt;
43 return v;
44}
45
46u_int32_t
47decode_label (u_char *pnt)
48{
49 u_int32_t l;
50
51 l = ((u_int32_t) *pnt++ << 12);
52 l |= (u_int32_t) *pnt++ << 4;
53 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
54 return l;
55}
56
paul94f2b392005-06-28 12:44:16 +000057static void
paul718e3742002-12-13 20:15:29 +000058decode_rd_as (u_char *pnt, struct rd_as *rd_as)
59{
60 rd_as->as = (u_int16_t) *pnt++ << 8;
61 rd_as->as |= (u_int16_t) *pnt++;
62
63 rd_as->val = ((u_int32_t) *pnt++ << 24);
64 rd_as->val |= ((u_int32_t) *pnt++ << 16);
65 rd_as->val |= ((u_int32_t) *pnt++ << 8);
66 rd_as->val |= (u_int32_t) *pnt;
67}
68
paul94f2b392005-06-28 12:44:16 +000069static void
paul718e3742002-12-13 20:15:29 +000070decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
71{
72 memcpy (&rd_ip->ip, pnt, 4);
73 pnt += 4;
74
75 rd_ip->val = ((u_int16_t) *pnt++ << 8);
76 rd_ip->val |= (u_int16_t) *pnt;
77}
78
paul718e3742002-12-13 20:15:29 +000079int
80bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
81 struct bgp_nlri *packet)
82{
83 u_char *pnt;
84 u_char *lim;
85 struct prefix p;
86 int psize;
87 int prefixlen;
paul718e3742002-12-13 20:15:29 +000088 u_int16_t type;
89 struct rd_as rd_as;
90 struct rd_ip rd_ip;
91 struct prefix_rd prd;
92 u_char *tagpnt;
93
94 /* Check peer status. */
95 if (peer->status != Established)
96 return 0;
97
98 /* Make prefix_rd */
99 prd.family = AF_UNSPEC;
100 prd.prefixlen = 64;
101
102 pnt = packet->nlri;
103 lim = pnt + packet->length;
104
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000105#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
paul718e3742002-12-13 20:15:29 +0000106 for (; pnt < lim; pnt += psize)
107 {
108 /* Clear prefix structure. */
109 memset (&p, 0, sizeof (struct prefix));
110
111 /* Fetch prefix length. */
112 prefixlen = *pnt++;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000113 p.family = afi2family (packet->afi);
paul718e3742002-12-13 20:15:29 +0000114 psize = PSIZE (prefixlen);
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000115
116 /* sanity check against packet data */
117 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8 || (pnt + psize) > lim)
118 {
119 zlog_err ("prefix length (%d) is less than 88"
120 " or larger than received (%u)",
121 prefixlen, (uint)(lim-pnt));
122 return -1;
123 }
124
125 /* sanity check against storage for the IP address portion */
126 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
127 {
128 zlog_err ("prefix length (%d) exceeds prefix storage (%zu)",
129 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
130 return -1;
131 }
132
133 /* Sanity check against max bitlen of the address family */
134 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
135 {
136 zlog_err ("prefix length (%d) exceeds family (%u) max byte length (%u)",
137 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
138 p.family, prefix_blen (&p));
139 return -1;
140
141 }
142
paul718e3742002-12-13 20:15:29 +0000143 /* Copyr label to prefix. */
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000144 tagpnt = pnt;
paul718e3742002-12-13 20:15:29 +0000145
146 /* Copy routing distinguisher to rd. */
147 memcpy (&prd.val, pnt + 3, 8);
148
149 /* Decode RD type. */
150 type = decode_rd_type (pnt + 3);
151
152 /* Decode RD value. */
153 if (type == RD_TYPE_AS)
154 decode_rd_as (pnt + 5, &rd_as);
155 else if (type == RD_TYPE_IP)
156 decode_rd_ip (pnt + 5, &rd_ip);
157 else
158 {
159 zlog_err ("Invalid RD type %d", type);
160 return -1;
161 }
162
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000163 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
164 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
165 psize - VPN_PREFIXLEN_MIN_BYTES);
paul718e3742002-12-13 20:15:29 +0000166
167#if 0
168 if (type == RD_TYPE_AS)
169 zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
170 inet_ntoa (p.u.prefix4), p.prefixlen);
171 else if (type == RD_TYPE_IP)
172 zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
173 rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
174#endif /* 0 */
175
paul718e3742002-12-13 20:15:29 +0000176 if (attr)
177 bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
paul94f2b392005-06-28 12:44:16 +0000178 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000179 else
180 bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
181 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
182 }
paul718e3742002-12-13 20:15:29 +0000183 /* Packet length consistency check. */
184 if (pnt != lim)
185 return -1;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000186
paul718e3742002-12-13 20:15:29 +0000187 return 0;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000188#undef VPN_PREFIXLEN_MIN_BYTES
paul718e3742002-12-13 20:15:29 +0000189}
190
191int
paulfd79ac92004-10-13 05:06:08 +0000192str2prefix_rd (const char *str, struct prefix_rd *prd)
paul718e3742002-12-13 20:15:29 +0000193{
Lou Berger056f3762013-04-10 12:30:04 -0700194 int ret; /* ret of called functions */
195 int lret; /* local ret, of this func */
paul5228ad22004-06-04 17:58:18 +0000196 char *p;
197 char *p2;
Lou Berger056f3762013-04-10 12:30:04 -0700198 struct stream *s = NULL;
199 char *half = NULL;
paul718e3742002-12-13 20:15:29 +0000200 struct in_addr addr;
201
202 s = stream_new (8);
203
204 prd->family = AF_UNSPEC;
205 prd->prefixlen = 64;
206
Lou Berger056f3762013-04-10 12:30:04 -0700207 lret = 0;
paul718e3742002-12-13 20:15:29 +0000208 p = strchr (str, ':');
209 if (! p)
Lou Berger056f3762013-04-10 12:30:04 -0700210 goto out;
paul718e3742002-12-13 20:15:29 +0000211
212 if (! all_digit (p + 1))
Lou Berger056f3762013-04-10 12:30:04 -0700213 goto out;
paul718e3742002-12-13 20:15:29 +0000214
215 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
216 memcpy (half, str, (p - str));
217 half[p - str] = '\0';
218
219 p2 = strchr (str, '.');
220
221 if (! p2)
222 {
223 if (! all_digit (half))
Lou Berger056f3762013-04-10 12:30:04 -0700224 goto out;
225
paul718e3742002-12-13 20:15:29 +0000226 stream_putw (s, RD_TYPE_AS);
227 stream_putw (s, atoi (half));
228 stream_putl (s, atol (p + 1));
229 }
230 else
231 {
232 ret = inet_aton (half, &addr);
233 if (! ret)
Lou Berger056f3762013-04-10 12:30:04 -0700234 goto out;
235
paul718e3742002-12-13 20:15:29 +0000236 stream_putw (s, RD_TYPE_IP);
237 stream_put_in_addr (s, &addr);
238 stream_putw (s, atol (p + 1));
239 }
240 memcpy (prd->val, s->data, 8);
Lou Berger056f3762013-04-10 12:30:04 -0700241 lret = 1;
paul718e3742002-12-13 20:15:29 +0000242
Lou Berger056f3762013-04-10 12:30:04 -0700243out:
244 if (s)
245 stream_free (s);
246 if (half)
247 XFREE(MTYPE_TMP, half);
248 return lret;
paul718e3742002-12-13 20:15:29 +0000249}
250
251int
paulfd79ac92004-10-13 05:06:08 +0000252str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000253{
paulfd79ac92004-10-13 05:06:08 +0000254 unsigned long l;
255 char *endptr;
256 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000257
Ulrich Weber664711c2011-12-21 02:24:11 +0400258 if (*str == '-')
259 return 0;
paulfd79ac92004-10-13 05:06:08 +0000260
Ulrich Weber664711c2011-12-21 02:24:11 +0400261 errno = 0;
262 l = strtoul (str, &endptr, 10);
263
264 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000265 return 0;
paul718e3742002-12-13 20:15:29 +0000266
paulfd79ac92004-10-13 05:06:08 +0000267 t = (u_int32_t) l;
268
269 tag[0] = (u_char)(t >> 12);
270 tag[1] = (u_char)(t >> 4);
271 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000272
273 return 1;
274}
275
276char *
277prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
278{
279 u_char *pnt;
280 u_int16_t type;
281 struct rd_as rd_as;
282 struct rd_ip rd_ip;
283
284 if (size < RD_ADDRSTRLEN)
285 return NULL;
286
287 pnt = prd->val;
288
289 type = decode_rd_type (pnt);
290
291 if (type == RD_TYPE_AS)
292 {
293 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400294 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000295 return buf;
296 }
297 else if (type == RD_TYPE_IP)
298 {
299 decode_rd_ip (pnt + 2, &rd_ip);
300 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
301 return buf;
302 }
303
304 return NULL;
305}
306
307/* For testing purpose, static route of MPLS-VPN. */
308DEFUN (vpnv4_network,
309 vpnv4_network_cmd,
310 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
311 "Specify a network to announce via BGP\n"
312 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
313 "Specify Route Distinguisher\n"
314 "VPN Route Distinguisher\n"
315 "BGP tag\n"
316 "tag value\n")
317{
318 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
319}
320
321/* For testing purpose, static route of MPLS-VPN. */
322DEFUN (no_vpnv4_network,
323 no_vpnv4_network_cmd,
324 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
325 NO_STR
326 "Specify a network to announce via BGP\n"
327 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
328 "Specify Route Distinguisher\n"
329 "VPN Route Distinguisher\n"
330 "BGP tag\n"
331 "tag value\n")
332{
333 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
334}
335
paul94f2b392005-06-28 12:44:16 +0000336static int
paul718e3742002-12-13 20:15:29 +0000337show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
338{
339 struct bgp *bgp;
340 struct bgp_table *table;
341 struct bgp_node *rn;
342 struct bgp_node *rm;
343 struct attr *attr;
344 int rd_header;
345 int header = 1;
346 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
347
348 bgp = bgp_get_default ();
349 if (bgp == NULL)
350 {
351 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
352 return CMD_WARNING;
353 }
354
355 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
356 rn = bgp_route_next (rn))
357 {
358 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
359 continue;
360
361 if ((table = rn->info) != NULL)
362 {
363 rd_header = 1;
364
365 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
366 if ((attr = rm->info) != NULL)
367 {
368 if (header)
369 {
370 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
371 inet_ntoa (bgp->router_id), VTY_NEWLINE);
372 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
373 VTY_NEWLINE);
374 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
375 VTY_NEWLINE, VTY_NEWLINE);
376 vty_out (vty, v4_header, VTY_NEWLINE);
377 header = 0;
378 }
379
380 if (rd_header)
381 {
382 u_int16_t type;
383 struct rd_as rd_as;
384 struct rd_ip rd_ip;
385 u_char *pnt;
386
387 pnt = rn->p.u.val;
388
389 /* Decode RD type. */
390 type = decode_rd_type (pnt);
391 /* Decode RD value. */
392 if (type == RD_TYPE_AS)
393 decode_rd_as (pnt + 2, &rd_as);
394 else if (type == RD_TYPE_IP)
395 decode_rd_ip (pnt + 2, &rd_ip);
396
397 vty_out (vty, "Route Distinguisher: ");
398
399 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400400 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000401 else if (type == RD_TYPE_IP)
402 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
403
404 vty_out (vty, "%s", VTY_NEWLINE);
405 rd_header = 0;
406 }
407 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
408 }
409 }
410 }
411 return CMD_SUCCESS;
412}
413
414enum bgp_show_type
415{
416 bgp_show_type_normal,
417 bgp_show_type_regexp,
418 bgp_show_type_prefix_list,
419 bgp_show_type_filter_list,
420 bgp_show_type_neighbor,
421 bgp_show_type_cidr_only,
422 bgp_show_type_prefix_longer,
423 bgp_show_type_community_all,
424 bgp_show_type_community,
425 bgp_show_type_community_exact,
426 bgp_show_type_community_list,
427 bgp_show_type_community_list_exact
428};
429
paul94f2b392005-06-28 12:44:16 +0000430static int
paul718e3742002-12-13 20:15:29 +0000431bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
432 void *output_arg, int tags)
433{
434 struct bgp *bgp;
435 struct bgp_table *table;
436 struct bgp_node *rn;
437 struct bgp_node *rm;
438 struct bgp_info *ri;
439 int rd_header;
440 int header = 1;
441 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
442 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
443
444 bgp = bgp_get_default ();
445 if (bgp == NULL)
446 {
447 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
448 return CMD_WARNING;
449 }
450
451 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
452 {
453 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
454 continue;
455
456 if ((table = rn->info) != NULL)
457 {
458 rd_header = 1;
459
460 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
461 for (ri = rm->info; ri; ri = ri->next)
462 {
463 if (type == bgp_show_type_neighbor)
464 {
465 union sockunion *su = output_arg;
466
467 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
468 continue;
469 }
470 if (header)
471 {
472 if (tags)
473 vty_out (vty, v4_header_tag, VTY_NEWLINE);
474 else
475 {
476 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
477 inet_ntoa (bgp->router_id), VTY_NEWLINE);
478 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
479 VTY_NEWLINE);
480 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
481 VTY_NEWLINE, VTY_NEWLINE);
482 vty_out (vty, v4_header, VTY_NEWLINE);
483 }
484 header = 0;
485 }
486
487 if (rd_header)
488 {
489 u_int16_t type;
490 struct rd_as rd_as;
491 struct rd_ip rd_ip;
492 u_char *pnt;
493
494 pnt = rn->p.u.val;
495
496 /* Decode RD type. */
497 type = decode_rd_type (pnt);
498 /* Decode RD value. */
499 if (type == RD_TYPE_AS)
500 decode_rd_as (pnt + 2, &rd_as);
501 else if (type == RD_TYPE_IP)
502 decode_rd_ip (pnt + 2, &rd_ip);
503
504 vty_out (vty, "Route Distinguisher: ");
505
506 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400507 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000508 else if (type == RD_TYPE_IP)
509 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
510
511 vty_out (vty, "%s", VTY_NEWLINE);
512 rd_header = 0;
513 }
514 if (tags)
515 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
516 else
517 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
518 }
519 }
520 }
521 return CMD_SUCCESS;
522}
523
524DEFUN (show_ip_bgp_vpnv4_all,
525 show_ip_bgp_vpnv4_all_cmd,
526 "show ip bgp vpnv4 all",
527 SHOW_STR
528 IP_STR
529 BGP_STR
530 "Display VPNv4 NLRI specific information\n"
531 "Display information about all VPNv4 NLRIs\n")
532{
533 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
534}
535
536DEFUN (show_ip_bgp_vpnv4_rd,
537 show_ip_bgp_vpnv4_rd_cmd,
538 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
539 SHOW_STR
540 IP_STR
541 BGP_STR
542 "Display VPNv4 NLRI specific information\n"
543 "Display information for a route distinguisher\n"
544 "VPN Route Distinguisher\n")
545{
546 int ret;
547 struct prefix_rd prd;
548
549 ret = str2prefix_rd (argv[0], &prd);
550 if (! ret)
551 {
552 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
553 return CMD_WARNING;
554 }
555 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
556}
557
558DEFUN (show_ip_bgp_vpnv4_all_tags,
559 show_ip_bgp_vpnv4_all_tags_cmd,
560 "show ip bgp vpnv4 all tags",
561 SHOW_STR
562 IP_STR
563 BGP_STR
564 "Display VPNv4 NLRI specific information\n"
565 "Display information about all VPNv4 NLRIs\n"
566 "Display BGP tags for prefixes\n")
567{
568 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
569}
570
571DEFUN (show_ip_bgp_vpnv4_rd_tags,
572 show_ip_bgp_vpnv4_rd_tags_cmd,
573 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
574 SHOW_STR
575 IP_STR
576 BGP_STR
577 "Display VPNv4 NLRI specific information\n"
578 "Display information for a route distinguisher\n"
579 "VPN Route Distinguisher\n"
580 "Display BGP tags for prefixes\n")
581{
582 int ret;
583 struct prefix_rd prd;
584
585 ret = str2prefix_rd (argv[0], &prd);
586 if (! ret)
587 {
588 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
589 return CMD_WARNING;
590 }
591 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
592}
593
594DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
595 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
596 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
597 SHOW_STR
598 IP_STR
599 BGP_STR
600 "Display VPNv4 NLRI specific information\n"
601 "Display information about all VPNv4 NLRIs\n"
602 "Detailed information on TCP and BGP neighbor connections\n"
603 "Neighbor to display information about\n"
604 "Display routes learned from neighbor\n")
605{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200606 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000607 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200608 int ret;
609
610 ret = str2sockunion (argv[0], &su);
611 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000612 {
613 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200614 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000615 }
616
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200617 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000618 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
619 {
620 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
621 return CMD_WARNING;
622 }
623
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200624 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000625}
626
627DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
628 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
629 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
630 SHOW_STR
631 IP_STR
632 BGP_STR
633 "Display VPNv4 NLRI specific information\n"
634 "Display information for a route distinguisher\n"
635 "VPN Route Distinguisher\n"
636 "Detailed information on TCP and BGP neighbor connections\n"
637 "Neighbor to display information about\n"
638 "Display routes learned from neighbor\n")
639{
640 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200641 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000642 struct peer *peer;
643 struct prefix_rd prd;
644
645 ret = str2prefix_rd (argv[0], &prd);
646 if (! ret)
647 {
648 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
649 return CMD_WARNING;
650 }
651
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200652 ret = str2sockunion (argv[1], &su);
653 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000654 {
655 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200656 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000657 }
658
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200659 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000660 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
661 {
662 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
663 return CMD_WARNING;
664 }
665
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200666 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000667}
668
669DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
670 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
671 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
672 SHOW_STR
673 IP_STR
674 BGP_STR
675 "Display VPNv4 NLRI specific information\n"
676 "Display information about all VPNv4 NLRIs\n"
677 "Detailed information on TCP and BGP neighbor connections\n"
678 "Neighbor to display information about\n"
679 "Display the routes advertised to a BGP neighbor\n")
680{
681 int ret;
682 struct peer *peer;
683 union sockunion su;
684
685 ret = str2sockunion (argv[0], &su);
686 if (ret < 0)
687 {
688 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
689 return CMD_WARNING;
690 }
691 peer = peer_lookup (NULL, &su);
692 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
693 {
694 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
695 return CMD_WARNING;
696 }
697
698 return show_adj_route_vpn (vty, peer, NULL);
699}
700
701DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
702 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
703 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
704 SHOW_STR
705 IP_STR
706 BGP_STR
707 "Display VPNv4 NLRI specific information\n"
708 "Display information for a route distinguisher\n"
709 "VPN Route Distinguisher\n"
710 "Detailed information on TCP and BGP neighbor connections\n"
711 "Neighbor to display information about\n"
712 "Display the routes advertised to a BGP neighbor\n")
713{
714 int ret;
715 struct peer *peer;
716 struct prefix_rd prd;
717 union sockunion su;
718
719 ret = str2sockunion (argv[1], &su);
720 if (ret < 0)
721 {
722 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
723 return CMD_WARNING;
724 }
725 peer = peer_lookup (NULL, &su);
726 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
727 {
728 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
729 return CMD_WARNING;
730 }
731
732 ret = str2prefix_rd (argv[0], &prd);
733 if (! ret)
734 {
735 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
736 return CMD_WARNING;
737 }
738
739 return show_adj_route_vpn (vty, peer, &prd);
740}
741
742void
paul94f2b392005-06-28 12:44:16 +0000743bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000744{
745 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
746 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
747
748
749 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
750 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
751 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
752 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
753 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
754 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
755 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
756 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
757
758 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
759 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
760 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
761 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
762 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
763 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
764 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
765 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
766}