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