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