blob: 75c90cd776a7bc2c1ae996d2a174fa15e822272b [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"
28
29#include "bgpd/bgpd.h"
30#include "bgpd/bgp_table.h"
31#include "bgpd/bgp_route.h"
32#include "bgpd/bgp_attr.h"
33#include "bgpd/bgp_mplsvpn.h"
34
paul94f2b392005-06-28 12:44:16 +000035static u_int16_t
paul718e3742002-12-13 20:15:29 +000036decode_rd_type (u_char *pnt)
37{
38 u_int16_t v;
39
40 v = ((u_int16_t) *pnt++ << 8);
41 v |= (u_int16_t) *pnt;
42 return v;
43}
44
45u_int32_t
46decode_label (u_char *pnt)
47{
48 u_int32_t l;
49
50 l = ((u_int32_t) *pnt++ << 12);
51 l |= (u_int32_t) *pnt++ << 4;
52 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
53 return l;
54}
55
paul94f2b392005-06-28 12:44:16 +000056static void
paul718e3742002-12-13 20:15:29 +000057decode_rd_as (u_char *pnt, struct rd_as *rd_as)
58{
59 rd_as->as = (u_int16_t) *pnt++ << 8;
60 rd_as->as |= (u_int16_t) *pnt++;
61
62 rd_as->val = ((u_int32_t) *pnt++ << 24);
63 rd_as->val |= ((u_int32_t) *pnt++ << 16);
64 rd_as->val |= ((u_int32_t) *pnt++ << 8);
65 rd_as->val |= (u_int32_t) *pnt;
66}
67
paul94f2b392005-06-28 12:44:16 +000068static void
paul718e3742002-12-13 20:15:29 +000069decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
70{
71 memcpy (&rd_ip->ip, pnt, 4);
72 pnt += 4;
73
74 rd_ip->val = ((u_int16_t) *pnt++ << 8);
75 rd_ip->val |= (u_int16_t) *pnt;
76}
77
paul718e3742002-12-13 20:15:29 +000078int
79bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
80 struct bgp_nlri *packet)
81{
82 u_char *pnt;
83 u_char *lim;
84 struct prefix p;
85 int psize;
86 int prefixlen;
paul718e3742002-12-13 20:15:29 +000087 u_int16_t type;
88 struct rd_as rd_as;
89 struct rd_ip rd_ip;
90 struct prefix_rd prd;
91 u_char *tagpnt;
92
93 /* Check peer status. */
94 if (peer->status != Established)
95 return 0;
96
97 /* Make prefix_rd */
98 prd.family = AF_UNSPEC;
99 prd.prefixlen = 64;
100
101 pnt = packet->nlri;
102 lim = pnt + packet->length;
103
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000104#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
paul718e3742002-12-13 20:15:29 +0000105 for (; pnt < lim; pnt += psize)
106 {
107 /* Clear prefix structure. */
108 memset (&p, 0, sizeof (struct prefix));
109
110 /* Fetch prefix length. */
111 prefixlen = *pnt++;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000112 p.family = afi2family (packet->afi);
paul718e3742002-12-13 20:15:29 +0000113 psize = PSIZE (prefixlen);
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000114
115 /* sanity check against packet data */
116 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8 || (pnt + psize) > lim)
117 {
118 zlog_err ("prefix length (%d) is less than 88"
119 " or larger than received (%u)",
120 prefixlen, (uint)(lim-pnt));
121 return -1;
122 }
123
124 /* sanity check against storage for the IP address portion */
125 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
126 {
127 zlog_err ("prefix length (%d) exceeds prefix storage (%zu)",
128 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
129 return -1;
130 }
131
132 /* Sanity check against max bitlen of the address family */
133 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
134 {
135 zlog_err ("prefix length (%d) exceeds family (%u) max byte length (%u)",
136 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
137 p.family, prefix_blen (&p));
138 return -1;
139
140 }
141
paul718e3742002-12-13 20:15:29 +0000142 /* Copyr label to prefix. */
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000143 tagpnt = pnt;
paul718e3742002-12-13 20:15:29 +0000144
145 /* Copy routing distinguisher to rd. */
146 memcpy (&prd.val, pnt + 3, 8);
147
148 /* Decode RD type. */
149 type = decode_rd_type (pnt + 3);
150
151 /* Decode RD value. */
152 if (type == RD_TYPE_AS)
153 decode_rd_as (pnt + 5, &rd_as);
154 else if (type == RD_TYPE_IP)
155 decode_rd_ip (pnt + 5, &rd_ip);
156 else
157 {
158 zlog_err ("Invalid RD type %d", type);
159 return -1;
160 }
161
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000162 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
163 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
164 psize - VPN_PREFIXLEN_MIN_BYTES);
paul718e3742002-12-13 20:15:29 +0000165
166#if 0
167 if (type == RD_TYPE_AS)
168 zlog_info ("prefix %ld:%ld:%ld:%s/%d", label, rd_as.as, rd_as.val,
169 inet_ntoa (p.u.prefix4), p.prefixlen);
170 else if (type == RD_TYPE_IP)
171 zlog_info ("prefix %ld:%s:%ld:%s/%d", label, inet_ntoa (rd_ip.ip),
172 rd_ip.val, inet_ntoa (p.u.prefix4), p.prefixlen);
173#endif /* 0 */
174
paul718e3742002-12-13 20:15:29 +0000175 if (attr)
176 bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
paul94f2b392005-06-28 12:44:16 +0000177 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000178 else
179 bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
180 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
181 }
paul718e3742002-12-13 20:15:29 +0000182 /* Packet length consistency check. */
183 if (pnt != lim)
184 return -1;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000185
paul718e3742002-12-13 20:15:29 +0000186 return 0;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000187#undef VPN_PREFIXLEN_MIN_BYTES
paul718e3742002-12-13 20:15:29 +0000188}
189
190int
paulfd79ac92004-10-13 05:06:08 +0000191str2prefix_rd (const char *str, struct prefix_rd *prd)
paul718e3742002-12-13 20:15:29 +0000192{
Lou Berger056f3762013-04-10 12:30:04 -0700193 int ret; /* ret of called functions */
194 int lret; /* local ret, of this func */
paul5228ad22004-06-04 17:58:18 +0000195 char *p;
196 char *p2;
Lou Berger056f3762013-04-10 12:30:04 -0700197 struct stream *s = NULL;
198 char *half = NULL;
paul718e3742002-12-13 20:15:29 +0000199 struct in_addr addr;
200
201 s = stream_new (8);
202
203 prd->family = AF_UNSPEC;
204 prd->prefixlen = 64;
205
Lou Berger056f3762013-04-10 12:30:04 -0700206 lret = 0;
paul718e3742002-12-13 20:15:29 +0000207 p = strchr (str, ':');
208 if (! p)
Lou Berger056f3762013-04-10 12:30:04 -0700209 goto out;
paul718e3742002-12-13 20:15:29 +0000210
211 if (! all_digit (p + 1))
Lou Berger056f3762013-04-10 12:30:04 -0700212 goto out;
paul718e3742002-12-13 20:15:29 +0000213
214 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
215 memcpy (half, str, (p - str));
216 half[p - str] = '\0';
217
218 p2 = strchr (str, '.');
219
220 if (! p2)
221 {
222 if (! all_digit (half))
Lou Berger056f3762013-04-10 12:30:04 -0700223 goto out;
224
paul718e3742002-12-13 20:15:29 +0000225 stream_putw (s, RD_TYPE_AS);
226 stream_putw (s, atoi (half));
227 stream_putl (s, atol (p + 1));
228 }
229 else
230 {
231 ret = inet_aton (half, &addr);
232 if (! ret)
Lou Berger056f3762013-04-10 12:30:04 -0700233 goto out;
234
paul718e3742002-12-13 20:15:29 +0000235 stream_putw (s, RD_TYPE_IP);
236 stream_put_in_addr (s, &addr);
237 stream_putw (s, atol (p + 1));
238 }
239 memcpy (prd->val, s->data, 8);
Lou Berger056f3762013-04-10 12:30:04 -0700240 lret = 1;
paul718e3742002-12-13 20:15:29 +0000241
Lou Berger056f3762013-04-10 12:30:04 -0700242out:
243 if (s)
244 stream_free (s);
245 if (half)
246 XFREE(MTYPE_TMP, half);
247 return lret;
paul718e3742002-12-13 20:15:29 +0000248}
249
250int
paulfd79ac92004-10-13 05:06:08 +0000251str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000252{
paulfd79ac92004-10-13 05:06:08 +0000253 unsigned long l;
254 char *endptr;
255 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000256
Ulrich Weber664711c2011-12-21 02:24:11 +0400257 if (*str == '-')
258 return 0;
paulfd79ac92004-10-13 05:06:08 +0000259
Ulrich Weber664711c2011-12-21 02:24:11 +0400260 errno = 0;
261 l = strtoul (str, &endptr, 10);
262
263 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000264 return 0;
paul718e3742002-12-13 20:15:29 +0000265
paulfd79ac92004-10-13 05:06:08 +0000266 t = (u_int32_t) l;
267
268 tag[0] = (u_char)(t >> 12);
269 tag[1] = (u_char)(t >> 4);
270 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000271
272 return 1;
273}
274
275char *
276prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
277{
278 u_char *pnt;
279 u_int16_t type;
280 struct rd_as rd_as;
281 struct rd_ip rd_ip;
282
283 if (size < RD_ADDRSTRLEN)
284 return NULL;
285
286 pnt = prd->val;
287
288 type = decode_rd_type (pnt);
289
290 if (type == RD_TYPE_AS)
291 {
292 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400293 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000294 return buf;
295 }
296 else if (type == RD_TYPE_IP)
297 {
298 decode_rd_ip (pnt + 2, &rd_ip);
299 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
300 return buf;
301 }
302
303 return NULL;
304}
305
306/* For testing purpose, static route of MPLS-VPN. */
307DEFUN (vpnv4_network,
308 vpnv4_network_cmd,
309 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
310 "Specify a network to announce via BGP\n"
311 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
312 "Specify Route Distinguisher\n"
313 "VPN Route Distinguisher\n"
314 "BGP tag\n"
315 "tag value\n")
316{
317 return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
318}
319
320/* For testing purpose, static route of MPLS-VPN. */
321DEFUN (no_vpnv4_network,
322 no_vpnv4_network_cmd,
323 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
324 NO_STR
325 "Specify a network to announce via BGP\n"
326 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
327 "Specify Route Distinguisher\n"
328 "VPN Route Distinguisher\n"
329 "BGP tag\n"
330 "tag value\n")
331{
332 return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
333}
334
paul94f2b392005-06-28 12:44:16 +0000335static int
paul718e3742002-12-13 20:15:29 +0000336show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
337{
338 struct bgp *bgp;
339 struct bgp_table *table;
340 struct bgp_node *rn;
341 struct bgp_node *rm;
342 struct attr *attr;
343 int rd_header;
344 int header = 1;
345 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
346
347 bgp = bgp_get_default ();
348 if (bgp == NULL)
349 {
350 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
351 return CMD_WARNING;
352 }
353
354 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
355 rn = bgp_route_next (rn))
356 {
357 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
358 continue;
359
360 if ((table = rn->info) != NULL)
361 {
362 rd_header = 1;
363
364 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
365 if ((attr = rm->info) != NULL)
366 {
367 if (header)
368 {
369 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
370 inet_ntoa (bgp->router_id), VTY_NEWLINE);
371 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
372 VTY_NEWLINE);
373 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
374 VTY_NEWLINE, VTY_NEWLINE);
375 vty_out (vty, v4_header, VTY_NEWLINE);
376 header = 0;
377 }
378
379 if (rd_header)
380 {
381 u_int16_t type;
382 struct rd_as rd_as;
383 struct rd_ip rd_ip;
384 u_char *pnt;
385
386 pnt = rn->p.u.val;
387
388 /* Decode RD type. */
389 type = decode_rd_type (pnt);
390 /* Decode RD value. */
391 if (type == RD_TYPE_AS)
392 decode_rd_as (pnt + 2, &rd_as);
393 else if (type == RD_TYPE_IP)
394 decode_rd_ip (pnt + 2, &rd_ip);
395
396 vty_out (vty, "Route Distinguisher: ");
397
398 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400399 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000400 else if (type == RD_TYPE_IP)
401 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
402
403 vty_out (vty, "%s", VTY_NEWLINE);
404 rd_header = 0;
405 }
406 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
407 }
408 }
409 }
410 return CMD_SUCCESS;
411}
412
413enum bgp_show_type
414{
415 bgp_show_type_normal,
416 bgp_show_type_regexp,
417 bgp_show_type_prefix_list,
418 bgp_show_type_filter_list,
419 bgp_show_type_neighbor,
420 bgp_show_type_cidr_only,
421 bgp_show_type_prefix_longer,
422 bgp_show_type_community_all,
423 bgp_show_type_community,
424 bgp_show_type_community_exact,
425 bgp_show_type_community_list,
426 bgp_show_type_community_list_exact
427};
428
paul94f2b392005-06-28 12:44:16 +0000429static int
paul718e3742002-12-13 20:15:29 +0000430bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
431 void *output_arg, int tags)
432{
433 struct bgp *bgp;
434 struct bgp_table *table;
435 struct bgp_node *rn;
436 struct bgp_node *rm;
437 struct bgp_info *ri;
438 int rd_header;
439 int header = 1;
440 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
441 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
442
443 bgp = bgp_get_default ();
444 if (bgp == NULL)
445 {
446 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
447 return CMD_WARNING;
448 }
449
450 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
451 {
452 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
453 continue;
454
455 if ((table = rn->info) != NULL)
456 {
457 rd_header = 1;
458
459 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
460 for (ri = rm->info; ri; ri = ri->next)
461 {
462 if (type == bgp_show_type_neighbor)
463 {
464 union sockunion *su = output_arg;
465
466 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
467 continue;
468 }
469 if (header)
470 {
471 if (tags)
472 vty_out (vty, v4_header_tag, VTY_NEWLINE);
473 else
474 {
475 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
476 inet_ntoa (bgp->router_id), VTY_NEWLINE);
477 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
478 VTY_NEWLINE);
479 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
480 VTY_NEWLINE, VTY_NEWLINE);
481 vty_out (vty, v4_header, VTY_NEWLINE);
482 }
483 header = 0;
484 }
485
486 if (rd_header)
487 {
488 u_int16_t type;
489 struct rd_as rd_as;
490 struct rd_ip rd_ip;
491 u_char *pnt;
492
493 pnt = rn->p.u.val;
494
495 /* Decode RD type. */
496 type = decode_rd_type (pnt);
497 /* Decode RD value. */
498 if (type == RD_TYPE_AS)
499 decode_rd_as (pnt + 2, &rd_as);
500 else if (type == RD_TYPE_IP)
501 decode_rd_ip (pnt + 2, &rd_ip);
502
503 vty_out (vty, "Route Distinguisher: ");
504
505 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400506 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000507 else if (type == RD_TYPE_IP)
508 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
509
510 vty_out (vty, "%s", VTY_NEWLINE);
511 rd_header = 0;
512 }
513 if (tags)
514 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
515 else
516 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
517 }
518 }
519 }
520 return CMD_SUCCESS;
521}
522
523DEFUN (show_ip_bgp_vpnv4_all,
524 show_ip_bgp_vpnv4_all_cmd,
525 "show ip bgp vpnv4 all",
526 SHOW_STR
527 IP_STR
528 BGP_STR
529 "Display VPNv4 NLRI specific information\n"
530 "Display information about all VPNv4 NLRIs\n")
531{
532 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
533}
534
535DEFUN (show_ip_bgp_vpnv4_rd,
536 show_ip_bgp_vpnv4_rd_cmd,
537 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
538 SHOW_STR
539 IP_STR
540 BGP_STR
541 "Display VPNv4 NLRI specific information\n"
542 "Display information for a route distinguisher\n"
543 "VPN Route Distinguisher\n")
544{
545 int ret;
546 struct prefix_rd prd;
547
548 ret = str2prefix_rd (argv[0], &prd);
549 if (! ret)
550 {
551 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
552 return CMD_WARNING;
553 }
554 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
555}
556
557DEFUN (show_ip_bgp_vpnv4_all_tags,
558 show_ip_bgp_vpnv4_all_tags_cmd,
559 "show ip bgp vpnv4 all tags",
560 SHOW_STR
561 IP_STR
562 BGP_STR
563 "Display VPNv4 NLRI specific information\n"
564 "Display information about all VPNv4 NLRIs\n"
565 "Display BGP tags for prefixes\n")
566{
567 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
568}
569
570DEFUN (show_ip_bgp_vpnv4_rd_tags,
571 show_ip_bgp_vpnv4_rd_tags_cmd,
572 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
573 SHOW_STR
574 IP_STR
575 BGP_STR
576 "Display VPNv4 NLRI specific information\n"
577 "Display information for a route distinguisher\n"
578 "VPN Route Distinguisher\n"
579 "Display BGP tags for prefixes\n")
580{
581 int ret;
582 struct prefix_rd prd;
583
584 ret = str2prefix_rd (argv[0], &prd);
585 if (! ret)
586 {
587 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
588 return CMD_WARNING;
589 }
590 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
591}
592
593DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
594 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
595 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
596 SHOW_STR
597 IP_STR
598 BGP_STR
599 "Display VPNv4 NLRI specific information\n"
600 "Display information about all VPNv4 NLRIs\n"
601 "Detailed information on TCP and BGP neighbor connections\n"
602 "Neighbor to display information about\n"
603 "Display routes learned from neighbor\n")
604{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200605 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000606 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200607 int ret;
608
609 ret = str2sockunion (argv[0], &su);
610 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000611 {
612 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200613 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000614 }
615
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200616 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000617 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
618 {
619 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
620 return CMD_WARNING;
621 }
622
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200623 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000624}
625
626DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
627 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
628 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
629 SHOW_STR
630 IP_STR
631 BGP_STR
632 "Display VPNv4 NLRI specific information\n"
633 "Display information for a route distinguisher\n"
634 "VPN Route Distinguisher\n"
635 "Detailed information on TCP and BGP neighbor connections\n"
636 "Neighbor to display information about\n"
637 "Display routes learned from neighbor\n")
638{
639 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200640 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000641 struct peer *peer;
642 struct prefix_rd prd;
643
644 ret = str2prefix_rd (argv[0], &prd);
645 if (! ret)
646 {
647 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
648 return CMD_WARNING;
649 }
650
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200651 ret = str2sockunion (argv[1], &su);
652 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000653 {
654 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200655 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000656 }
657
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200658 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000659 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
660 {
661 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
662 return CMD_WARNING;
663 }
664
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200665 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000666}
667
668DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
669 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
670 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
671 SHOW_STR
672 IP_STR
673 BGP_STR
674 "Display VPNv4 NLRI specific information\n"
675 "Display information about all VPNv4 NLRIs\n"
676 "Detailed information on TCP and BGP neighbor connections\n"
677 "Neighbor to display information about\n"
678 "Display the routes advertised to a BGP neighbor\n")
679{
680 int ret;
681 struct peer *peer;
682 union sockunion su;
683
684 ret = str2sockunion (argv[0], &su);
685 if (ret < 0)
686 {
687 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
688 return CMD_WARNING;
689 }
690 peer = peer_lookup (NULL, &su);
691 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
692 {
693 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
694 return CMD_WARNING;
695 }
696
697 return show_adj_route_vpn (vty, peer, NULL);
698}
699
700DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
701 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
702 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
703 SHOW_STR
704 IP_STR
705 BGP_STR
706 "Display VPNv4 NLRI specific information\n"
707 "Display information for a route distinguisher\n"
708 "VPN Route Distinguisher\n"
709 "Detailed information on TCP and BGP neighbor connections\n"
710 "Neighbor to display information about\n"
711 "Display the routes advertised to a BGP neighbor\n")
712{
713 int ret;
714 struct peer *peer;
715 struct prefix_rd prd;
716 union sockunion su;
717
718 ret = str2sockunion (argv[1], &su);
719 if (ret < 0)
720 {
721 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
722 return CMD_WARNING;
723 }
724 peer = peer_lookup (NULL, &su);
725 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
726 {
727 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
728 return CMD_WARNING;
729 }
730
731 ret = str2prefix_rd (argv[0], &prd);
732 if (! ret)
733 {
734 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
735 return CMD_WARNING;
736 }
737
738 return show_adj_route_vpn (vty, peer, &prd);
739}
740
741void
paul94f2b392005-06-28 12:44:16 +0000742bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000743{
744 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
745 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
746
747
748 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
749 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
750 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
751 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
752 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
753 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
754 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
755 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
756
757 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
758 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
759 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
760 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
761 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
762 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
763 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
764 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
765}