]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge remote-tracking branch 'origin/master' into redistribute
[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
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;
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));
193
194 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
195 for (; pnt < lim; pnt += psize)
196 {
197 /* Clear prefix structure. */
198 memset (&p, 0, sizeof (struct prefix));
199
200 if (addpath_encoded)
201 {
202
203 /* When packet overflow occurs return immediately. */
204 if (pnt + BGP_ADDPATH_ID_LEN > lim)
205 return -1;
206
207 addpath_id = ntohl(*((uint32_t*) pnt));
208 pnt += BGP_ADDPATH_ID_LEN;
209 }
210
211 /* Fetch prefix length. */
212 prefixlen = *pnt++;
213 p.family = afi2family (packet->afi);
214 psize = PSIZE (prefixlen);
215
216 if (prefixlen < VPN_PREFIXLEN_MIN_BYTES*8)
217 {
218 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
219 peer->host, prefixlen);
220 return -1;
221 }
222
223 /* sanity check against packet data */
224 if ((pnt + psize) > lim)
225 {
226 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
227 peer->host,
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 {
235 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
236 peer->host,
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 {
244 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
245 peer->host,
246 prefixlen - VPN_PREFIXLEN_MIN_BYTES*8,
247 p.family, prefix_blen (&p));
248 return -1;
249 }
250
251 /* Copyr label to prefix. */
252 tagpnt = pnt;
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
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
274 #if ENABLE_BGP_VNC
275 case RD_TYPE_VNC_ETH:
276 break;
277 #endif
278
279 default:
280 zlog_err ("Unknown RD type %d", type);
281 break; /* just report */
282 }
283
284 p.prefixlen = prefixlen - VPN_PREFIXLEN_MIN_BYTES*8;/* exclude label & RD */
285 memcpy (&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
286 psize - VPN_PREFIXLEN_MIN_BYTES);
287
288 if (attr)
289 {
290 bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
291 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
292 }
293 else
294 {
295 bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
296 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
297 }
298 }
299 /* Packet length consistency check. */
300 if (pnt != lim)
301 {
302 zlog_err ("%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
303 peer->host, lim - pnt);
304 return -1;
305 }
306
307 return 0;
308 #undef VPN_PREFIXLEN_MIN_BYTES
309 }
310
311 int
312 str2prefix_rd (const char *str, struct prefix_rd *prd)
313 {
314 int ret; /* ret of called functions */
315 int lret; /* local ret, of this func */
316 char *p;
317 char *p2;
318 struct stream *s = NULL;
319 char *half = NULL;
320 struct in_addr addr;
321
322 s = stream_new (8);
323
324 prd->family = AF_UNSPEC;
325 prd->prefixlen = 64;
326
327 lret = 0;
328 p = strchr (str, ':');
329 if (! p)
330 goto out;
331
332 if (! all_digit (p + 1))
333 goto out;
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 {
343 unsigned long as_val;
344
345 if (! all_digit (half))
346 goto out;
347
348 as_val = atol(half);
349 if (as_val > 0xffff)
350 {
351 stream_putw (s, RD_TYPE_AS4);
352 stream_putl (s, as_val);
353 stream_putw (s, atol (p + 1));
354 }
355 else
356 {
357 stream_putw (s, RD_TYPE_AS);
358 stream_putw (s, as_val);
359 stream_putl (s, atol (p + 1));
360 }
361 }
362 else
363 {
364 ret = inet_aton (half, &addr);
365 if (! ret)
366 goto out;
367
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);
373 lret = 1;
374
375 out:
376 if (s)
377 stream_free (s);
378 if (half)
379 XFREE(MTYPE_TMP, half);
380 return lret;
381 }
382
383 int
384 str2tag (const char *str, u_char *tag)
385 {
386 unsigned long l;
387 char *endptr;
388 u_int32_t t;
389
390 if (*str == '-')
391 return 0;
392
393 errno = 0;
394 l = strtoul (str, &endptr, 10);
395
396 if (*endptr != '\0' || errno || l > UINT32_MAX)
397 return 0;
398
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);
404
405 return 1;
406 }
407
408 char *
409 prefix_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);
426 snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
427 return buf;
428 }
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 }
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 }
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
456 return NULL;
457 }
458
459 /* For testing purpose, static route of MPLS-VPN. */
460 DEFUN (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"
464 "IPv4 prefix\n"
465 "Specify Route Distinguisher\n"
466 "VPN Route Distinguisher\n"
467 "BGP tag\n"
468 "tag value\n")
469 {
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);
474 }
475
476 DEFUN (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"
480 "IPv4 prefix\n"
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 {
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);
493 }
494
495 /* For testing purpose, static route of MPLS-VPN. */
496 DEFUN (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"
501 "IPv4 prefix\n"
502 "Specify Route Distinguisher\n"
503 "VPN Route Distinguisher\n"
504 "BGP tag\n"
505 "tag value\n")
506 {
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);
511 }
512
513 DEFUN (vpnv6_network,
514 vpnv6_network_cmd,
515 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD [route-map WORD]",
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"
521 "tag value\n"
522 "route map\n"
523 "route map name\n")
524 {
525 int idx_ipv6_prefix = 1;
526 int idx_ext_community = 3;
527 int idx_word = 5;
528 int idx_word_2 = 7;
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);
533 }
534
535 /* For testing purpose, static route of MPLS-VPN. */
536 DEFUN (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
553 #if defined(KEEP_OLD_VPN_COMMANDS)
554 static int
555 show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u_char use_json, afi_t afi)
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";
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;
570
571 bgp = bgp_get_default ();
572 if (bgp == NULL)
573 {
574 if (!use_json)
575 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
576 return CMD_WARNING;
577 }
578
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
598 for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn;
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 {
606 if (use_json)
607 json_array = json_object_new_array();
608 else
609 json_array = NULL;
610
611 rd_header = 1;
612
613 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
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;
643 struct rd_ip rd_ip = {0};
644 #if ENABLE_BGP_VNC
645 struct rd_vnc_eth rd_vnc_eth = {0};
646 #endif
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);
656 else if (type == RD_TYPE_AS4)
657 decode_rd_as4 (pnt + 2, &rd_as);
658 else if (type == RD_TYPE_IP)
659 decode_rd_ip (pnt + 2, &rd_ip);
660 #if ENABLE_BGP_VNC
661 else if (type == RD_TYPE_VNC_ETH)
662 decode_rd_vnc_eth (pnt, &rd_vnc_eth);
663 #endif
664
665 if (use_json)
666 {
667 char buffer[BUFSIZ];
668 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
669 sprintf (buffer, "%u:%d", rd_as.as, rd_as.val);
670 else if (type == RD_TYPE_IP)
671 sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
672 json_object_string_add(json_routes, "routeDistinguisher", buffer);
673 }
674 else
675 {
676 vty_out (vty, "Route Distinguisher: ");
677
678 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
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);
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
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 }
710 }
711 }
712 if (use_json)
713 {
714 json_object_object_add(json, "routes", json_routes);
715 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
716 json_object_free(json);
717 }
718 return CMD_SUCCESS;
719 }
720 #endif
721
722 int
723 bgp_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)
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";
735 unsigned long output_count = 0;
736 unsigned long total_count = 0;
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;
743
744 bgp = bgp_get_default ();
745 if (bgp == NULL)
746 {
747 if (!use_json)
748 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
749 return CMD_WARNING;
750 }
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
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))
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))
788 {
789 total_count++;
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;
838 struct rd_ip rd_ip = {0};
839 #if ENABLE_BGP_VNC
840 struct rd_vnc_eth rd_vnc_eth = {0};
841 #endif
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);
851 else if (type == RD_TYPE_AS4)
852 decode_rd_as4 (pnt + 2, &rd_as);
853 else if (type == RD_TYPE_IP)
854 decode_rd_ip (pnt + 2, &rd_ip);
855 #if ENABLE_BGP_VNC
856 else if (type == RD_TYPE_VNC_ETH)
857 decode_rd_vnc_eth (pnt, &rd_vnc_eth);
858 #endif
859
860 if (use_json)
861 {
862 char buffer[BUFSIZ];
863 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
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
873 if (type == RD_TYPE_AS || type == RD_TYPE_AS4)
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);
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
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);
896 output_count++;
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 }
919 }
920 }
921
922 if (use_json)
923 {
924 json_object_object_add(json, "routes", json_nroute);
925 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
926 json_object_free(json);
927 }
928 else
929 {
930 if (output_count == 0)
931 vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
932 else
933 vty_out (vty, "%sDisplayed %ld routes and %ld total paths%s",
934 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
935 }
936
937 return CMD_SUCCESS;
938 }
939
940 #ifdef KEEP_OLD_VPN_COMMANDS
941 DEFUN (show_ip_bgp_vpn_all,
942 show_ip_bgp_vpn_all_cmd,
943 "show [ip] bgp <vpnv4|vpnv6>",
944 SHOW_STR
945 IP_STR
946 BGP_STR
947 BGP_VPNVX_HELP_STR)
948 {
949 afi_t afi;
950 int idx = 0;
951
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);
954
955 return CMD_SUCCESS;
956 }
957 #endif
958
959 DEFUN (show_bgp_ip_vpn_all_rd,
960 show_bgp_ip_vpn_all_rd_cmd,
961 "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
962 SHOW_STR
963 IP_STR
964 BGP_STR
965 BGP_VPNVX_HELP_STR
966 "Display VPN NLRI specific information\n"
967 "Display information for a route distinguisher\n"
968 "VPN Route Distinguisher\n"
969 JSON_STR)
970 {
971 int idx_rd = 5;
972 int ret;
973 struct prefix_rd prd;
974 afi_t afi;
975 int idx = 0;
976
977 if (argv_find_and_parse_afi (argv, argc, &idx, &afi))
978 {
979 if (argc >= 7 && argv[idx_rd]->arg)
980 {
981 ret = str2prefix_rd (argv[idx_rd]->arg, &prd);
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 }
993 }
994 return CMD_SUCCESS;
995 }
996
997 DEFUN (show_ip_bgp_vpn_rd,
998 show_ip_bgp_vpn_rd_cmd,
999 "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn",
1000 SHOW_STR
1001 IP_STR
1002 BGP_STR
1003 BGP_AFI_HELP_STR
1004 "Address Family modifier\n"
1005 "Display information for a route distinguisher\n"
1006 "VPN Route Distinguisher\n")
1007 {
1008 int idx_ext_community = argc-1;
1009 int ret;
1010 struct prefix_rd prd;
1011 afi_t afi;
1012 int idx = 0;
1013
1014 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1015 {
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);
1023 }
1024 return CMD_SUCCESS;
1025 }
1026
1027 #ifdef KEEP_OLD_VPN_COMMANDS
1028 DEFUN (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
1044 DEFUN (show_ip_bgp_vpn_all_tags,
1045 show_ip_bgp_vpn_all_tags_cmd,
1046 "show [ip] bgp <vpnv4|vpnv6> all tags",
1047 SHOW_STR
1048 IP_STR
1049 BGP_STR
1050 BGP_VPNVX_HELP_STR
1051 "Display information about all VPNv4/VPNV6 NLRIs\n"
1052 "Display BGP tags for prefixes\n")
1053 {
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;
1060 }
1061
1062 DEFUN (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",
1065 SHOW_STR
1066 IP_STR
1067 BGP_STR
1068 BGP_VPNVX_HELP_STR
1069 "Display information for a route distinguisher\n"
1070 "VPN Route Distinguisher\n"
1071 "Display BGP tags for prefixes\n")
1072 {
1073 int idx_ext_community = 5;
1074 int ret;
1075 struct prefix_rd prd;
1076 afi_t afi;
1077 int idx = 0;
1078
1079 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1080 {
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);
1088 }
1089 return CMD_SUCCESS;
1090 }
1091
1092 DEFUN (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]",
1095 SHOW_STR
1096 IP_STR
1097 BGP_STR
1098 BGP_VPNVX_HELP_STR
1099 "Display information about all VPNv4/VPNv6 NLRIs\n"
1100 "Detailed information on TCP and BGP neighbor connections\n"
1101 "Neighbor to display information about\n"
1102 "Display routes learned from neighbor\n"
1103 JSON_STR)
1104 {
1105 int idx_ipv4 = 6;
1106 union sockunion su;
1107 struct peer *peer;
1108 int ret;
1109 u_char uj = use_json(argc, argv);
1110 afi_t afi;
1111 int idx = 0;
1112
1113 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1114 {
1115 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1116 if (ret < 0)
1117 {
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;
1129 }
1130
1131 peer = peer_lookup (NULL, &su);
1132 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1133 {
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;
1145 }
1146
1147 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_neighbor, &su, 0, uj);
1148 }
1149 return CMD_SUCCESS;
1150 }
1151
1152 DEFUN (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]",
1155 SHOW_STR
1156 IP_STR
1157 BGP_STR
1158 BGP_VPNVX_HELP_STR
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"
1163 "Display routes learned from neighbor\n"
1164 JSON_STR)
1165 {
1166 int idx_ext_community = 5;
1167 int idx_ipv4 = 7;
1168 int ret;
1169 union sockunion su;
1170 struct peer *peer;
1171 struct prefix_rd prd;
1172 u_char uj = use_json(argc, argv);
1173 afi_t afi;
1174 int idx = 0;
1175
1176 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1177 {
1178 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1179 if (! ret)
1180 {
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;
1192 }
1193
1194 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1195 if (ret < 0)
1196 {
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;
1208 }
1209
1210 peer = peer_lookup (NULL, &su);
1211 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1212 {
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;
1224 }
1225
1226 return bgp_show_mpls_vpn (vty, afi, &prd, bgp_show_type_neighbor, &su, 0, uj);
1227 }
1228 return CMD_SUCCESS;
1229 }
1230
1231 DEFUN (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]",
1234 SHOW_STR
1235 IP_STR
1236 BGP_STR
1237 BGP_VPNVX_HELP_STR
1238 "Display information about all VPNv4/VPNv6 NLRIs\n"
1239 "Detailed information on TCP and BGP neighbor connections\n"
1240 "Neighbor to display information about\n"
1241 "Display the routes advertised to a BGP neighbor\n"
1242 JSON_STR)
1243 {
1244 int idx_ipv4 = 6;
1245 int ret;
1246 struct peer *peer;
1247 union sockunion su;
1248 u_char uj = use_json(argc, argv);
1249 afi_t afi;
1250 int idx = 0;
1251
1252 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1253 {
1254 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1255 if (ret < 0)
1256 {
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;
1268 }
1269 peer = peer_lookup (NULL, &su);
1270 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1271 {
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;
1283 }
1284
1285 return show_adj_route_vpn (vty, peer, NULL, uj, afi);
1286 }
1287 return CMD_SUCCESS;
1288 }
1289
1290 DEFUN (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]",
1293 SHOW_STR
1294 IP_STR
1295 BGP_STR
1296 BGP_VPNVX_HELP_STR
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"
1301 "Display the routes advertised to a BGP neighbor\n"
1302 JSON_STR)
1303 {
1304 int idx_ext_community = 5;
1305 int idx_ipv4 = 7;
1306 int ret;
1307 struct peer *peer;
1308 struct prefix_rd prd;
1309 union sockunion su;
1310 u_char uj = use_json(argc, argv);
1311 afi_t afi;
1312 int idx = 0;
1313
1314 if (argv_find_and_parse_vpnvx (argv, argc, &idx, &afi))
1315 {
1316 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1317 if (ret < 0)
1318 {
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;
1330 }
1331 peer = peer_lookup (NULL, &su);
1332 if (! peer || ! peer->afc[afi][SAFI_MPLS_VPN])
1333 {
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;
1345 }
1346
1347 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1348 if (! ret)
1349 {
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;
1361 }
1362
1363 return show_adj_route_vpn (vty, peer, &prd, uj, afi);
1364 }
1365 return CMD_SUCCESS;
1366 }
1367 #endif /* KEEP_OLD_VPN_COMMANDS */
1368
1369 void
1370 bgp_mplsvpn_init (void)
1371 {
1372 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
1373 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1374 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1375
1376 install_element (BGP_VPNV6_NODE, &vpnv6_network_cmd);
1377 install_element (BGP_VPNV6_NODE, &no_vpnv6_network_cmd);
1378
1379 install_element (VIEW_NODE, &show_bgp_ip_vpn_all_rd_cmd);
1380 install_element (VIEW_NODE, &show_ip_bgp_vpn_rd_cmd);
1381 #ifdef KEEP_OLD_VPN_COMMANDS
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);
1390 #endif /* KEEP_OLD_VPN_COMMANDS */
1391 }