]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.c
bgpd: handling router mac extended community
[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 290 bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
7ef5a232 291 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0, NULL);
65efcfce 292 }
718e3744 293 else
65efcfce 294 {
28070ee3 295 bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
7ef5a232 296 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, NULL);
28070ee3 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
3517059b 1004 "Address Family modifier\n"
718e3744 1005 "Display information for a route distinguisher\n"
1006 "VPN Route Distinguisher\n")
1007{
4f280b15 1008 int idx_ext_community = argc-1;
718e3744 1009 int ret;
1010 struct prefix_rd prd;
3f227172
PG
1011 afi_t afi;
1012 int idx = 0;
718e3744 1013
3f227172 1014 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
718e3744 1015 {
3f227172
PG
1016 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1017 if (! ret)
1018 {
1019 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1020 return CMD_WARNING;
1021 }
1022 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 0, 0);
718e3744 1023 }
3f227172
PG
1024 return CMD_SUCCESS;
1025 }
718e3744 1026
4f280b15
LB
1027#ifdef KEEP_OLD_VPN_COMMANDS
1028DEFUN (show_ip_bgp_vpn_all,
1029 show_ip_bgp_vpn_all_cmd,
1030 "show [ip] bgp <vpnv4|vpnv6>",
1031 SHOW_STR
1032 IP_STR
1033 BGP_STR
1034 BGP_VPNVX_HELP_STR)
1035{
1036 afi_t afi;
1037 int idx = 0;
1038
1039 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1040 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, 0);
1041 return CMD_SUCCESS;
1042}
1043
3f227172
PG
1044DEFUN (show_ip_bgp_vpn_all_tags,
1045 show_ip_bgp_vpn_all_tags_cmd,
1046 "show [ip] bgp <vpnv4|vpnv6> all tags",
718e3744 1047 SHOW_STR
1048 IP_STR
1049 BGP_STR
3f227172
PG
1050 BGP_VPNVX_HELP_STR
1051 "Display information about all VPNv4/VPNV6 NLRIs\n"
718e3744 1052 "Display BGP tags for prefixes\n")
1053{
3f227172
PG
1054 afi_t afi;
1055 int idx = 0;
1056
1057 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1058 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 1, 0);
1059 return CMD_SUCCESS;
718e3744 1060}
1061
3f227172
PG
1062DEFUN (show_ip_bgp_vpn_rd_tags,
1063 show_ip_bgp_vpn_rd_tags_cmd,
1064 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
718e3744 1065 SHOW_STR
1066 IP_STR
1067 BGP_STR
3f227172 1068 BGP_VPNVX_HELP_STR
718e3744 1069 "Display information for a route distinguisher\n"
1070 "VPN Route Distinguisher\n"
1071 "Display BGP tags for prefixes\n")
1072{
c500ae40 1073 int idx_ext_community = 5;
718e3744 1074 int ret;
1075 struct prefix_rd prd;
3f227172
PG
1076 afi_t afi;
1077 int idx = 0;
718e3744 1078
3f227172 1079 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
718e3744 1080 {
3f227172
PG
1081 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1082 if (! ret)
1083 {
1084 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1085 return CMD_WARNING;
1086 }
1087 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_normal, NULL, 1, 0);
718e3744 1088 }
3f227172 1089 return CMD_SUCCESS;
718e3744 1090}
1091
3f227172
PG
1092DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
1093 show_ip_bgp_vpn_all_neighbor_routes_cmd,
1094 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
718e3744 1095 SHOW_STR
1096 IP_STR
1097 BGP_STR
3f227172
PG
1098 BGP_VPNVX_HELP_STR
1099 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1100 "Detailed information on TCP and BGP neighbor connections\n"
1101 "Neighbor to display information about\n"
856ca177 1102 "Display routes learned from neighbor\n"
9973d184 1103 JSON_STR)
718e3744 1104{
c500ae40 1105 int idx_ipv4 = 6;
c63b83fe 1106 union sockunion su;
718e3744 1107 struct peer *peer;
c63b83fe 1108 int ret;
db7c8528 1109 u_char uj = use_json(argc, argv);
3f227172
PG
1110 afi_t afi;
1111 int idx = 0;
c63b83fe 1112
3f227172 1113 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
718e3744 1114 {
3f227172
PG
1115 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1116 if (ret < 0)
856ca177 1117 {
3f227172
PG
1118 if (uj)
1119 {
1120 json_object *json_no = NULL;
1121 json_no = json_object_new_object();
1122 json_object_string_add(json_no, "warning", "Malformed address");
1123 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1124 json_object_free(json_no);
1125 }
1126 else
1127 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
1128 return CMD_WARNING;
856ca177 1129 }
718e3744 1130
3f227172
PG
1131 peer = peer_lookup (NULL, &su);
1132 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
856ca177 1133 {
3f227172
PG
1134 if (uj)
1135 {
1136 json_object *json_no = NULL;
1137 json_no = json_object_new_object();
1138 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1139 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1140 json_object_free(json_no);
1141 }
1142 else
1143 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1144 return CMD_WARNING;
856ca177 1145 }
718e3744 1146
3f227172
PG
1147 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_neighbor, &su, 0, uj);
1148 }
1149 return CMD_SUCCESS;
718e3744 1150}
1151
3f227172
PG
1152DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
1153 show_ip_bgp_vpn_rd_neighbor_routes_cmd,
1154 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
718e3744 1155 SHOW_STR
1156 IP_STR
1157 BGP_STR
3f227172 1158 BGP_VPNVX_HELP_STR
718e3744 1159 "Display information for a route distinguisher\n"
1160 "VPN Route Distinguisher\n"
1161 "Detailed information on TCP and BGP neighbor connections\n"
1162 "Neighbor to display information about\n"
856ca177 1163 "Display routes learned from neighbor\n"
9973d184 1164 JSON_STR)
718e3744 1165{
c500ae40
DW
1166 int idx_ext_community = 5;
1167 int idx_ipv4 = 7;
718e3744 1168 int ret;
c63b83fe 1169 union sockunion su;
718e3744 1170 struct peer *peer;
1171 struct prefix_rd prd;
db7c8528 1172 u_char uj = use_json(argc, argv);
3f227172
PG
1173 afi_t afi;
1174 int idx = 0;
718e3744 1175
3f227172 1176 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
718e3744 1177 {
3f227172
PG
1178 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1179 if (! ret)
856ca177 1180 {
3f227172
PG
1181 if (uj)
1182 {
1183 json_object *json_no = NULL;
1184 json_no = json_object_new_object();
1185 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1186 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1187 json_object_free(json_no);
1188 }
1189 else
1190 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1191 return CMD_WARNING;
856ca177 1192 }
718e3744 1193
3f227172
PG
1194 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1195 if (ret < 0)
856ca177 1196 {
3f227172
PG
1197 if (uj)
1198 {
1199 json_object *json_no = NULL;
1200 json_no = json_object_new_object();
1201 json_object_string_add(json_no, "warning", "Malformed address");
1202 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1203 json_object_free(json_no);
1204 }
1205 else
1206 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1207 return CMD_WARNING;
856ca177 1208 }
718e3744 1209
3f227172
PG
1210 peer = peer_lookup (NULL, &su);
1211 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
856ca177 1212 {
3f227172
PG
1213 if (uj)
1214 {
1215 json_object *json_no = NULL;
1216 json_no = json_object_new_object();
1217 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1218 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1219 json_object_free(json_no);
1220 }
1221 else
1222 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1223 return CMD_WARNING;
856ca177 1224 }
718e3744 1225
3f227172
PG
1226 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_neighbor, &su, 0, uj);
1227 }
1228 return CMD_SUCCESS;
718e3744 1229}
1230
3f227172
PG
1231DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
1232 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd,
1233 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
718e3744 1234 SHOW_STR
1235 IP_STR
1236 BGP_STR
3f227172
PG
1237 BGP_VPNVX_HELP_STR
1238 "Display information about all VPNv4/VPNv6 NLRIs\n"
718e3744 1239 "Detailed information on TCP and BGP neighbor connections\n"
1240 "Neighbor to display information about\n"
856ca177 1241 "Display the routes advertised to a BGP neighbor\n"
9973d184 1242 JSON_STR)
718e3744 1243{
c500ae40 1244 int idx_ipv4 = 6;
718e3744 1245 int ret;
1246 struct peer *peer;
1247 union sockunion su;
db7c8528 1248 u_char uj = use_json(argc, argv);
3f227172
PG
1249 afi_t afi;
1250 int idx = 0;
718e3744 1251
3f227172 1252 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
718e3744 1253 {
3f227172
PG
1254 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1255 if (ret < 0)
856ca177 1256 {
3f227172
PG
1257 if (uj)
1258 {
1259 json_object *json_no = NULL;
1260 json_no = json_object_new_object();
1261 json_object_string_add(json_no, "warning", "Malformed address");
1262 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1263 json_object_free(json_no);
1264 }
1265 else
1266 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
1267 return CMD_WARNING;
856ca177 1268 }
3f227172
PG
1269 peer = peer_lookup (NULL, &su);
1270 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
856ca177 1271 {
3f227172
PG
1272 if (uj)
1273 {
1274 json_object *json_no = NULL;
1275 json_no = json_object_new_object();
1276 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1277 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1278 json_object_free(json_no);
1279 }
1280 else
1281 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1282 return CMD_WARNING;
856ca177 1283 }
718e3744 1284
3f227172
PG
1285 return show_adj_route_vpn (vty, peer, NULL, uj, afi);
1286 }
1287 return CMD_SUCCESS;
718e3744 1288}
1289
3f227172
PG
1290DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
1291 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
1292 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
718e3744 1293 SHOW_STR
1294 IP_STR
1295 BGP_STR
3f227172 1296 BGP_VPNVX_HELP_STR
718e3744 1297 "Display information for a route distinguisher\n"
1298 "VPN Route Distinguisher\n"
1299 "Detailed information on TCP and BGP neighbor connections\n"
1300 "Neighbor to display information about\n"
856ca177 1301 "Display the routes advertised to a BGP neighbor\n"
9973d184 1302 JSON_STR)
718e3744 1303{
c500ae40
DW
1304 int idx_ext_community = 5;
1305 int idx_ipv4 = 7;
718e3744 1306 int ret;
1307 struct peer *peer;
1308 struct prefix_rd prd;
1309 union sockunion su;
db7c8528 1310 u_char uj = use_json(argc, argv);
3f227172
PG
1311 afi_t afi;
1312 int idx = 0;
718e3744 1313
3f227172 1314 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
718e3744 1315 {
3f227172
PG
1316 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1317 if (ret < 0)
856ca177 1318 {
3f227172
PG
1319 if (uj)
1320 {
1321 json_object *json_no = NULL;
1322 json_no = json_object_new_object();
1323 json_object_string_add(json_no, "warning", "Malformed address");
1324 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1325 json_object_free(json_no);
1326 }
1327 else
1328 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1329 return CMD_WARNING;
856ca177 1330 }
3f227172
PG
1331 peer = peer_lookup (NULL, &su);
1332 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
856ca177 1333 {
3f227172
PG
1334 if (uj)
1335 {
1336 json_object *json_no = NULL;
1337 json_no = json_object_new_object();
1338 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1339 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1340 json_object_free(json_no);
1341 }
1342 else
1343 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1344 return CMD_WARNING;
856ca177 1345 }
718e3744 1346
3f227172
PG
1347 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1348 if (! ret)
856ca177 1349 {
3f227172
PG
1350 if (uj)
1351 {
1352 json_object *json_no = NULL;
1353 json_no = json_object_new_object();
1354 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1355 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1356 json_object_free(json_no);
1357 }
1358 else
1359 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1360 return CMD_WARNING;
856ca177 1361 }
718e3744 1362
3f227172
PG
1363 return show_adj_route_vpn (vty, peer, &prd, uj, afi);
1364 }
1365 return CMD_SUCCESS;
718e3744 1366}
d6902373 1367#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 1368
1369void
94f2b392 1370bgp_mplsvpn_init (void)
718e3744 1371{
1372 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
137446f9 1373 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
718e3744 1374 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1375
c286be96 1376 install_element (BGP_VPNV6_NODE, &vpnv6_network_cmd);
c286be96
LX
1377 install_element (BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
1378
4f280b15
LB
1379 install_element (VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
1380 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
d6902373 1381#ifdef KEEP_OLD_VPN_COMMANDS
3f227172
PG
1382 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_cmd);
1383 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
1384 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_tags_cmd);
1385 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_tags_cmd);
1386 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_routes_cmd);
1387 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_routes_cmd);
1388 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd);
1389 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
d6902373 1390#endif /* KEEP_OLD_VPN_COMMANDS */
718e3744 1391}