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