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