]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
bgpd: use loops to reduce code duplication
[mirror_frr.git] / bgpd / bgp_mplsvpn.c
CommitLineData
718e3744 1/* 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"
3f9c7369 28#include "queue.h"
039f3a34 29#include "filter.h"
718e3744 30
856ca177 31#include "lib/json.h"
718e3744 32#include "bgpd/bgpd.h"
33#include "bgpd/bgp_table.h"
34#include "bgpd/bgp_route.h"
35#include "bgpd/bgp_attr.h"
36#include "bgpd/bgp_mplsvpn.h"
48a5452b 37#include "bgpd/bgp_packet.h"
718e3744 38
65efcfce 39#if ENABLE_BGP_VNC
f8b6f499 40#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
41#endif
42
1a39c60a 43u_int16_t
718e3744 44decode_rd_type (u_char *pnt)
45{
46 u_int16_t v;
47
48 v = ((u_int16_t) *pnt++ << 8);
65efcfce
LB
49#if ENABLE_BGP_VNC
50 /*
51 * VNC L2 stores LHI in lower byte, so omit it
52 */
53 if (v != RD_TYPE_VNC_ETH)
54 v |= (u_int16_t) *pnt;
55#else /* duplicate code for clarity */
718e3744 56 v |= (u_int16_t) *pnt;
65efcfce
LB
57#endif
58
718e3744 59 return v;
60}
61
65efcfce
LB
62void
63encode_rd_type (u_int16_t v, u_char *pnt)
64{
65 *((u_int16_t *)pnt) = htons(v);
66}
67
718e3744 68u_int32_t
69decode_label (u_char *pnt)
70{
71 u_int32_t l;
72
73 l = ((u_int32_t) *pnt++ << 12);
74 l |= (u_int32_t) *pnt++ << 4;
75 l |= (u_int32_t) ((*pnt & 0xf0) >> 4);
76 return l;
77}
78
65efcfce
LB
79void
80encode_label(u_int32_t label,
81 u_char *pnt)
82{
83 if (pnt == NULL)
84 return;
85 *pnt++ = (label>>12) & 0xff;
86 *pnt++ = (label>>4) & 0xff;
87 *pnt++ = ((label<<4)+1) & 0xff; /* S=1 */
88}
89
fe770c88 90/* type == RD_TYPE_AS */
1a39c60a 91void
718e3744 92decode_rd_as (u_char *pnt, struct rd_as *rd_as)
93{
94 rd_as->as = (u_int16_t) *pnt++ << 8;
95 rd_as->as |= (u_int16_t) *pnt++;
96
97 rd_as->val = ((u_int32_t) *pnt++ << 24);
98 rd_as->val |= ((u_int32_t) *pnt++ << 16);
99 rd_as->val |= ((u_int32_t) *pnt++ << 8);
100 rd_as->val |= (u_int32_t) *pnt;
101}
102
fe770c88 103/* type == RD_TYPE_AS4 */
1a39c60a 104void
fe770c88
LB
105decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
106{
107 rd_as->as = (u_int32_t) *pnt++ << 24;
108 rd_as->as |= (u_int32_t) *pnt++ << 16;
109 rd_as->as |= (u_int32_t) *pnt++ << 8;
110 rd_as->as |= (u_int32_t) *pnt++;
111
112 rd_as->val = ((u_int16_t) *pnt++ << 8);
113 rd_as->val |= (u_int16_t) *pnt;
114}
115
116/* type == RD_TYPE_IP */
1a39c60a 117void
718e3744 118decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
119{
120 memcpy (&rd_ip->ip, pnt, 4);
121 pnt += 4;
122
123 rd_ip->val = ((u_int16_t) *pnt++ << 8);
124 rd_ip->val |= (u_int16_t) *pnt;
125}
126
65efcfce
LB
127#if ENABLE_BGP_VNC
128/* type == RD_TYPE_VNC_ETH */
2de1475f 129static void
65efcfce
LB
130decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
131{
132 rd_vnc_eth->type = RD_TYPE_VNC_ETH;
133 rd_vnc_eth->local_nve_id = pnt[1];
134 memcpy (rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
135}
136#endif
137
ebd12e62
PJ
138int
139bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
140 struct bgp_nlri *packet)
718e3744 141{
142 u_char *pnt;
143 u_char *lim;
144 struct prefix p;
945c8fe9 145 int psize = 0;
718e3744 146 int prefixlen;
718e3744 147 u_int16_t type;
148 struct rd_as rd_as;
149 struct rd_ip rd_ip;
150 struct prefix_rd prd;
151 u_char *tagpnt;
a82478b9
DS
152 afi_t afi;
153 safi_t safi;
adbac85e 154 int addpath_encoded;
a82478b9 155 u_int32_t addpath_id;
65efcfce
LB
156#if ENABLE_BGP_VNC
157 u_int32_t label = 0;
158#endif
718e3744 159
160 /* Check peer status. */
161 if (peer->status != Established)
162 return 0;
163
164 /* Make prefix_rd */
165 prd.family = AF_UNSPEC;
166 prd.prefixlen = 64;
167
168 pnt = packet->nlri;
169 lim = pnt + packet->length;
a82478b9
DS
170 afi = packet->afi;
171 safi = packet->safi;
172 addpath_id = 0;
173
174 addpath_encoded = (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
175 CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
718e3744 176
50905aa2 177#define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
718e3744 178 for (; pnt < lim; pnt += psize)
179 {
180 /* Clear prefix structure. */
181 memset (&p, 0, sizeof (struct prefix));
182
a82478b9
DS
183 if (addpath_encoded)
184 {
cd808e74
DS
185
186 /* When packet overflow occurs return immediately. */
187 if (pnt + BGP_ADDPATH_ID_LEN > lim)
188 return -1;
189
a82478b9
DS
190 addpath_id = ntohl(*((uint32_t*) pnt));
191 pnt += BGP_ADDPATH_ID_LEN;
192 }
193
e5528198
LB
194 /* Fetch prefix length. */
195 prefixlen = *pnt++;
196 p.family = afi2family (packet->afi);
197 psize = PSIZE (prefixlen);
198
48a5452b 199 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
1f9a9fff 200 {
48a5452b
PJ
201 zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d less than VPNv4 min length)",
202 peer->host, prefixlen);
1f9a9fff
PJ
203 return -1;
204 }
205
50905aa2 206 /* sanity check against packet data */
48a5452b 207 if ((pnt + psize) > lim)
50905aa2 208 {
48a5452b
PJ
209 zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d exceeds packet size %u)",
210 peer->host,
50905aa2
DS
211 prefixlen, (uint)(lim-pnt));
212 return -1;
213 }
214
215 /* sanity check against storage for the IP address portion */
216 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > (ssize_t) sizeof(p.u))
217 {
48a5452b
PJ
218 zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds storage size %zu)",
219 peer->host,
50905aa2
DS
220 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8, sizeof(p.u));
221 return -1;
222 }
223
224 /* Sanity check against max bitlen of the address family */
225 if ((psize - VPN_PREFIXLEN_MIN_BYTES) > prefix_blen (&p))
226 {
48a5452b
PJ
227 zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds family (%u) max byte len %u)",
228 peer->host,
50905aa2
DS
229 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
230 p.family, prefix_blen (&p));
231 return -1;
50905aa2
DS
232 }
233
65efcfce
LB
234#if ENABLE_BGP_VNC
235 label = decode_label (pnt);
236#endif
237
718e3744 238 /* Copyr label to prefix. */
50905aa2 239 tagpnt = pnt;
718e3744 240
241 /* Copy routing distinguisher to rd. */
242 memcpy (&prd.val, pnt + 3, 8);
243
244 /* Decode RD type. */
245 type = decode_rd_type (pnt + 3);
246
fe770c88
LB
247 switch (type)
248 {
249 case RD_TYPE_AS:
250 decode_rd_as (pnt + 5, &rd_as);
251 break;
252
253 case RD_TYPE_AS4:
254 decode_rd_as4 (pnt + 5, &rd_as);
255 break;
256
257 case RD_TYPE_IP:
258 decode_rd_ip (pnt + 5, &rd_ip);
259 break;
260
65efcfce
LB
261#if ENABLE_BGP_VNC
262 case RD_TYPE_VNC_ETH:
263 break;
264#endif
265
93b73dfa
LB
266 default:
267 zlog_err ("Unknown RD type %d", type);
268 break; /* just report */
269 }
718e3744 270
65efcfce 271 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;/* exclude label & RD */
50905aa2
DS
272 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
273 psize - VPN_PREFIXLEN_MIN_BYTES);
718e3744 274
ebd12e62 275 if (attr)
65efcfce 276 {
ebd12e62
PJ
277 bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
278 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
65efcfce 279#if ENABLE_BGP_VNC
ebd12e62
PJ
280 rfapiProcessUpdate(peer, NULL, &p, &prd, attr, packet->afi,
281 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
282 &label);
65efcfce 283#endif
ebd12e62
PJ
284 }
285 else
286 {
65efcfce 287#if ENABLE_BGP_VNC
ebd12e62
PJ
288 rfapiProcessWithdraw(peer, NULL, &p, &prd, attr, packet->afi,
289 SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, 0);
65efcfce 290#endif
ebd12e62
PJ
291 bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
292 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
65efcfce 293 }
718e3744 294 }
718e3744 295 /* Packet length consistency check. */
296 if (pnt != lim)
48a5452b
PJ
297 {
298 zlog_err ("%s [Error] Update packet error / VPNv4 (%zu data remaining after parsing)",
299 peer->host, lim - pnt);
48a5452b
PJ
300 return -1;
301 }
302
718e3744 303 return 0;
50905aa2 304#undef VPN_PREFIXLEN_MIN_BYTES
718e3744 305}
306
307int
fd79ac91 308str2prefix_rd (const char *str, struct prefix_rd *prd)
718e3744 309{
289d2501
LB
310 int ret; /* ret of called functions */
311 int lret; /* local ret, of this func */
5228ad27 312 char *p;
313 char *p2;
289d2501
LB
314 struct stream *s = NULL;
315 char *half = NULL;
718e3744 316 struct in_addr addr;
317
318 s = stream_new (8);
319
320 prd->family = AF_UNSPEC;
321 prd->prefixlen = 64;
322
289d2501 323 lret = 0;
718e3744 324 p = strchr (str, ':');
325 if (! p)
289d2501 326 goto out;
718e3744 327
328 if (! all_digit (p + 1))
289d2501 329 goto out;
718e3744 330
331 half = XMALLOC (MTYPE_TMP, (p - str) + 1);
332 memcpy (half, str, (p - str));
333 half[p - str] = '\0';
334
335 p2 = strchr (str, '.');
336
337 if (! p2)
338 {
339 if (! all_digit (half))
289d2501
LB
340 goto out;
341
718e3744 342 stream_putw (s, RD_TYPE_AS);
343 stream_putw (s, atoi (half));
344 stream_putl (s, atol (p + 1));
345 }
346 else
347 {
348 ret = inet_aton (half, &addr);
349 if (! ret)
289d2501
LB
350 goto out;
351
718e3744 352 stream_putw (s, RD_TYPE_IP);
353 stream_put_in_addr (s, &addr);
354 stream_putw (s, atol (p + 1));
355 }
356 memcpy (prd->val, s->data, 8);
289d2501
LB
357 lret = 1;
358
359out:
360 if (s)
361 stream_free (s);
362 if (half)
363 XFREE(MTYPE_TMP, half);
364 return lret;
718e3744 365}
366
367int
fd79ac91 368str2tag (const char *str, u_char *tag)
718e3744 369{
fd79ac91 370 unsigned long l;
371 char *endptr;
372 u_int32_t t;
718e3744 373
664711c1
UW
374 if (*str == '-')
375 return 0;
fd79ac91 376
664711c1
UW
377 errno = 0;
378 l = strtoul (str, &endptr, 10);
379
380 if (*endptr != '\0' || errno || l > UINT32_MAX)
fd79ac91 381 return 0;
718e3744 382
fd79ac91 383 t = (u_int32_t) l;
384
385 tag[0] = (u_char)(t >> 12);
386 tag[1] = (u_char)(t >> 4);
387 tag[2] = (u_char)(t << 4);
718e3744 388
389 return 1;
390}
391
392char *
393prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
394{
395 u_char *pnt;
396 u_int16_t type;
397 struct rd_as rd_as;
398 struct rd_ip rd_ip;
399
400 if (size < RD_ADDRSTRLEN)
401 return NULL;
402
403 pnt = prd->val;
404
405 type = decode_rd_type (pnt);
406
407 if (type == RD_TYPE_AS)
408 {
409 decode_rd_as (pnt + 2, &rd_as);
aea339f7 410 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
718e3744 411 return buf;
412 }
fe770c88
LB
413 else if (type == RD_TYPE_AS4)
414 {
415 decode_rd_as4 (pnt + 2, &rd_as);
416 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
417 return buf;
418 }
718e3744 419 else if (type == RD_TYPE_IP)
420 {
421 decode_rd_ip (pnt + 2, &rd_ip);
422 snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
423 return buf;
424 }
65efcfce
LB
425#if ENABLE_BGP_VNC
426 else if (type == RD_TYPE_VNC_ETH)
427 {
428 snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
429 *(pnt+1), /* LHI */
430 *(pnt+2), /* MAC[0] */
431 *(pnt+3),
432 *(pnt+4),
433 *(pnt+5),
434 *(pnt+6),
435 *(pnt+7));
436
437 return buf;
438 }
439#endif
718e3744 440 return NULL;
441}
442
443/* For testing purpose, static route of MPLS-VPN. */
444DEFUN (vpnv4_network,
445 vpnv4_network_cmd,
446 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
447 "Specify a network to announce via BGP\n"
448 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
449 "Specify Route Distinguisher\n"
450 "VPN Route Distinguisher\n"
451 "BGP tag\n"
452 "tag value\n")
453{
137446f9
LB
454 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
455}
456
457DEFUN (vpnv4_network_route_map,
458 vpnv4_network_route_map_cmd,
459 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
460 "Specify a network to announce via BGP\n"
461 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
462 "Specify Route Distinguisher\n"
463 "VPN Route Distinguisher\n"
464 "BGP tag\n"
465 "tag value\n"
466 "route map\n"
467 "route map name\n")
468{
469 return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
718e3744 470}
471
472/* For testing purpose, static route of MPLS-VPN. */
473DEFUN (no_vpnv4_network,
474 no_vpnv4_network_cmd,
475 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
476 NO_STR
477 "Specify a network to announce via BGP\n"
478 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
479 "Specify Route Distinguisher\n"
480 "VPN Route Distinguisher\n"
481 "BGP tag\n"
482 "tag value\n")
483{
137446f9 484 return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
718e3744 485}
486
94f2b392 487static int
856ca177 488show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u_char use_json)
718e3744 489{
490 struct bgp *bgp;
491 struct bgp_table *table;
492 struct bgp_node *rn;
493 struct bgp_node *rm;
494 struct attr *attr;
495 int rd_header;
496 int header = 1;
497 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
856ca177
MS
498 json_object *json = NULL;
499 json_object *json_scode = NULL;
500 json_object *json_ocode = NULL;
501 json_object *json_routes = NULL;
502 json_object *json_array = NULL;
718e3744 503
504 bgp = bgp_get_default ();
505 if (bgp == NULL)
506 {
856ca177
MS
507 if (!use_json)
508 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
718e3744 509 return CMD_WARNING;
510 }
511
856ca177
MS
512 if (use_json)
513 {
514 json_scode = json_object_new_object();
515 json_ocode = json_object_new_object();
516 json_routes = json_object_new_object();
517 json = json_object_new_object();
518
519 json_object_string_add(json_scode, "suppressed", "s");
520 json_object_string_add(json_scode, "damped", "d");
521 json_object_string_add(json_scode, "history", "h");
522 json_object_string_add(json_scode, "valid", "*");
523 json_object_string_add(json_scode, "best", ">");
524 json_object_string_add(json_scode, "internal", "i");
525
526 json_object_string_add(json_ocode, "igp", "i");
527 json_object_string_add(json_ocode, "egp", "e");
528 json_object_string_add(json_ocode, "incomplete", "?");
529 }
530
718e3744 531 for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
532 rn = bgp_route_next (rn))
533 {
534 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
535 continue;
536
537 if ((table = rn->info) != NULL)
538 {
856ca177
MS
539 if (use_json)
540 json_array = json_object_new_array();
541 else
542 json_array = NULL;
543
718e3744 544 rd_header = 1;
545
546 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
856ca177
MS
547 {
548 if ((attr = rm->info) != NULL)
549 {
550 if (header)
551 {
552 if (use_json)
553 {
554 json_object_int_add(json, "bgpTableVersion", 0);
555 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
556 json_object_object_add(json, "bgpStatusCodes", json_scode);
557 json_object_object_add(json, "bgpOriginCodes", json_ocode);
558 }
559 else
560 {
561 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
562 inet_ntoa (bgp->router_id), VTY_NEWLINE);
563 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
564 VTY_NEWLINE);
565 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
566 VTY_NEWLINE, VTY_NEWLINE);
567 vty_out (vty, v4_header, VTY_NEWLINE);
568 }
569 header = 0;
570 }
571
572 if (rd_header)
573 {
574 u_int16_t type;
575 struct rd_as rd_as;
ea8b7c71 576 struct rd_ip rd_ip = {0};
65efcfce
LB
577#if ENABLE_BGP_VNC
578 struct rd_vnc_eth rd_vnc_eth;
579#endif
856ca177
MS
580 u_char *pnt;
581
582 pnt = rn->p.u.val;
583
584 /* Decode RD type. */
585 type = decode_rd_type (pnt);
586 /* Decode RD value. */
587 if (type == RD_TYPE_AS)
588 decode_rd_as (pnt + 2, &rd_as);
fe770c88
LB
589 else if (type == RD_TYPE_AS4)
590 decode_rd_as4 (pnt + 2, &rd_as);
856ca177
MS
591 else if (type == RD_TYPE_IP)
592 decode_rd_ip (pnt + 2, &rd_ip);
65efcfce
LB
593#if ENABLE_BGP_VNC
594 else if (type == RD_TYPE_VNC_ETH)
595 decode_rd_vnc_eth (pnt, &rd_vnc_eth);
596#endif
856ca177
MS
597
598 if (use_json)
599 {
600 char buffer[BUFSIZ];
fe770c88 601 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
856ca177
MS
602 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
603 else if (type == RD_TYPE_IP)
5007999a 604 sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
856ca177
MS
605 json_object_string_add(json_routes, "routeDistinguisher", buffer);
606 }
607 else
608 {
609 vty_out (vty, "Route Distinguisher: ");
610
fe770c88 611 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
856ca177
MS
612 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
613 else if (type == RD_TYPE_IP)
614 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
65efcfce
LB
615#if ENABLE_BGP_VNC
616 else if (type == RD_TYPE_VNC_ETH)
617 vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
618 rd_vnc_eth.local_nve_id,
619 rd_vnc_eth.macaddr.octet[0],
620 rd_vnc_eth.macaddr.octet[1],
621 rd_vnc_eth.macaddr.octet[2],
622 rd_vnc_eth.macaddr.octet[3],
623 rd_vnc_eth.macaddr.octet[4],
624 rd_vnc_eth.macaddr.octet[5]);
625#endif
856ca177
MS
626
627 vty_out (vty, "%s", VTY_NEWLINE);
628 }
629 rd_header = 0;
630 }
631 route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN, use_json, json_array);
632 }
633 }
634 if (use_json)
635 {
636 struct prefix *p;
637 char buf_a[BUFSIZ];
638 char buf_b[BUFSIZ];
639 p = &rm->p;
640 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
641 json_object_object_add(json_routes, buf_a, json_array);
642 }
718e3744 643 }
644 }
856ca177
MS
645 if (use_json)
646 {
647 json_object_object_add(json, "routes", json_routes);
2aac5767 648 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
856ca177
MS
649 json_object_free(json);
650 }
718e3744 651 return CMD_SUCCESS;
652}
653
654enum bgp_show_type
655{
656 bgp_show_type_normal,
657 bgp_show_type_regexp,
658 bgp_show_type_prefix_list,
659 bgp_show_type_filter_list,
660 bgp_show_type_neighbor,
661 bgp_show_type_cidr_only,
662 bgp_show_type_prefix_longer,
663 bgp_show_type_community_all,
664 bgp_show_type_community,
665 bgp_show_type_community_exact,
666 bgp_show_type_community_list,
667 bgp_show_type_community_list_exact
668};
669
94f2b392 670static int
e3e29b32
LB
671bgp_show_mpls_vpn (struct vty *vty, afi_t afi, struct prefix_rd *prd,
672 enum bgp_show_type type, void *output_arg, int tags, u_char use_json)
718e3744 673{
674 struct bgp *bgp;
675 struct bgp_table *table;
676 struct bgp_node *rn;
677 struct bgp_node *rm;
678 struct bgp_info *ri;
679 int rd_header;
680 int header = 1;
681 char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
682 char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
e3e29b32
LB
683 unsigned long output_count = 0;
684 unsigned long total_count = 0;
856ca177
MS
685 json_object *json = NULL;
686 json_object *json_mroute = NULL;
687 json_object *json_nroute = NULL;
688 json_object *json_array = NULL;
689 json_object *json_scode = NULL;
690 json_object *json_ocode = NULL;
718e3744 691
692 bgp = bgp_get_default ();
693 if (bgp == NULL)
694 {
856ca177
MS
695 if (!use_json)
696 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
718e3744 697 return CMD_WARNING;
698 }
856ca177
MS
699
700 if (use_json)
701 {
702 json_scode = json_object_new_object();
703 json_ocode = json_object_new_object();
704 json = json_object_new_object();
705 json_mroute = json_object_new_object();
706 json_nroute = json_object_new_object();
707
708 json_object_string_add(json_scode, "suppressed", "s");
709 json_object_string_add(json_scode, "damped", "d");
710 json_object_string_add(json_scode, "history", "h");
711 json_object_string_add(json_scode, "valid", "*");
712 json_object_string_add(json_scode, "best", ">");
713 json_object_string_add(json_scode, "internal", "i");
714
715 json_object_string_add(json_ocode, "igp", "i");
716 json_object_string_add(json_ocode, "egp", "e");
717 json_object_string_add(json_ocode, "incomplete", "?");
718 }
719
945c8fe9
LB
720 if ((afi != AFI_IP) && (afi != AFI_IP6))
721 {
722 vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
723 return CMD_WARNING;
724 }
725
726 for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
718e3744 727 {
728 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
729 continue;
730
731 if ((table = rn->info) != NULL)
732 {
733 rd_header = 1;
734
735 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
856ca177 736 {
e3e29b32 737 total_count++;
856ca177
MS
738 if (use_json)
739 json_array = json_object_new_array();
740 else
741 json_array = NULL;
742
743 for (ri = rm->info; ri; ri = ri->next)
744 {
745 if (type == bgp_show_type_neighbor)
746 {
747 union sockunion *su = output_arg;
748
749 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
750 continue;
751 }
752 if (header)
753 {
754 if (use_json)
755 {
756 if (!tags)
757 {
758 json_object_int_add(json, "bgpTableVersion", 0);
759 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
760 json_object_object_add(json, "bgpStatusCodes", json_scode);
761 json_object_object_add(json, "bgpOriginCodes", json_ocode);
762 }
763 }
764 else
765 {
766 if (tags)
767 vty_out (vty, v4_header_tag, VTY_NEWLINE);
768 else
769 {
770 vty_out (vty, "BGP table version is 0, local router ID is %s%s",
771 inet_ntoa (bgp->router_id), VTY_NEWLINE);
772 vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
773 VTY_NEWLINE);
774 vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
775 VTY_NEWLINE, VTY_NEWLINE);
776 vty_out (vty, v4_header, VTY_NEWLINE);
777 }
778 }
779 header = 0;
780 }
781
782 if (rd_header)
783 {
784 u_int16_t type;
785 struct rd_as rd_as;
ea8b7c71 786 struct rd_ip rd_ip = {0};
65efcfce
LB
787#if ENABLE_BGP_VNC
788 struct rd_vnc_eth rd_vnc_eth;
789#endif
856ca177
MS
790 u_char *pnt;
791
792 pnt = rn->p.u.val;
793
794 /* Decode RD type. */
795 type = decode_rd_type (pnt);
796 /* Decode RD value. */
797 if (type == RD_TYPE_AS)
798 decode_rd_as (pnt + 2, &rd_as);
fe770c88
LB
799 else if (type == RD_TYPE_AS4)
800 decode_rd_as4 (pnt + 2, &rd_as);
856ca177
MS
801 else if (type == RD_TYPE_IP)
802 decode_rd_ip (pnt + 2, &rd_ip);
65efcfce
LB
803#if ENABLE_BGP_VNC
804 else if (type == RD_TYPE_VNC_ETH)
805 decode_rd_vnc_eth (pnt, &rd_vnc_eth);
806#endif
856ca177
MS
807
808 if (use_json)
809 {
810 char buffer[BUFSIZ];
fe770c88 811 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
856ca177
MS
812 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
813 else if (type == RD_TYPE_IP)
814 sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
815 json_object_string_add(json_nroute, "routeDistinguisher", buffer);
816 }
817 else
818 {
819 vty_out (vty, "Route Distinguisher: ");
820
fe770c88 821 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
856ca177
MS
822 vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
823 else if (type == RD_TYPE_IP)
824 vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
65efcfce
LB
825#if ENABLE_BGP_VNC
826 else if (type == RD_TYPE_VNC_ETH)
827 vty_out (vty, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
828 rd_vnc_eth.local_nve_id,
829 rd_vnc_eth.macaddr.octet[0],
830 rd_vnc_eth.macaddr.octet[1],
831 rd_vnc_eth.macaddr.octet[2],
832 rd_vnc_eth.macaddr.octet[3],
833 rd_vnc_eth.macaddr.octet[4],
834 rd_vnc_eth.macaddr.octet[5]);
835#endif
856ca177
MS
836 vty_out (vty, "%s", VTY_NEWLINE);
837 }
838 rd_header = 0;
839 }
840 if (tags)
841 route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
842 else
843 route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, json_array);
e3e29b32 844 output_count++;
856ca177
MS
845 }
846
847 if (use_json)
848 {
849 struct prefix *p;
850 char buf_a[BUFSIZ];
851 char buf_b[BUFSIZ];
852 p = &rm->p;
853 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
854 json_object_object_add(json_mroute, buf_a, json_array);
855 }
856 }
857
858 if (use_json)
859 {
860 struct prefix *p;
861 char buf_a[BUFSIZ];
862 char buf_b[BUFSIZ];
863 p = &rn->p;
864 sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), p->prefixlen);
865 json_object_object_add(json_nroute, buf_a, json_mroute);
866 }
718e3744 867 }
868 }
856ca177
MS
869
870 if (use_json)
871 {
872 json_object_object_add(json, "routes", json_nroute);
2aac5767 873 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
856ca177
MS
874 json_object_free(json);
875 }
e3e29b32
LB
876 else
877 {
878 if (output_count == 0)
879 vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
880 else
881 vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
882 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
883 }
884
718e3744 885 return CMD_SUCCESS;
886}
887
e3e29b32
LB
888DEFUN (show_bgp_ivp4_vpn,
889 show_bgp_ipv4_vpn_cmd,
890 "show bgp ipv4 vpn {json}",
891 SHOW_STR
892 BGP_STR
893 "Address Family\n"
894 "Display VPN NLRI specific information\n")
895{
896 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
897}
898
899DEFUN (show_bgp_ipv6_vpn,
900 show_bgp_ipv6_vpn_cmd,
901 "show bgp ipv6 vpn {json}",
902 SHOW_STR
903 BGP_STR
904 "Address Family\n"
905 "Display VPN NLRI specific information\n")
906{
907 return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
908}
909
910DEFUN (show_bgp_ipv4_vpn_rd,
911 show_bgp_ipv4_vpn_rd_cmd,
912 "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn {json}",
913 SHOW_STR
914 BGP_STR
915 "Address Family\n"
916 "Display VPN NLRI specific information\n"
917 "Display information for a route distinguisher\n"
918 "VPN Route Distinguisher\n"
919 JSON_STR)
920{
921 int ret;
922 struct prefix_rd prd;
923
924 ret = str2prefix_rd (argv[0], &prd);
925 if (! ret)
926 {
927 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
928 return CMD_WARNING;
929 }
930 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
931}
932
933DEFUN (show_bgp_ipv6_vpn_rd,
934 show_bgp_ipv6_vpn_rd_cmd,
935 "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn {json}",
936 SHOW_STR
937 BGP_STR
938 "Address Family\n"
939 "Display VPN NLRI specific information\n"
940 "Display information for a route distinguisher\n"
941 "VPN Route Distinguisher\n"
942 JSON_STR)
943{
944 int ret;
945 struct prefix_rd prd;
946
947 ret = str2prefix_rd (argv[0], &prd);
948 if (!ret)
949 {
950 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
951 return CMD_WARNING;
952 }
953
954 return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
955}
956
718e3744 957DEFUN (show_ip_bgp_vpnv4_all,
958 show_ip_bgp_vpnv4_all_cmd,
959 "show ip bgp vpnv4 all",
960 SHOW_STR
961 IP_STR
962 BGP_STR
963 "Display VPNv4 NLRI specific information\n"
964 "Display information about all VPNv4 NLRIs\n")
965{
e3e29b32 966 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0, 0);
718e3744 967}
968
969DEFUN (show_ip_bgp_vpnv4_rd,
970 show_ip_bgp_vpnv4_rd_cmd,
971 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
972 SHOW_STR
973 IP_STR
974 BGP_STR
975 "Display VPNv4 NLRI specific information\n"
976 "Display information for a route distinguisher\n"
977 "VPN Route Distinguisher\n")
978{
979 int ret;
980 struct prefix_rd prd;
981
982 ret = str2prefix_rd (argv[0], &prd);
983 if (! ret)
984 {
985 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
986 return CMD_WARNING;
987 }
e3e29b32 988 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0, 0);
718e3744 989}
990
991DEFUN (show_ip_bgp_vpnv4_all_tags,
992 show_ip_bgp_vpnv4_all_tags_cmd,
993 "show ip bgp vpnv4 all tags",
994 SHOW_STR
995 IP_STR
996 BGP_STR
997 "Display VPNv4 NLRI specific information\n"
998 "Display information about all VPNv4 NLRIs\n"
999 "Display BGP tags for prefixes\n")
1000{
e3e29b32 1001 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 1, 0);
718e3744 1002}
1003
1004DEFUN (show_ip_bgp_vpnv4_rd_tags,
1005 show_ip_bgp_vpnv4_rd_tags_cmd,
1006 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
1007 SHOW_STR
1008 IP_STR
1009 BGP_STR
1010 "Display VPNv4 NLRI specific information\n"
1011 "Display information for a route distinguisher\n"
1012 "VPN Route Distinguisher\n"
1013 "Display BGP tags for prefixes\n")
1014{
1015 int ret;
1016 struct prefix_rd prd;
1017
1018 ret = str2prefix_rd (argv[0], &prd);
1019 if (! ret)
1020 {
1021 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1022 return CMD_WARNING;
1023 }
e3e29b32 1024 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1, 0);
718e3744 1025}
1026
1027DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
1028 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
856ca177 1029 "show ip bgp vpnv4 all neighbors A.B.C.D routes {json}",
718e3744 1030 SHOW_STR
1031 IP_STR
1032 BGP_STR
1033 "Display VPNv4 NLRI specific information\n"
1034 "Display information about all VPNv4 NLRIs\n"
1035 "Detailed information on TCP and BGP neighbor connections\n"
1036 "Neighbor to display information about\n"
856ca177
MS
1037 "Display routes learned from neighbor\n"
1038 "JavaScript Object Notation\n")
718e3744 1039{
c63b83fe 1040 union sockunion su;
718e3744 1041 struct peer *peer;
c63b83fe 1042 int ret;
db7c8528 1043 u_char uj = use_json(argc, argv);
c63b83fe
JBD
1044
1045 ret = str2sockunion (argv[0], &su);
1046 if (ret < 0)
718e3744 1047 {
db7c8528 1048 if (uj)
856ca177
MS
1049 {
1050 json_object *json_no = NULL;
1051 json_no = json_object_new_object();
1052 json_object_string_add(json_no, "warning", "Malformed address");
1053 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1054 json_object_free(json_no);
1055 }
1056 else
1057 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
c63b83fe 1058 return CMD_WARNING;
718e3744 1059 }
1060
c63b83fe 1061 peer = peer_lookup (NULL, &su);
718e3744 1062 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1063 {
db7c8528 1064 if (uj)
856ca177
MS
1065 {
1066 json_object *json_no = NULL;
1067 json_no = json_object_new_object();
1068 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1069 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1070 json_object_free(json_no);
1071 }
1072 else
1073 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
718e3744 1074 return CMD_WARNING;
1075 }
1076
e3e29b32 1077 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0, uj);
718e3744 1078}
1079
1080DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
1081 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
856ca177 1082 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes {json}",
718e3744 1083 SHOW_STR
1084 IP_STR
1085 BGP_STR
1086 "Display VPNv4 NLRI specific information\n"
1087 "Display information for a route distinguisher\n"
1088 "VPN Route Distinguisher\n"
1089 "Detailed information on TCP and BGP neighbor connections\n"
1090 "Neighbor to display information about\n"
856ca177
MS
1091 "Display routes learned from neighbor\n"
1092 "JavaScript Object Notation\n")
718e3744 1093{
1094 int ret;
c63b83fe 1095 union sockunion su;
718e3744 1096 struct peer *peer;
1097 struct prefix_rd prd;
db7c8528 1098 u_char uj = use_json(argc, argv);
718e3744 1099
1100 ret = str2prefix_rd (argv[0], &prd);
1101 if (! ret)
1102 {
db7c8528 1103 if (uj)
856ca177
MS
1104 {
1105 json_object *json_no = NULL;
1106 json_no = json_object_new_object();
1107 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1108 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1109 json_object_free(json_no);
1110 }
1111 else
1112 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
718e3744 1113 return CMD_WARNING;
1114 }
1115
c63b83fe
JBD
1116 ret = str2sockunion (argv[1], &su);
1117 if (ret < 0)
718e3744 1118 {
db7c8528 1119 if (uj)
856ca177
MS
1120 {
1121 json_object *json_no = NULL;
1122 json_no = json_object_new_object();
1123 json_object_string_add(json_no, "warning", "Malformed address");
1124 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1125 json_object_free(json_no);
1126 }
1127 else
1128 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
c63b83fe 1129 return CMD_WARNING;
718e3744 1130 }
1131
c63b83fe 1132 peer = peer_lookup (NULL, &su);
718e3744 1133 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1134 {
db7c8528 1135 if (uj)
856ca177
MS
1136 {
1137 json_object *json_no = NULL;
1138 json_no = json_object_new_object();
1139 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1140 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1141 json_object_free(json_no);
1142 }
1143 else
1144 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
718e3744 1145 return CMD_WARNING;
1146 }
1147
e3e29b32 1148 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0, uj);
718e3744 1149}
1150
1151DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
1152 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
856ca177 1153 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes {json}",
718e3744 1154 SHOW_STR
1155 IP_STR
1156 BGP_STR
1157 "Display VPNv4 NLRI specific information\n"
1158 "Display information about all VPNv4 NLRIs\n"
1159 "Detailed information on TCP and BGP neighbor connections\n"
1160 "Neighbor to display information about\n"
856ca177
MS
1161 "Display the routes advertised to a BGP neighbor\n"
1162 "JavaScript Object Notation\n")
718e3744 1163{
1164 int ret;
1165 struct peer *peer;
1166 union sockunion su;
db7c8528 1167 u_char uj = use_json(argc, argv);
718e3744 1168
1169 ret = str2sockunion (argv[0], &su);
1170 if (ret < 0)
1171 {
db7c8528 1172 if (uj)
856ca177
MS
1173 {
1174 json_object *json_no = NULL;
1175 json_no = json_object_new_object();
1176 json_object_string_add(json_no, "warning", "Malformed address");
1177 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1178 json_object_free(json_no);
1179 }
1180 else
1181 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
718e3744 1182 return CMD_WARNING;
1183 }
1184 peer = peer_lookup (NULL, &su);
1185 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1186 {
db7c8528 1187 if (uj)
856ca177
MS
1188 {
1189 json_object *json_no = NULL;
1190 json_no = json_object_new_object();
1191 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1192 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1193 json_object_free(json_no);
1194 }
1195 else
1196 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
718e3744 1197 return CMD_WARNING;
1198 }
1199
db7c8528 1200 return show_adj_route_vpn (vty, peer, NULL, uj);
718e3744 1201}
1202
1203DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
1204 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
856ca177 1205 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes {json}",
718e3744 1206 SHOW_STR
1207 IP_STR
1208 BGP_STR
1209 "Display VPNv4 NLRI specific information\n"
1210 "Display information for a route distinguisher\n"
1211 "VPN Route Distinguisher\n"
1212 "Detailed information on TCP and BGP neighbor connections\n"
1213 "Neighbor to display information about\n"
856ca177
MS
1214 "Display the routes advertised to a BGP neighbor\n"
1215 "JavaScript Object Notation\n")
718e3744 1216{
1217 int ret;
1218 struct peer *peer;
1219 struct prefix_rd prd;
1220 union sockunion su;
db7c8528 1221 u_char uj = use_json(argc, argv);
718e3744 1222
1223 ret = str2sockunion (argv[1], &su);
1224 if (ret < 0)
1225 {
db7c8528 1226 if (uj)
856ca177
MS
1227 {
1228 json_object *json_no = NULL;
1229 json_no = json_object_new_object();
1230 json_object_string_add(json_no, "warning", "Malformed address");
1231 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1232 json_object_free(json_no);
1233 }
1234 else
1235 vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
718e3744 1236 return CMD_WARNING;
1237 }
1238 peer = peer_lookup (NULL, &su);
1239 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1240 {
db7c8528 1241 if (uj)
856ca177
MS
1242 {
1243 json_object *json_no = NULL;
1244 json_no = json_object_new_object();
1245 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1246 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1247 json_object_free(json_no);
1248 }
1249 else
1250 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
718e3744 1251 return CMD_WARNING;
1252 }
1253
1254 ret = str2prefix_rd (argv[0], &prd);
1255 if (! ret)
1256 {
db7c8528 1257 if (uj)
856ca177
MS
1258 {
1259 json_object *json_no = NULL;
1260 json_no = json_object_new_object();
1261 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1262 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1263 json_object_free(json_no);
1264 }
1265 else
1266 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
718e3744 1267 return CMD_WARNING;
1268 }
1269
db7c8528 1270 return show_adj_route_vpn (vty, peer, &prd, uj);
718e3744 1271}
1272
1273void
94f2b392 1274bgp_mplsvpn_init (void)
718e3744 1275{
1276 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
137446f9 1277 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
718e3744 1278 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1279
e3e29b32
LB
1280 install_element (VIEW_NODE, &show_bgp_ipv4_vpn_cmd);
1281 install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_cmd);
1282 install_element (VIEW_NODE, &show_bgp_ipv6_vpn_cmd);
1283 install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_cmd);
718e3744 1284 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
1285 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
1286 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
1287 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
1288 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
1289 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
1290 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
1291 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
718e3744 1292}