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