blob: bbc739bba774e6c1040edc7806ff936e0d30b17d [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
Lou Bergera03bd162016-01-12 13:41:54 -050057/* type == RD_TYPE_AS */
paul94f2b392005-06-28 12:44:16 +000058static void
paul718e3742002-12-13 20:15:29 +000059decode_rd_as (u_char *pnt, struct rd_as *rd_as)
60{
61 rd_as->as = (u_int16_t) *pnt++ << 8;
62 rd_as->as |= (u_int16_t) *pnt++;
63
64 rd_as->val = ((u_int32_t) *pnt++ << 24);
65 rd_as->val |= ((u_int32_t) *pnt++ << 16);
66 rd_as->val |= ((u_int32_t) *pnt++ << 8);
67 rd_as->val |= (u_int32_t) *pnt;
68}
69
Lou Bergera03bd162016-01-12 13:41:54 -050070/* type == RD_TYPE_AS4 */
71static void
72decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
73{
74 rd_as->as = (u_int32_t) *pnt++ << 24;
75 rd_as->as |= (u_int32_t) *pnt++ << 16;
76 rd_as->as |= (u_int32_t) *pnt++ << 8;
77 rd_as->as |= (u_int32_t) *pnt++;
78
79 rd_as->val = ((u_int16_t) *pnt++ << 8);
80 rd_as->val |= (u_int16_t) *pnt;
81}
82
83/* type == RD_TYPE_IP */
paul94f2b392005-06-28 12:44:16 +000084static void
paul718e3742002-12-13 20:15:29 +000085decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
86{
87 memcpy (&rd_ip->ip, pnt, 4);
88 pnt += 4;
89
90 rd_ip->val = ((u_int16_t) *pnt++ << 8);
91 rd_ip->val |= (u_int16_t) *pnt;
92}
93
paul718e3742002-12-13 20:15:29 +000094int
95bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
96 struct bgp_nlri *packet)
97{
98 u_char *pnt;
99 u_char *lim;
100 struct prefix p;
101 int psize;
102 int prefixlen;
paul718e3742002-12-13 20:15:29 +0000103 u_int16_t type;
104 struct rd_as rd_as;
105 struct rd_ip rd_ip;
106 struct prefix_rd prd;
107 u_char *tagpnt;
108
109 /* Check peer status. */
110 if (peer->status != Established)
111 return 0;
112
113 /* Make prefix_rd */
114 prd.family = AF_UNSPEC;
115 prd.prefixlen = 64;
116
117 pnt = packet->nlri;
118 lim = pnt + packet->length;
119
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000120#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
paul718e3742002-12-13 20:15:29 +0000121 for (; pnt < lim; pnt += psize)
122 {
123 /* Clear prefix structure. */
124 memset (&p, 0, sizeof (struct prefix));
125
126 /* Fetch prefix length. */
127 prefixlen = *pnt++;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000128 p.family = afi2family (packet->afi);
paul718e3742002-12-13 20:15:29 +0000129 psize = PSIZE (prefixlen);
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000130
131 /* sanity check against packet data */
132 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8 || (pnt + psize) > lim)
133 {
134 zlog_err ("prefix length (%d) is less than 88"
135 " or larger than received (%u)",
136 prefixlen, (uint)(lim-pnt));
137 return -1;
138 }
139
140 /* sanity check against storage for the IP address portion */
141 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
142 {
143 zlog_err ("prefix length (%d) exceeds prefix storage (%zu)",
144 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
145 return -1;
146 }
147
148 /* Sanity check against max bitlen of the address family */
149 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
150 {
151 zlog_err ("prefix length (%d) exceeds family (%u) max byte length (%u)",
152 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
153 p.family, prefix_blen (&p));
154 return -1;
155
156 }
157
paul718e3742002-12-13 20:15:29 +0000158 /* Copyr label to prefix. */
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000159 tagpnt = pnt;
paul718e3742002-12-13 20:15:29 +0000160
161 /* Copy routing distinguisher to rd. */
162 memcpy (&prd.val, pnt + 3, 8);
163
164 /* Decode RD type. */
165 type = decode_rd_type (pnt + 3);
166
Lou Bergera03bd162016-01-12 13:41:54 -0500167 switch (type)
168 {
169 case RD_TYPE_AS:
170 decode_rd_as (pnt + 5, &rd_as);
171 break;
172
173 case RD_TYPE_AS4:
174 decode_rd_as4 (pnt + 5, &rd_as);
175 break;
176
177 case RD_TYPE_IP:
178 decode_rd_ip (pnt + 5, &rd_ip);
179 break;
180
181 case RD_TYPE_EOI:
182 break;
183
184 default:
185 zlog_err ("Invalid RD type %d", type);
186 return -1;
187 }
paul718e3742002-12-13 20:15:29 +0000188
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000189 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;
190 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
191 psize - VPN_PREFIXLEN_MIN_BYTES);
paul718e3742002-12-13 20:15:29 +0000192
paul718e3742002-12-13 20:15:29 +0000193 if (attr)
194 bgp_update (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
paul94f2b392005-06-28 12:44:16 +0000195 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000196 else
197 bgp_withdraw (peer, &p, attr, AFI_IP, SAFI_MPLS_VPN,
198 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
199 }
paul718e3742002-12-13 20:15:29 +0000200 /* Packet length consistency check. */
201 if (pnt != lim)
202 return -1;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000203
paul718e3742002-12-13 20:15:29 +0000204 return 0;
Donald Sharpa3bc7e92016-01-27 16:54:45 +0000205#undef VPN_PREFIXLEN_MIN_BYTES
paul718e3742002-12-13 20:15:29 +0000206}
207
208int
paulfd79ac92004-10-13 05:06:08 +0000209str2prefix_rd (const char *str, struct prefix_rd *prd)
paul718e3742002-12-13 20:15:29 +0000210{
Lou Berger056f3762013-04-10 12:30:04 -0700211 int ret; /* ret of called functions */
212 int lret; /* local ret, of this func */
paul5228ad22004-06-04 17:58:18 +0000213 char *p;
214 char *p2;
Lou Berger056f3762013-04-10 12:30:04 -0700215 struct stream *s = NULL;
216 char *half = NULL;
paul718e3742002-12-13 20:15:29 +0000217 struct in_addr addr;
218
219 s = stream_new (8);
220
221 prd->family = AF_UNSPEC;
222 prd->prefixlen = 64;
223
Lou Berger056f3762013-04-10 12:30:04 -0700224 lret = 0;
paul718e3742002-12-13 20:15:29 +0000225 p = strchr (str, ':');
226 if (! p)
Lou Berger056f3762013-04-10 12:30:04 -0700227 goto out;
paul718e3742002-12-13 20:15:29 +0000228
229 if (! all_digit (p + 1))
Lou Berger056f3762013-04-10 12:30:04 -0700230 goto out;
paul718e3742002-12-13 20:15:29 +0000231
232 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
233 memcpy (half, str, (p - str));
234 half[p - str] = '\0';
235
236 p2 = strchr (str, '.');
237
238 if (! p2)
239 {
240 if (! all_digit (half))
Lou Berger056f3762013-04-10 12:30:04 -0700241 goto out;
242
paul718e3742002-12-13 20:15:29 +0000243 stream_putw (s, RD_TYPE_AS);
244 stream_putw (s, atoi (half));
245 stream_putl (s, atol (p + 1));
246 }
247 else
248 {
249 ret = inet_aton (half, &addr);
250 if (! ret)
Lou Berger056f3762013-04-10 12:30:04 -0700251 goto out;
252
paul718e3742002-12-13 20:15:29 +0000253 stream_putw (s, RD_TYPE_IP);
254 stream_put_in_addr (s, &addr);
255 stream_putw (s, atol (p + 1));
256 }
257 memcpy (prd->val, s->data, 8);
Lou Berger056f3762013-04-10 12:30:04 -0700258 lret = 1;
paul718e3742002-12-13 20:15:29 +0000259
Lou Berger056f3762013-04-10 12:30:04 -0700260out:
261 if (s)
262 stream_free (s);
263 if (half)
264 XFREE(MTYPE_TMP, half);
265 return lret;
paul718e3742002-12-13 20:15:29 +0000266}
267
268int
paulfd79ac92004-10-13 05:06:08 +0000269str2tag (const char *str, u_char *tag)
paul718e3742002-12-13 20:15:29 +0000270{
paulfd79ac92004-10-13 05:06:08 +0000271 unsigned long l;
272 char *endptr;
273 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000274
Ulrich Weber664711c2011-12-21 02:24:11 +0400275 if (*str == '-')
276 return 0;
paulfd79ac92004-10-13 05:06:08 +0000277
Ulrich Weber664711c2011-12-21 02:24:11 +0400278 errno = 0;
279 l = strtoul (str, &endptr, 10);
280
281 if (*endptr != '\0' || errno || l > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +0000282 return 0;
paul718e3742002-12-13 20:15:29 +0000283
paulfd79ac92004-10-13 05:06:08 +0000284 t = (u_int32_t) l;
285
286 tag[0] = (u_char)(t >> 12);
287 tag[1] = (u_char)(t >> 4);
288 tag[2] = (u_char)(t << 4);
paul718e3742002-12-13 20:15:29 +0000289
290 return 1;
291}
292
293char *
294prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
295{
296 u_char *pnt;
297 u_int16_t type;
298 struct rd_as rd_as;
299 struct rd_ip rd_ip;
300
301 if (size < RD_ADDRSTRLEN)
302 return NULL;
303
304 pnt = prd->val;
305
306 type = decode_rd_type (pnt);
307
308 if (type == RD_TYPE_AS)
309 {
310 decode_rd_as (pnt + 2, &rd_as);
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400311 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000312 return buf;
313 }
Lou Bergera03bd162016-01-12 13:41:54 -0500314 else if (type == RD_TYPE_AS4)
315 {
316 decode_rd_as4 (pnt + 2, &rd_as);
317 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
318 return buf;
319 }
paul718e3742002-12-13 20:15:29 +0000320 else if (type == RD_TYPE_IP)
321 {
322 decode_rd_ip (pnt + 2, &rd_ip);
323 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
324 return buf;
325 }
Lou Bergera03bd162016-01-12 13:41:54 -0500326 else if (type == RD_TYPE_EOI)
327 {
328 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
329 pnt[1], /* LHI */
330 pnt[2], pnt[3], pnt[4], pnt[5], pnt[6], pnt[7]); /* MAC */
331 return buf;
332 }
paul718e3742002-12-13 20:15:29 +0000333
334 return NULL;
335}
336
337/* For testing purpose, static route of MPLS-VPN. */
338DEFUN (vpnv4_network,
339 vpnv4_network_cmd,
340 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
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_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
349}
350
351DEFUN (vpnv4_network_route_map,
352 vpnv4_network_route_map_cmd,
353 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
354 "Specify a network to announce via BGP\n"
355 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
356 "Specify Route Distinguisher\n"
357 "VPN Route Distinguisher\n"
358 "BGP tag\n"
359 "tag value\n"
360 "route map\n"
361 "route map name\n")
362{
363 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
paul718e3742002-12-13 20:15:29 +0000364}
365
366/* For testing purpose, static route of MPLS-VPN. */
367DEFUN (no_vpnv4_network,
368 no_vpnv4_network_cmd,
369 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
370 NO_STR
371 "Specify a network to announce via BGP\n"
372 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
373 "Specify Route Distinguisher\n"
374 "VPN Route Distinguisher\n"
375 "BGP tag\n"
376 "tag value\n")
377{
Lou Bergera76d9ca2016-01-12 13:41:53 -0500378 return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
paul718e3742002-12-13 20:15:29 +0000379}
380
paul94f2b392005-06-28 12:44:16 +0000381static int
paul718e3742002-12-13 20:15:29 +0000382show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
383{
384 struct bgp *bgp;
385 struct bgp_table *table;
386 struct bgp_node *rn;
387 struct bgp_node *rm;
388 struct attr *attr;
389 int rd_header;
390 int header = 1;
391 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
392
393 bgp = bgp_get_default ();
394 if (bgp == NULL)
395 {
396 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
397 return CMD_WARNING;
398 }
399
400 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
401 rn = bgp_route_next (rn))
402 {
403 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
404 continue;
405
406 if ((table = rn->info) != NULL)
407 {
408 rd_header = 1;
409
410 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
411 if ((attr = rm->info) != NULL)
412 {
413 if (header)
414 {
415 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
416 inet_ntoa (bgp->router_id), VTY_NEWLINE);
417 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
418 VTY_NEWLINE);
419 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
420 VTY_NEWLINE, VTY_NEWLINE);
421 vty_out (vty, v4_header, VTY_NEWLINE);
422 header = 0;
423 }
424
425 if (rd_header)
426 {
427 u_int16_t type;
428 struct rd_as rd_as;
429 struct rd_ip rd_ip;
430 u_char *pnt;
431
432 pnt = rn->p.u.val;
433
434 /* Decode RD type. */
435 type = decode_rd_type (pnt);
436 /* Decode RD value. */
437 if (type == RD_TYPE_AS)
438 decode_rd_as (pnt + 2, &rd_as);
Lou Bergera03bd162016-01-12 13:41:54 -0500439 else if (type == RD_TYPE_AS4)
440 decode_rd_as4 (pnt + 2, &rd_as);
paul718e3742002-12-13 20:15:29 +0000441 else if (type == RD_TYPE_IP)
442 decode_rd_ip (pnt + 2, &rd_ip);
443
444 vty_out (vty, "Route Distinguisher: ");
445
446 if (type == RD_TYPE_AS)
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400447 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
Lou Bergera03bd162016-01-12 13:41:54 -0500448 else if (type == RD_TYPE_AS4)
449 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000450 else if (type == RD_TYPE_IP)
451 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
452
453 vty_out (vty, "%s", VTY_NEWLINE);
454 rd_header = 0;
455 }
456 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
457 }
458 }
459 }
460 return CMD_SUCCESS;
461}
462
463enum bgp_show_type
464{
465 bgp_show_type_normal,
466 bgp_show_type_regexp,
467 bgp_show_type_prefix_list,
468 bgp_show_type_filter_list,
469 bgp_show_type_neighbor,
470 bgp_show_type_cidr_only,
471 bgp_show_type_prefix_longer,
472 bgp_show_type_community_all,
473 bgp_show_type_community,
474 bgp_show_type_community_exact,
475 bgp_show_type_community_list,
476 bgp_show_type_community_list_exact
477};
478
paul94f2b392005-06-28 12:44:16 +0000479static int
paul718e3742002-12-13 20:15:29 +0000480bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
481 void *output_arg, int tags)
482{
483 struct bgp *bgp;
484 struct bgp_table *table;
485 struct bgp_node *rn;
486 struct bgp_node *rm;
487 struct bgp_info *ri;
488 int rd_header;
489 int header = 1;
490 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
491 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
492
493 bgp = bgp_get_default ();
494 if (bgp == NULL)
495 {
496 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
497 return CMD_WARNING;
498 }
499
500 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
501 {
502 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
503 continue;
504
505 if ((table = rn->info) != NULL)
506 {
507 rd_header = 1;
508
509 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
510 for (ri = rm->info; ri; ri = ri->next)
511 {
512 if (type == bgp_show_type_neighbor)
513 {
514 union sockunion *su = output_arg;
515
516 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
517 continue;
518 }
519 if (header)
520 {
521 if (tags)
522 vty_out (vty, v4_header_tag, VTY_NEWLINE);
523 else
524 {
525 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
526 inet_ntoa (bgp->router_id), VTY_NEWLINE);
527 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
528 VTY_NEWLINE);
529 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
530 VTY_NEWLINE, VTY_NEWLINE);
531 vty_out (vty, v4_header, VTY_NEWLINE);
532 }
533 header = 0;
534 }
535
536 if (rd_header)
537 {
538 u_int16_t type;
539 struct rd_as rd_as;
540 struct rd_ip rd_ip;
541 u_char *pnt;
542
543 pnt = rn->p.u.val;
544
545 /* Decode RD type. */
546 type = decode_rd_type (pnt);
547 /* Decode RD value. */
548 if (type == RD_TYPE_AS)
549 decode_rd_as (pnt + 2, &rd_as);
Lou Bergera03bd162016-01-12 13:41:54 -0500550 else if (type == RD_TYPE_AS4)
551 decode_rd_as4 (pnt + 2, &rd_as);
paul718e3742002-12-13 20:15:29 +0000552 else if (type == RD_TYPE_IP)
553 decode_rd_ip (pnt + 2, &rd_ip);
554
555 vty_out (vty, "Route Distinguisher: ");
556
557 if (type == RD_TYPE_AS)
Lou Bergera03bd162016-01-12 13:41:54 -0500558 vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
559 else if (type == RD_TYPE_AS4)
560 vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000561 else if (type == RD_TYPE_IP)
Lou Bergera03bd162016-01-12 13:41:54 -0500562 vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
paul718e3742002-12-13 20:15:29 +0000563
564 vty_out (vty, "%s", VTY_NEWLINE);
565 rd_header = 0;
566 }
567 if (tags)
568 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
569 else
570 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
571 }
572 }
573 }
574 return CMD_SUCCESS;
575}
576
577DEFUN (show_ip_bgp_vpnv4_all,
578 show_ip_bgp_vpnv4_all_cmd,
579 "show ip bgp vpnv4 all",
580 SHOW_STR
581 IP_STR
582 BGP_STR
583 "Display VPNv4 NLRI specific information\n"
584 "Display information about all VPNv4 NLRIs\n")
585{
586 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
587}
588
589DEFUN (show_ip_bgp_vpnv4_rd,
590 show_ip_bgp_vpnv4_rd_cmd,
591 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
592 SHOW_STR
593 IP_STR
594 BGP_STR
595 "Display VPNv4 NLRI specific information\n"
596 "Display information for a route distinguisher\n"
597 "VPN Route Distinguisher\n")
598{
599 int ret;
600 struct prefix_rd prd;
601
602 ret = str2prefix_rd (argv[0], &prd);
603 if (! ret)
604 {
605 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
606 return CMD_WARNING;
607 }
608 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
609}
610
611DEFUN (show_ip_bgp_vpnv4_all_tags,
612 show_ip_bgp_vpnv4_all_tags_cmd,
613 "show ip bgp vpnv4 all tags",
614 SHOW_STR
615 IP_STR
616 BGP_STR
617 "Display VPNv4 NLRI specific information\n"
618 "Display information about all VPNv4 NLRIs\n"
619 "Display BGP tags for prefixes\n")
620{
621 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
622}
623
624DEFUN (show_ip_bgp_vpnv4_rd_tags,
625 show_ip_bgp_vpnv4_rd_tags_cmd,
626 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
627 SHOW_STR
628 IP_STR
629 BGP_STR
630 "Display VPNv4 NLRI specific information\n"
631 "Display information for a route distinguisher\n"
632 "VPN Route Distinguisher\n"
633 "Display BGP tags for prefixes\n")
634{
635 int ret;
636 struct prefix_rd prd;
637
638 ret = str2prefix_rd (argv[0], &prd);
639 if (! ret)
640 {
641 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
642 return CMD_WARNING;
643 }
644 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
645}
646
647DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
648 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
649 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
650 SHOW_STR
651 IP_STR
652 BGP_STR
653 "Display VPNv4 NLRI specific information\n"
654 "Display information about all VPNv4 NLRIs\n"
655 "Detailed information on TCP and BGP neighbor connections\n"
656 "Neighbor to display information about\n"
657 "Display routes learned from neighbor\n")
658{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200659 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000660 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200661 int ret;
662
663 ret = str2sockunion (argv[0], &su);
664 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000665 {
666 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200667 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000668 }
669
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200670 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000671 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
672 {
673 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
674 return CMD_WARNING;
675 }
676
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200677 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000678}
679
680DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
681 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
682 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
683 SHOW_STR
684 IP_STR
685 BGP_STR
686 "Display VPNv4 NLRI specific information\n"
687 "Display information for a route distinguisher\n"
688 "VPN Route Distinguisher\n"
689 "Detailed information on TCP and BGP neighbor connections\n"
690 "Neighbor to display information about\n"
691 "Display routes learned from neighbor\n")
692{
693 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200694 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000695 struct peer *peer;
696 struct prefix_rd prd;
697
698 ret = str2prefix_rd (argv[0], &prd);
699 if (! ret)
700 {
701 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
702 return CMD_WARNING;
703 }
704
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200705 ret = str2sockunion (argv[1], &su);
706 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000707 {
708 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200709 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000710 }
711
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200712 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000713 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
714 {
715 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
716 return CMD_WARNING;
717 }
718
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200719 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000720}
721
722DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
723 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
724 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
725 SHOW_STR
726 IP_STR
727 BGP_STR
728 "Display VPNv4 NLRI specific information\n"
729 "Display information about all VPNv4 NLRIs\n"
730 "Detailed information on TCP and BGP neighbor connections\n"
731 "Neighbor to display information about\n"
732 "Display the routes advertised to a BGP neighbor\n")
733{
734 int ret;
735 struct peer *peer;
736 union sockunion su;
737
738 ret = str2sockunion (argv[0], &su);
739 if (ret < 0)
740 {
741 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
742 return CMD_WARNING;
743 }
744 peer = peer_lookup (NULL, &su);
745 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
746 {
747 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
748 return CMD_WARNING;
749 }
750
751 return show_adj_route_vpn (vty, peer, NULL);
752}
753
754DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
755 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
756 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
757 SHOW_STR
758 IP_STR
759 BGP_STR
760 "Display VPNv4 NLRI specific information\n"
761 "Display information for a route distinguisher\n"
762 "VPN Route Distinguisher\n"
763 "Detailed information on TCP and BGP neighbor connections\n"
764 "Neighbor to display information about\n"
765 "Display the routes advertised to a BGP neighbor\n")
766{
767 int ret;
768 struct peer *peer;
769 struct prefix_rd prd;
770 union sockunion su;
771
772 ret = str2sockunion (argv[1], &su);
773 if (ret < 0)
774 {
775 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
776 return CMD_WARNING;
777 }
778 peer = peer_lookup (NULL, &su);
779 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
780 {
781 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
782 return CMD_WARNING;
783 }
784
785 ret = str2prefix_rd (argv[0], &prd);
786 if (! ret)
787 {
788 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
789 return CMD_WARNING;
790 }
791
792 return show_adj_route_vpn (vty, peer, &prd);
793}
794
795void
paul94f2b392005-06-28 12:44:16 +0000796bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000797{
798 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
Lou Bergera76d9ca2016-01-12 13:41:53 -0500799 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
paul718e3742002-12-13 20:15:29 +0000800 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
801
802
803 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
804 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
805 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
806 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
807 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
808 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
809 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
810 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
811
812 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
813 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
814 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
815 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
816 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
817 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
818 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
819 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
820}