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