2 Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4 This file is part of GNU Zebra.
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
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.
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
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"
41 #include "bgpd/rfapi/rfapi_backend.h"
45 decode_rd_type (u_char
*pnt
)
49 v
= ((u_int16_t
) *pnt
++ << 8);
52 * VNC L2 stores LHI in lower byte, so omit it
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
;
64 encode_rd_type (u_int16_t v
, u_char
*pnt
)
66 *((u_int16_t
*)pnt
) = htons(v
);
70 decode_label (u_char
*pnt
)
74 l
= ((u_int32_t
) *pnt
++ << 12);
75 l
|= (u_int32_t
) *pnt
++ << 4;
76 l
|= (u_int32_t
) ((*pnt
& 0xf0) >> 4);
81 encode_label(u_int32_t label
,
86 *pnt
++ = (label
>>12) & 0xff;
87 *pnt
++ = (label
>>4) & 0xff;
88 *pnt
++ = ((label
<<4)+1) & 0xff; /* S=1 */
91 /* type == RD_TYPE_AS */
93 decode_rd_as (u_char
*pnt
, struct rd_as
*rd_as
)
95 rd_as
->as
= (u_int16_t
) *pnt
++ << 8;
96 rd_as
->as
|= (u_int16_t
) *pnt
++;
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
;
104 /* type == RD_TYPE_AS4 */
106 decode_rd_as4 (u_char
*pnt
, struct rd_as
*rd_as
)
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
++;
113 rd_as
->val
= ((u_int16_t
) *pnt
++ << 8);
114 rd_as
->val
|= (u_int16_t
) *pnt
;
117 /* type == RD_TYPE_IP */
119 decode_rd_ip (u_char
*pnt
, struct rd_ip
*rd_ip
)
121 memcpy (&rd_ip
->ip
, pnt
, 4);
124 rd_ip
->val
= ((u_int16_t
) *pnt
++ << 8);
125 rd_ip
->val
|= (u_int16_t
) *pnt
;
129 /* type == RD_TYPE_VNC_ETH */
131 decode_rd_vnc_eth (u_char
*pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
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
);
140 bgp_nlri_parse_vpn (struct peer
*peer
, struct attr
*attr
,
141 struct bgp_nlri
*packet
)
151 struct prefix_rd prd
;
156 u_int32_t addpath_id
;
158 /* Check peer status. */
159 if (peer
->status
!= Established
)
163 prd
.family
= AF_UNSPEC
;
167 lim
= pnt
+ packet
->length
;
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
));
175 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
176 for (; pnt
< lim
; pnt
+= psize
)
178 /* Clear prefix structure. */
179 memset (&p
, 0, sizeof (struct prefix
));
184 /* When packet overflow occurs return immediately. */
185 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
188 addpath_id
= ntohl(*((uint32_t*) pnt
));
189 pnt
+= BGP_ADDPATH_ID_LEN
;
192 /* Fetch prefix length. */
194 p
.family
= afi2family (packet
->afi
);
195 psize
= PSIZE (prefixlen
);
197 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
*8)
199 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
200 peer
->host
, prefixlen
);
204 /* sanity check against packet data */
205 if ((pnt
+ psize
) > lim
)
207 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
209 prefixlen
, (uint
)(lim
-pnt
));
213 /* sanity check against storage for the IP address portion */
214 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
) sizeof(p
.u
))
216 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
218 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8, sizeof(p
.u
));
222 /* Sanity check against max bitlen of the address family */
223 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen (&p
))
225 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
227 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8,
228 p
.family
, prefix_blen (&p
));
232 /* Copyr label to prefix. */
235 /* Copy routing distinguisher to rd. */
236 memcpy (&prd
.val
, pnt
+ 3, 8);
238 /* Decode RD type. */
239 type
= decode_rd_type (pnt
+ 3);
244 decode_rd_as (pnt
+ 5, &rd_as
);
248 decode_rd_as4 (pnt
+ 5, &rd_as
);
252 decode_rd_ip (pnt
+ 5, &rd_ip
);
256 case RD_TYPE_VNC_ETH
:
261 zlog_err ("Unknown RD type %d", type
);
262 break; /* just report */
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
);
271 bgp_update (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
272 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
, 0);
276 bgp_withdraw (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
277 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
);
280 /* Packet length consistency check. */
283 zlog_err ("%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
284 peer
->host
, lim
- pnt
);
289 #undef VPN_PREFIXLEN_MIN_BYTES
293 str2prefix_rd (const char *str
, struct prefix_rd
*prd
)
295 int ret
; /* ret of called functions */
296 int lret
; /* local ret, of this func */
299 struct stream
*s
= NULL
;
305 prd
->family
= AF_UNSPEC
;
309 p
= strchr (str
, ':');
313 if (! all_digit (p
+ 1))
316 half
= XMALLOC (MTYPE_TMP
, (p
- str
) + 1);
317 memcpy (half
, str
, (p
- str
));
318 half
[p
- str
] = '\0';
320 p2
= strchr (str
, '.');
324 unsigned long as_val
;
326 if (! all_digit (half
))
332 stream_putw (s
, RD_TYPE_AS4
);
333 stream_putl (s
, as_val
);
334 stream_putw (s
, atol (p
+ 1));
338 stream_putw (s
, RD_TYPE_AS
);
339 stream_putw (s
, as_val
);
340 stream_putl (s
, atol (p
+ 1));
345 ret
= inet_aton (half
, &addr
);
349 stream_putw (s
, RD_TYPE_IP
);
350 stream_put_in_addr (s
, &addr
);
351 stream_putw (s
, atol (p
+ 1));
353 memcpy (prd
->val
, s
->data
, 8);
360 XFREE(MTYPE_TMP
, half
);
365 str2tag (const char *str
, u_char
*tag
)
375 l
= strtoul (str
, &endptr
, 10);
377 if (*endptr
!= '\0' || errno
|| l
> UINT32_MAX
)
382 tag
[0] = (u_char
)(t
>> 12);
383 tag
[1] = (u_char
)(t
>> 4);
384 tag
[2] = (u_char
)(t
<< 4);
390 prefix_rd2str (struct prefix_rd
*prd
, char *buf
, size_t size
)
397 if (size
< RD_ADDRSTRLEN
)
402 type
= decode_rd_type (pnt
);
404 if (type
== RD_TYPE_AS
)
406 decode_rd_as (pnt
+ 2, &rd_as
);
407 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
410 else if (type
== RD_TYPE_AS4
)
412 decode_rd_as4 (pnt
+ 2, &rd_as
);
413 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
416 else if (type
== RD_TYPE_IP
)
418 decode_rd_ip (pnt
+ 2, &rd_ip
);
419 snprintf (buf
, size
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
423 else if (type
== RD_TYPE_VNC_ETH
)
425 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
427 *(pnt
+2), /* MAC[0] */
440 /* For testing purpose, static route of MPLS-VPN. */
441 DEFUN (vpnv4_network
,
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"
451 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[0], argv
[1], argv
[2], NULL
);
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"
466 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[0], argv
[1], argv
[2], argv
[3]);
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",
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"
481 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[0], argv
[1], argv
[2]);
485 show_adj_route_vpn (struct vty
*vty
, struct peer
*peer
, afi_t afi
, struct prefix_rd
*prd
, u_char use_json
)
488 struct bgp_table
*table
;
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
;
501 bgp
= bgp_get_default ();
505 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
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();
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");
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", "?");
528 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
529 rn
= bgp_route_next (rn
))
531 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
534 if ((table
= rn
->info
) != NULL
)
537 json_array
= json_object_new_array();
543 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
545 if ((attr
= rm
->info
) != NULL
)
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
);
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",
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
);
573 struct rd_ip rd_ip
= {0};
575 struct rd_vnc_eth rd_vnc_eth
= {0};
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
);
591 else if (type
== RD_TYPE_VNC_ETH
)
592 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
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
);
606 vty_out (vty
, "Route Distinguisher: ");
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
);
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]);
624 vty_out (vty
, "%s", VTY_NEWLINE
);
628 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_MPLS_VPN
, use_json
, json_array
);
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
);
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
);
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
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
)
672 struct bgp_table
*table
;
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
;
689 bgp
= bgp_get_default ();
693 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
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();
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");
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", "?");
717 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
))
719 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
723 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
; rn
= bgp_route_next (rn
))
725 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
728 if ((table
= rn
->info
) != NULL
)
732 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
736 json_array
= json_object_new_array();
740 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
742 if (type
== bgp_show_type_neighbor
)
744 union sockunion
*su
= output_arg
;
746 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
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
);
764 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
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",
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
);
783 struct rd_ip rd_ip
= {0};
785 struct rd_vnc_eth rd_vnc_eth
= {0};
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
);
801 else if (type
== RD_TYPE_VNC_ETH
)
802 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
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
);
816 vty_out (vty
, "Route Distinguisher: ");
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
);
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]);
833 vty_out (vty
, "%s", VTY_NEWLINE
);
838 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
840 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
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
);
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
);
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
);
875 if (output_count
== 0)
876 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
878 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
879 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
885 DEFUN (show_bgp_ivp4_vpn
,
886 show_bgp_ipv4_vpn_cmd
,
887 "show bgp ipv4 vpn {json}",
891 "Display VPN NLRI specific information\n")
893 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
896 DEFUN (show_bgp_ipv6_vpn
,
897 show_bgp_ipv6_vpn_cmd
,
898 "show bgp ipv6 vpn {json}",
902 "Display VPN NLRI specific information\n")
904 return bgp_show_mpls_vpn (vty
, AFI_IP6
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
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}",
913 "Display VPN NLRI specific information\n"
914 "Display information for a route distinguisher\n"
915 "VPN Route Distinguisher\n"
919 struct prefix_rd prd
;
921 ret
= str2prefix_rd (argv
[0], &prd
);
924 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
927 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
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}",
936 "Display VPN NLRI specific information\n"
937 "Display information for a route distinguisher\n"
938 "VPN Route Distinguisher\n"
942 struct prefix_rd prd
;
944 ret
= str2prefix_rd (argv
[0], &prd
);
947 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
951 return bgp_show_mpls_vpn (vty
, AFI_IP6
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
954 DEFUN (show_bgp_ip_vpn_all
,
955 show_bgp_ip_vpn_all_cmd
,
956 "show bgp "BGP_AFI_CMD_STR
" vpn all",
961 "Display information about all VPN NLRIs\n")
963 return bgp_show_mpls_vpn (vty
, bgp_vty_afi_from_arg(argv
[0]), NULL
, bgp_show_type_normal
, NULL
, 0, 0);
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",
973 "Display information for a route distinguisher\n"
974 "VPN Route Distinguisher\n")
977 struct prefix_rd prd
;
979 ret
= str2prefix_rd (argv
[0], &prd
);
982 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
985 return bgp_show_mpls_vpn (vty
, bgp_vty_afi_from_arg(argv
[0]), &prd
, bgp_show_type_normal
, NULL
, 0, 0);
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",
995 "Display information about all VPNv4 NLRIs\n"
996 "Display BGP tags for prefixes\n")
998 return bgp_show_mpls_vpn (vty
, bgp_vty_afi_from_arg(argv
[0]), NULL
, bgp_show_type_normal
, NULL
, 1, 0);
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",
1008 "Display information for a route distinguisher\n"
1009 "VPN Route Distinguisher\n"
1010 "Display BGP tags for prefixes\n")
1013 struct prefix_rd prd
;
1015 ret
= str2prefix_rd (argv
[1], &prd
);
1018 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1021 return bgp_show_mpls_vpn (vty
, bgp_vty_afi_from_arg(argv
[0]), &prd
, bgp_show_type_normal
, NULL
, 1, 0);
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}",
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")
1041 u_char uj
= use_json(argc
, argv
);
1042 afi_t afi
= bgp_vty_afi_from_arg(argv
[0]);
1044 ret
= str2sockunion (argv
[1], &su
);
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
);
1056 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1060 peer
= peer_lookup (NULL
, &su
);
1061 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
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
);
1072 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1076 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
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}",
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")
1097 struct prefix_rd prd
;
1098 u_char uj
= use_json(argc
, argv
);
1099 afi_t afi
= bgp_vty_afi_from_arg(argv
[0]);
1101 ret
= str2prefix_rd (argv
[1], &prd
);
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
);
1113 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1117 ret
= str2sockunion (argv
[2], &su
);
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
);
1129 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1133 peer
= peer_lookup (NULL
, &su
);
1134 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
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
);
1145 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1149 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
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}",
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")
1169 u_char uj
= use_json(argc
, argv
);
1170 afi_t afi
= bgp_vty_afi_from_arg(argv
[0]);
1172 ret
= str2sockunion (argv
[1], &su
);
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
);
1184 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1187 peer
= peer_lookup (NULL
, &su
);
1188 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
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
);
1199 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1203 return show_adj_route_vpn (vty
, peer
, afi
, NULL
, uj
);
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}",
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")
1223 struct prefix_rd prd
;
1225 u_char uj
= use_json(argc
, argv
);
1226 afi_t afi
= bgp_vty_afi_from_arg(argv
[0]);
1228 ret
= str2sockunion (argv
[2], &su
);
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
);
1240 vty_out (vty
, "Malformed address: %s%s", argv
[2], VTY_NEWLINE
);
1243 peer
= peer_lookup (NULL
, &su
);
1244 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
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
);
1255 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1259 ret
= str2prefix_rd (argv
[1], &prd
);
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
);
1271 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1275 return show_adj_route_vpn (vty
, peer
, afi
, &prd
, uj
);
1279 bgp_mplsvpn_init (void)
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
);
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
);