]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.c
Merge remote-tracking branch 'osr_private_quagga/queue/osr/vtysh-generic' into vtysh...
[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 [ip] bgp ipv4 vpn [json]",
901 SHOW_STR
902 IP_STR
903 BGP_STR
904 "Address Family\n"
905 "Display VPN NLRI specific information\n"
906 JSON_STR)
907 {
908 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
909 }
910
911 DEFUN (show_bgp_ipv6_vpn,
912 show_bgp_ipv6_vpn_cmd,
913 "show [ip] bgp ipv6 vpn [json]",
914 SHOW_STR
915 IP_STR
916 BGP_STR
917 "Address Family\n"
918 "Display VPN NLRI specific information\n"
919 JSON_STR)
920 {
921 return bgp_show_mpls_vpn (vty, AFI_IP6, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
922 }
923
924 DEFUN (show_bgp_ipv4_vpn_rd,
925 show_bgp_ipv4_vpn_rd_cmd,
926 "show [ip] bgp ipv4 vpn rd ASN:nn_or_IP-address:nn [json]",
927 SHOW_STR
928 IP_STR
929 BGP_STR
930 "Address Family\n"
931 "Display VPN NLRI specific information\n"
932 "Display information for a route distinguisher\n"
933 "VPN Route Distinguisher\n"
934 JSON_STR)
935 {
936 int idx_ext_community = 5;
937 int ret;
938 struct prefix_rd prd;
939
940 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
941 if (! ret)
942 {
943 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
944 return CMD_WARNING;
945 }
946 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
947 }
948
949 DEFUN (show_bgp_ipv6_vpn_rd,
950 show_bgp_ipv6_vpn_rd_cmd,
951 "show [ip] bgp ipv6 vpn rd ASN:nn_or_IP-address:nn [json]",
952 SHOW_STR
953 IP_STR
954 BGP_STR
955 "Address Family\n"
956 "Display VPN NLRI specific information\n"
957 "Display information for a route distinguisher\n"
958 "VPN Route Distinguisher\n"
959 JSON_STR)
960 {
961 int idx_ext_community = 5;
962 int ret;
963 struct prefix_rd prd;
964
965 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
966 if (!ret)
967 {
968 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
969 return CMD_WARNING;
970 }
971
972 return bgp_show_mpls_vpn (vty, AFI_IP6, &prd, bgp_show_type_normal, NULL, 0, use_json (argc, argv));
973 }
974
975 DEFUN (show_ip_bgp_vpnv4_all,
976 show_ip_bgp_vpnv4_all_cmd,
977 "show [ip] bgp vpnv4 all",
978 SHOW_STR
979 IP_STR
980 BGP_STR
981 "Address Family\n"
982 "Display information about all VPNv4 NLRIs\n")
983 {
984 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 0, 0);
985 }
986
987 DEFUN (show_ip_bgp_vpnv4_rd,
988 show_ip_bgp_vpnv4_rd_cmd,
989 "show [ip] bgp vpnv4 rd ASN:nn_or_IP-address:nn",
990 SHOW_STR
991 IP_STR
992 BGP_STR
993 "Address Family\n"
994 "Display information for a route distinguisher\n"
995 "VPN Route Distinguisher\n")
996 {
997 int idx_ext_community = 5;
998 int ret;
999 struct prefix_rd prd;
1000
1001 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1002 if (! ret)
1003 {
1004 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1005 return CMD_WARNING;
1006 }
1007 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 0, 0);
1008 }
1009
1010 DEFUN (show_ip_bgp_vpnv4_all_tags,
1011 show_ip_bgp_vpnv4_all_tags_cmd,
1012 "show [ip] bgp vpnv4 all tags",
1013 SHOW_STR
1014 IP_STR
1015 BGP_STR
1016 "Address Family\n"
1017 "Display information about all VPNv4 NLRIs\n"
1018 "Display BGP tags for prefixes\n")
1019 {
1020 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_normal, NULL, 1, 0);
1021 }
1022
1023 DEFUN (show_ip_bgp_vpnv4_rd_tags,
1024 show_ip_bgp_vpnv4_rd_tags_cmd,
1025 "show [ip] bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
1026 SHOW_STR
1027 IP_STR
1028 BGP_STR
1029 "Address Family\n"
1030 "Display information for a route distinguisher\n"
1031 "VPN Route Distinguisher\n"
1032 "Display BGP tags for prefixes\n")
1033 {
1034 int idx_ext_community = 5;
1035 int ret;
1036 struct prefix_rd prd;
1037
1038 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1039 if (! ret)
1040 {
1041 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1042 return CMD_WARNING;
1043 }
1044 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_normal, NULL, 1, 0);
1045 }
1046
1047 DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
1048 show_ip_bgp_vpnv4_all_neighbor_routes_cmd,
1049 "show [ip] bgp vpnv4 all neighbors A.B.C.D routes [json]",
1050 SHOW_STR
1051 IP_STR
1052 BGP_STR
1053 "Address Family\n"
1054 "Display information about all VPNv4 NLRIs\n"
1055 "Detailed information on TCP and BGP neighbor connections\n"
1056 "Neighbor to display information about\n"
1057 "Display routes learned from neighbor\n"
1058 JSON_STR)
1059 {
1060 int idx_ipv4 = 6;
1061 union sockunion su;
1062 struct peer *peer;
1063 int ret;
1064 u_char uj = use_json(argc, argv);
1065
1066 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1067 if (ret < 0)
1068 {
1069 if (uj)
1070 {
1071 json_object *json_no = NULL;
1072 json_no = json_object_new_object();
1073 json_object_string_add(json_no, "warning", "Malformed address");
1074 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1075 json_object_free(json_no);
1076 }
1077 else
1078 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
1079 return CMD_WARNING;
1080 }
1081
1082 peer = peer_lookup (NULL, &su);
1083 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1084 {
1085 if (uj)
1086 {
1087 json_object *json_no = NULL;
1088 json_no = json_object_new_object();
1089 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1090 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1091 json_object_free(json_no);
1092 }
1093 else
1094 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1095 return CMD_WARNING;
1096 }
1097
1098 return bgp_show_mpls_vpn (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0, uj);
1099 }
1100
1101 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
1102 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd,
1103 "show [ip] bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
1104 SHOW_STR
1105 IP_STR
1106 BGP_STR
1107 "Address Family\n"
1108 "Display information for a route distinguisher\n"
1109 "VPN Route Distinguisher\n"
1110 "Detailed information on TCP and BGP neighbor connections\n"
1111 "Neighbor to display information about\n"
1112 "Display routes learned from neighbor\n"
1113 JSON_STR)
1114 {
1115 int idx_ext_community = 5;
1116 int idx_ipv4 = 7;
1117 int ret;
1118 union sockunion su;
1119 struct peer *peer;
1120 struct prefix_rd prd;
1121 u_char uj = use_json(argc, argv);
1122
1123 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1124 if (! ret)
1125 {
1126 if (uj)
1127 {
1128 json_object *json_no = NULL;
1129 json_no = json_object_new_object();
1130 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1131 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1132 json_object_free(json_no);
1133 }
1134 else
1135 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1136 return CMD_WARNING;
1137 }
1138
1139 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1140 if (ret < 0)
1141 {
1142 if (uj)
1143 {
1144 json_object *json_no = NULL;
1145 json_no = json_object_new_object();
1146 json_object_string_add(json_no, "warning", "Malformed address");
1147 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1148 json_object_free(json_no);
1149 }
1150 else
1151 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1152 return CMD_WARNING;
1153 }
1154
1155 peer = peer_lookup (NULL, &su);
1156 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1157 {
1158 if (uj)
1159 {
1160 json_object *json_no = NULL;
1161 json_no = json_object_new_object();
1162 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1163 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1164 json_object_free(json_no);
1165 }
1166 else
1167 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1168 return CMD_WARNING;
1169 }
1170
1171 return bgp_show_mpls_vpn (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0, uj);
1172 }
1173
1174 DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
1175 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd,
1176 "show [ip] bgp vpnv4 all neighbors A.B.C.D advertised-routes [json]",
1177 SHOW_STR
1178 IP_STR
1179 BGP_STR
1180 "Address Family\n"
1181 "Display information about all VPNv4 NLRIs\n"
1182 "Detailed information on TCP and BGP neighbor connections\n"
1183 "Neighbor to display information about\n"
1184 "Display the routes advertised to a BGP neighbor\n"
1185 JSON_STR)
1186 {
1187 int idx_ipv4 = 6;
1188 int ret;
1189 struct peer *peer;
1190 union sockunion su;
1191 u_char uj = use_json(argc, argv);
1192
1193 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1194 if (ret < 0)
1195 {
1196 if (uj)
1197 {
1198 json_object *json_no = NULL;
1199 json_no = json_object_new_object();
1200 json_object_string_add(json_no, "warning", "Malformed address");
1201 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1202 json_object_free(json_no);
1203 }
1204 else
1205 vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE);
1206 return CMD_WARNING;
1207 }
1208 peer = peer_lookup (NULL, &su);
1209 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1210 {
1211 if (uj)
1212 {
1213 json_object *json_no = NULL;
1214 json_no = json_object_new_object();
1215 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1216 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1217 json_object_free(json_no);
1218 }
1219 else
1220 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1221 return CMD_WARNING;
1222 }
1223
1224 return show_adj_route_vpn (vty, peer, NULL, uj);
1225 }
1226
1227 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
1228 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd,
1229 "show [ip] bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1230 SHOW_STR
1231 IP_STR
1232 BGP_STR
1233 "Address Family\n"
1234 "Display information for a route distinguisher\n"
1235 "VPN Route Distinguisher\n"
1236 "Detailed information on TCP and BGP neighbor connections\n"
1237 "Neighbor to display information about\n"
1238 "Display the routes advertised to a BGP neighbor\n"
1239 JSON_STR)
1240 {
1241 int idx_ext_community = 5;
1242 int idx_ipv4 = 7;
1243 int ret;
1244 struct peer *peer;
1245 struct prefix_rd prd;
1246 union sockunion su;
1247 u_char uj = use_json(argc, argv);
1248
1249 ret = str2sockunion (argv[idx_ipv4]->arg, &su);
1250 if (ret < 0)
1251 {
1252 if (uj)
1253 {
1254 json_object *json_no = NULL;
1255 json_no = json_object_new_object();
1256 json_object_string_add(json_no, "warning", "Malformed address");
1257 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1258 json_object_free(json_no);
1259 }
1260 else
1261 vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE);
1262 return CMD_WARNING;
1263 }
1264 peer = peer_lookup (NULL, &su);
1265 if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN])
1266 {
1267 if (uj)
1268 {
1269 json_object *json_no = NULL;
1270 json_no = json_object_new_object();
1271 json_object_string_add(json_no, "warning", "No such neighbor or address family");
1272 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1273 json_object_free(json_no);
1274 }
1275 else
1276 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
1277 return CMD_WARNING;
1278 }
1279
1280 ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd);
1281 if (! ret)
1282 {
1283 if (uj)
1284 {
1285 json_object *json_no = NULL;
1286 json_no = json_object_new_object();
1287 json_object_string_add(json_no, "warning", "Malformed Route Distinguisher");
1288 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
1289 json_object_free(json_no);
1290 }
1291 else
1292 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
1293 return CMD_WARNING;
1294 }
1295
1296 return show_adj_route_vpn (vty, peer, &prd, uj);
1297 }
1298
1299 void
1300 bgp_mplsvpn_init (void)
1301 {
1302 install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
1303 install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
1304 install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
1305
1306 install_element (VIEW_NODE, &show_bgp_ipv4_vpn_cmd);
1307 install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_cmd);
1308 install_element (VIEW_NODE, &show_bgp_ipv6_vpn_cmd);
1309 install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_cmd);
1310 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_cmd);
1311 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_cmd);
1312 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_tags_cmd);
1313 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_tags_cmd);
1314 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd);
1315 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd);
1316 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd);
1317 install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd);
1318 }