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