blob: 78a71e70cc362b8da10be7e347d7e6dba59ed6f3 [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
Lou Berger9da04bc2016-01-12 13:41:55 -050095bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
96 struct bgp_nlri *packet)
paul718e3742002-12-13 20:15:29 +000097{
98 u_char *pnt;
99 u_char *lim;
100 struct prefix p;
Lou Berger9da04bc2016-01-12 13:41:55 -0500101 int psize = 0;
paul718e3742002-12-13 20:15:29 +0000102 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)
Lou Berger9da04bc2016-01-12 13:41:55 -0500194 bgp_update (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
195 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
paul718e3742002-12-13 20:15:29 +0000196 else
Lou Berger9da04bc2016-01-12 13:41:55 -0500197 bgp_withdraw (peer, &p, attr, packet->afi, SAFI_MPLS_VPN,
198 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
paul718e3742002-12-13 20:15:29 +0000199 }
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{
Lou Berger9da04bc2016-01-12 13:41:55 -0500483 afi_t afi = AFI_IP;
paul718e3742002-12-13 20:15:29 +0000484 struct bgp *bgp;
485 struct bgp_table *table;
486 struct bgp_node *rn;
487 struct bgp_node *rm;
488 struct bgp_info *ri;
489 int rd_header;
490 int header = 1;
491 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
492 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
493
494 bgp = bgp_get_default ();
495 if (bgp == NULL)
496 {
497 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
498 return CMD_WARNING;
499 }
500
Lou Berger9da04bc2016-01-12 13:41:55 -0500501 if ((afi != AFI_IP) && (afi != AFI_IP6))
502 {
503 vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
504 return CMD_WARNING;
505 }
506
507 for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
paul718e3742002-12-13 20:15:29 +0000508 {
509 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
510 continue;
511
512 if ((table = rn->info) != NULL)
513 {
514 rd_header = 1;
515
516 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
517 for (ri = rm->info; ri; ri = ri->next)
518 {
519 if (type == bgp_show_type_neighbor)
520 {
521 union sockunion *su = output_arg;
522
523 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
524 continue;
525 }
526 if (header)
527 {
528 if (tags)
529 vty_out (vty, v4_header_tag, VTY_NEWLINE);
530 else
531 {
532 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
533 inet_ntoa (bgp->router_id), VTY_NEWLINE);
534 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
535 VTY_NEWLINE);
536 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
537 VTY_NEWLINE, VTY_NEWLINE);
538 vty_out (vty, v4_header, VTY_NEWLINE);
539 }
540 header = 0;
541 }
542
543 if (rd_header)
544 {
545 u_int16_t type;
546 struct rd_as rd_as;
547 struct rd_ip rd_ip;
548 u_char *pnt;
549
550 pnt = rn->p.u.val;
551
552 /* Decode RD type. */
553 type = decode_rd_type (pnt);
554 /* Decode RD value. */
555 if (type == RD_TYPE_AS)
556 decode_rd_as (pnt + 2, &rd_as);
Lou Bergera03bd162016-01-12 13:41:54 -0500557 else if (type == RD_TYPE_AS4)
558 decode_rd_as4 (pnt + 2, &rd_as);
paul718e3742002-12-13 20:15:29 +0000559 else if (type == RD_TYPE_IP)
560 decode_rd_ip (pnt + 2, &rd_ip);
561
562 vty_out (vty, "Route Distinguisher: ");
563
564 if (type == RD_TYPE_AS)
Lou Bergera03bd162016-01-12 13:41:54 -0500565 vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
566 else if (type == RD_TYPE_AS4)
567 vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
paul718e3742002-12-13 20:15:29 +0000568 else if (type == RD_TYPE_IP)
Lou Bergera03bd162016-01-12 13:41:54 -0500569 vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
paul718e3742002-12-13 20:15:29 +0000570
571 vty_out (vty, "%s", VTY_NEWLINE);
572 rd_header = 0;
573 }
574 if (tags)
575 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
576 else
577 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN);
578 }
579 }
580 }
581 return CMD_SUCCESS;
582}
583
584DEFUN (show_ip_bgp_vpnv4_all,
585 show_ip_bgp_vpnv4_all_cmd,
586 "show ip bgp vpnv4 all",
587 SHOW_STR
588 IP_STR
589 BGP_STR
590 "Display VPNv4 NLRI specific information\n"
591 "Display information about all VPNv4 NLRIs\n")
592{
593 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0);
594}
595
596DEFUN (show_ip_bgp_vpnv4_rd,
597 show_ip_bgp_vpnv4_rd_cmd,
598 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
599 SHOW_STR
600 IP_STR
601 BGP_STR
602 "Display VPNv4 NLRI specific information\n"
603 "Display information for a route distinguisher\n"
604 "VPN Route Distinguisher\n")
605{
606 int ret;
607 struct prefix_rd prd;
608
609 ret = str2prefix_rd (argv[0], &prd);
610 if (! ret)
611 {
612 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
613 return CMD_WARNING;
614 }
615 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0);
616}
617
618DEFUN (show_ip_bgp_vpnv4_all_tags,
619 show_ip_bgp_vpnv4_all_tags_cmd,
620 "show ip bgp vpnv4 all tags",
621 SHOW_STR
622 IP_STR
623 BGP_STR
624 "Display VPNv4 NLRI specific information\n"
625 "Display information about all VPNv4 NLRIs\n"
626 "Display BGP tags for prefixes\n")
627{
628 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1);
629}
630
631DEFUN (show_ip_bgp_vpnv4_rd_tags,
632 show_ip_bgp_vpnv4_rd_tags_cmd,
633 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
634 SHOW_STR
635 IP_STR
636 BGP_STR
637 "Display VPNv4 NLRI specific information\n"
638 "Display information for a route distinguisher\n"
639 "VPN Route Distinguisher\n"
640 "Display BGP tags for prefixes\n")
641{
642 int ret;
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 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1);
652}
653
654DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
655 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
656 "show ip bgp vpnv4 all neighbors A.B.C.D routes",
657 SHOW_STR
658 IP_STR
659 BGP_STR
660 "Display VPNv4 NLRI specific information\n"
661 "Display information about all VPNv4 NLRIs\n"
662 "Detailed information on TCP and BGP neighbor connections\n"
663 "Neighbor to display information about\n"
664 "Display routes learned from neighbor\n")
665{
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200666 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000667 struct peer *peer;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200668 int ret;
669
670 ret = str2sockunion (argv[0], &su);
671 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000672 {
673 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200674 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000675 }
676
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200677 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000678 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
679 {
680 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
681 return CMD_WARNING;
682 }
683
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200684 return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000685}
686
687DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
688 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
689 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
690 SHOW_STR
691 IP_STR
692 BGP_STR
693 "Display VPNv4 NLRI specific information\n"
694 "Display information for a route distinguisher\n"
695 "VPN Route Distinguisher\n"
696 "Detailed information on TCP and BGP neighbor connections\n"
697 "Neighbor to display information about\n"
698 "Display routes learned from neighbor\n")
699{
700 int ret;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200701 union sockunion su;
paul718e3742002-12-13 20:15:29 +0000702 struct peer *peer;
703 struct prefix_rd prd;
704
705 ret = str2prefix_rd (argv[0], &prd);
706 if (! ret)
707 {
708 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
709 return CMD_WARNING;
710 }
711
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200712 ret = str2sockunion (argv[1], &su);
713 if (ret < 0)
paul718e3742002-12-13 20:15:29 +0000714 {
715 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200716 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +0000717 }
718
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200719 peer = peer_lookup (NULL, &su);
paul718e3742002-12-13 20:15:29 +0000720 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
721 {
722 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
723 return CMD_WARNING;
724 }
725
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200726 return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0);
paul718e3742002-12-13 20:15:29 +0000727}
728
729DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
730 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
731 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes",
732 SHOW_STR
733 IP_STR
734 BGP_STR
735 "Display VPNv4 NLRI specific information\n"
736 "Display information about all VPNv4 NLRIs\n"
737 "Detailed information on TCP and BGP neighbor connections\n"
738 "Neighbor to display information about\n"
739 "Display the routes advertised to a BGP neighbor\n")
740{
741 int ret;
742 struct peer *peer;
743 union sockunion su;
744
745 ret = str2sockunion (argv[0], &su);
746 if (ret < 0)
747 {
748 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
749 return CMD_WARNING;
750 }
751 peer = peer_lookup (NULL, &su);
752 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
753 {
754 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
755 return CMD_WARNING;
756 }
757
758 return show_adj_route_vpn (vty, peer, NULL);
759}
760
761DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
762 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
763 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
764 SHOW_STR
765 IP_STR
766 BGP_STR
767 "Display VPNv4 NLRI specific information\n"
768 "Display information for a route distinguisher\n"
769 "VPN Route Distinguisher\n"
770 "Detailed information on TCP and BGP neighbor connections\n"
771 "Neighbor to display information about\n"
772 "Display the routes advertised to a BGP neighbor\n")
773{
774 int ret;
775 struct peer *peer;
776 struct prefix_rd prd;
777 union sockunion su;
778
779 ret = str2sockunion (argv[1], &su);
780 if (ret < 0)
781 {
782 vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
783 return CMD_WARNING;
784 }
785 peer = peer_lookup (NULL, &su);
786 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
787 {
788 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
789 return CMD_WARNING;
790 }
791
792 ret = str2prefix_rd (argv[0], &prd);
793 if (! ret)
794 {
795 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
796 return CMD_WARNING;
797 }
798
799 return show_adj_route_vpn (vty, peer, &prd);
800}
801
802void
paul94f2b392005-06-28 12:44:16 +0000803bgp_mplsvpn_init (void)
paul718e3742002-12-13 20:15:29 +0000804{
805 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
Lou Bergera76d9ca2016-01-12 13:41:53 -0500806 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
paul718e3742002-12-13 20:15:29 +0000807 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
808
809
810 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
811 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
812 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
813 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
814 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
815 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
816 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
817 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
818
819 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_cmd);
820 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_cmd);
821 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
822 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
823 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
824 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
825 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
826 install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
827}