blob: 3eab76fc5b4be32bed6800068a46dcf1f43c415f [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{
Lou Bergera76d9ca2016-01-12 13:41:53 -0500318 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
319}
320
321DEFUN (vpnv4_network_route_map,
322 vpnv4_network_route_map_cmd,
323 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
324 "Specify a network to announce via BGP\n"
325 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
326 "Specify Route Distinguisher\n"
327 "VPN Route Distinguisher\n"
328 "BGP tag\n"
329 "tag value\n"
330 "route map\n"
331 "route map name\n")
332{
333 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000334}
335
336/* For testing purpose, static route of MPLS-VPN. */
337DEFUN (no_vpnv4_network,
338 no_vpnv4_network_cmd,
339 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
340 NO_STR
341 "Specify a network to announce via BGP\n"
342 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
343 "Specify Route Distinguisher\n"
344 "VPN Route Distinguisher\n"
345 "BGP tag\n"
346 "tag value\n")
347{
Lou Bergera76d9ca2016-01-12 13:41:53 -0500348 return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
paul718e3742002-12-13 20:15:29 +0000349}
350
paul94f2b392005-06-28 12:44:16 +0000351static int
paul718e3742002-12-13 20:15:29 +0000352show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
353{
354 struct bgp *bgp;
355 struct bgp_table *table;
356 struct bgp_node *rn;
357 struct bgp_node *rm;
358 struct attr *attr;
359 int rd_header;
360 int header = 1;
361 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
362
363 bgp = bgp_get_default ();
364 if (bgp == NULL)
365 {
366 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
367 return CMD_WARNING;
368 }
369
370 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
371 rn = bgp_route_next (rn))
372 {
373 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
374 continue;
375
376 if ((table = rn->info) != NULL)
377 {
378 rd_header = 1;
379
380 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
381 if ((attr = rm->info) != NULL)
382 {
383 if (header)
384 {
385 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
386 inet_ntoa (bgp->router_id), VTY_NEWLINE);
387 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
388 VTY_NEWLINE);
389 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
390 VTY_NEWLINE, VTY_NEWLINE);
391 vty_out (vty, v4_header, VTY_NEWLINE);
392 header = 0;
393 }
394
395 if (rd_header)
396 {
397 u_int16_t type;
398 struct rd_as rd_as;
399 struct rd_ip rd_ip;
400 u_char *pnt;
401
402 pnt = rn->p.u.val;
403
404 /* Decode RD type. */
405 type = decode_rd_type (pnt);
406 /* Decode RD value. */
407 if (type == RD_TYPE_AS)
408 decode_rd_as (pnt + 2, &rd_as);
409 else if (type == RD_TYPE_IP)
410 decode_rd_ip (pnt + 2, &rd_ip);
411
412 vty_out (vty, "Route Distinguisher: ");
413
414 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400415 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000416 else if (type == RD_TYPE_IP)
417 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
418
419 vty_out (vty, "%s", VTY_NEWLINE);
420 rd_header = 0;
421 }
422 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
423 }
424 }
425 }
426 return CMD_SUCCESS;
427}
428
429enum bgp_show_type
430{
431 bgp_show_type_normal,
432 bgp_show_type_regexp,
433 bgp_show_type_prefix_list,
434 bgp_show_type_filter_list,
435 bgp_show_type_neighbor,
436 bgp_show_type_cidr_only,
437 bgp_show_type_prefix_longer,
438 bgp_show_type_community_all,
439 bgp_show_type_community,
440 bgp_show_type_community_exact,
441 bgp_show_type_community_list,
442 bgp_show_type_community_list_exact
443};
444
paul94f2b392005-06-28 12:44:16 +0000445static int
paul718e3742002-12-13 20:15:29 +0000446bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
447 void *output_arg, int tags)
448{
449 struct bgp *bgp;
450 struct bgp_table *table;
451 struct bgp_node *rn;
452 struct bgp_node *rm;
453 struct bgp_info *ri;
454 int rd_header;
455 int header = 1;
456 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
457 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
458
459 bgp = bgp_get_default ();
460 if (bgp == NULL)
461 {
462 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
463 return CMD_WARNING;
464 }
465
466 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
467 {
468 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
469 continue;
470
471 if ((table = rn->info) != NULL)
472 {
473 rd_header = 1;
474
475 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
476 for (ri = rm->info; ri; ri = ri->next)
477 {
478 if (type == bgp_show_type_neighbor)
479 {
480 union sockunion *su = output_arg;
481
482 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
483 continue;
484 }
485 if (header)
486 {
487 if (tags)
488 vty_out (vty, v4_header_tag, VTY_NEWLINE);
489 else
490 {
491 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
492 inet_ntoa (bgp->router_id), VTY_NEWLINE);
493 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
494 VTY_NEWLINE);
495 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
496 VTY_NEWLINE, VTY_NEWLINE);
497 vty_out (vty, v4_header, VTY_NEWLINE);
498 }
499 header = 0;
500 }
501
502 if (rd_header)
503 {
504 u_int16_t type;
505 struct rd_as rd_as;
506 struct rd_ip rd_ip;
507 u_char *pnt;
508
509 pnt = rn->p.u.val;
510
511 /* Decode RD type. */
512 type = decode_rd_type (pnt);
513 /* Decode RD value. */
514 if (type == RD_TYPE_AS)
515 decode_rd_as (pnt + 2, &rd_as);
516 else if (type == RD_TYPE_IP)
517 decode_rd_ip (pnt + 2, &rd_ip);
518
519 vty_out (vty, "Route Distinguisher: ");
520
521 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400522 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000523 else if (type == RD_TYPE_IP)
524 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
525
526 vty_out (vty, "%s", VTY_NEWLINE);
527 rd_header = 0;
528 }
529 if (tags)
530 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
531 else
532 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
533 }
534 }
535 }
536 return CMD_SUCCESS;
537}
538
539DEFUN (show_ip_bgp_vpnv4_all,
540 show_ip_bgp_vpnv4_all_cmd,
541 "show ip bgp vpnv4 all",
542 SHOW_STR
543 IP_STR
544 BGP_STR
545 "Display VPNv4 NLRI specific information\n"
546 "Display information about all VPNv4 NLRIs\n")
547{
548 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
549}
550
551DEFUN (show_ip_bgp_vpnv4_rd,
552 show_ip_bgp_vpnv4_rd_cmd,
553 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
554 SHOW_STR
555 IP_STR
556 BGP_STR
557 "Display VPNv4 NLRI specific information\n"
558 "Display information for a route distinguisher\n"
559 "VPN Route Distinguisher\n")
560{
561 int ret;
562 struct prefix_rd prd;
563
564 ret = str2prefix_rd (argv[0], &prd);
565 if (! ret)
566 {
567 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
568 return CMD_WARNING;
569 }
570 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
571}
572
573DEFUN (show_ip_bgp_vpnv4_all_tags,
574 show_ip_bgp_vpnv4_all_tags_cmd,
575 "show ip bgp vpnv4 all tags",
576 SHOW_STR
577 IP_STR
578 BGP_STR
579 "Display VPNv4 NLRI specific information\n"
580 "Display information about all VPNv4 NLRIs\n"
581 "Display BGP tags for prefixes\n")
582{
583 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
584}
585
586DEFUN (show_ip_bgp_vpnv4_rd_tags,
587 show_ip_bgp_vpnv4_rd_tags_cmd,
588 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
589 SHOW_STR
590 IP_STR
591 BGP_STR
592 "Display VPNv4 NLRI specific information\n"
593 "Display information for a route distinguisher\n"
594 "VPN Route Distinguisher\n"
595 "Display BGP tags for prefixes\n")
596{
597 int ret;
598 struct prefix_rd prd;
599
600 ret = str2prefix_rd (argv[0], &prd);
601 if (! ret)
602 {
603 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
604 return CMD_WARNING;
605 }
606 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
607}
608
609DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
610 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
611 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
612 SHOW_STR
613 IP_STR
614 BGP_STR
615 "Display VPNv4 NLRI specific information\n"
616 "Display information about all VPNv4 NLRIs\n"
617 "Detailed information on TCP and BGP neighbor connections\n"
618 "Neighbor to display information about\n"
619 "Display routes learned from neighbor\n")
620{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200621 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000622 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200623 int ret;
624
625 ret = str2sockunion (argv[0], &su);
626 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000627 {
628 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200629 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000630 }
631
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200632 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000633 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
634 {
635 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
636 return CMD_WARNING;
637 }
638
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200639 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000640}
641
642DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
643 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
644 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
645 SHOW_STR
646 IP_STR
647 BGP_STR
648 "Display VPNv4 NLRI specific information\n"
649 "Display information for a route distinguisher\n"
650 "VPN Route Distinguisher\n"
651 "Detailed information on TCP and BGP neighbor connections\n"
652 "Neighbor to display information about\n"
653 "Display routes learned from neighbor\n")
654{
655 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200656 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000657 struct peer *peer;
658 struct prefix_rd prd;
659
660 ret = str2prefix_rd (argv[0], &prd);
661 if (! ret)
662 {
663 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
664 return CMD_WARNING;
665 }
666
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200667 ret = str2sockunion (argv[1], &su);
668 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000669 {
670 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200671 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000672 }
673
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200674 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000675 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
676 {
677 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
678 return CMD_WARNING;
679 }
680
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200681 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000682}
683
684DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
685 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
686 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
687 SHOW_STR
688 IP_STR
689 BGP_STR
690 "Display VPNv4 NLRI specific information\n"
691 "Display information about all VPNv4 NLRIs\n"
692 "Detailed information on TCP and BGP neighbor connections\n"
693 "Neighbor to display information about\n"
694 "Display the routes advertised to a BGP neighbor\n")
695{
696 int ret;
697 struct peer *peer;
698 union sockunion su;
699
700 ret = str2sockunion (argv[0], &su);
701 if (ret < 0)
702 {
703 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
704 return CMD_WARNING;
705 }
706 peer = peer_lookup (NULL, &su);
707 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
708 {
709 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
710 return CMD_WARNING;
711 }
712
713 return show_adj_route_vpn (vty, peer, NULL);
714}
715
716DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
717 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
718 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
719 SHOW_STR
720 IP_STR
721 BGP_STR
722 "Display VPNv4 NLRI specific information\n"
723 "Display information for a route distinguisher\n"
724 "VPN Route Distinguisher\n"
725 "Detailed information on TCP and BGP neighbor connections\n"
726 "Neighbor to display information about\n"
727 "Display the routes advertised to a BGP neighbor\n")
728{
729 int ret;
730 struct peer *peer;
731 struct prefix_rd prd;
732 union sockunion su;
733
734 ret = str2sockunion (argv[1], &su);
735 if (ret < 0)
736 {
737 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
738 return CMD_WARNING;
739 }
740 peer = peer_lookup (NULL, &su);
741 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
742 {
743 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
744 return CMD_WARNING;
745 }
746
747 ret = str2prefix_rd (argv[0], &prd);
748 if (! ret)
749 {
750 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
751 return CMD_WARNING;
752 }
753
754 return show_adj_route_vpn (vty, peer, &prd);
755}
756
757void
paul94f2b392005-06-28 12:44:16 +0000758bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000759{
760 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
Lou Bergera76d9ca2016-01-12 13:41:53 -0500761 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
paul718e3742002-12-13 20:15:29 +0000762 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
763
764
765 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
766 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
767 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
768 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
769 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
770 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
771 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
772 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
773
774 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
775 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
776 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
777 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
778 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
779 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
780 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
781 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
782}