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"
40 #include "bgpd/rfapi/rfapi_backend.h"
44 decode_rd_type (u_char
*pnt
)
48 v
= ((u_int16_t
) *pnt
++ << 8);
51 * VNC L2 stores LHI in lower byte, so omit it
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
;
63 encode_rd_type (u_int16_t v
, u_char
*pnt
)
65 *((u_int16_t
*)pnt
) = htons(v
);
69 decode_label (u_char
*pnt
)
73 l
= ((u_int32_t
) *pnt
++ << 12);
74 l
|= (u_int32_t
) *pnt
++ << 4;
75 l
|= (u_int32_t
) ((*pnt
& 0xf0) >> 4);
80 encode_label(u_int32_t label
,
85 *pnt
++ = (label
>>12) & 0xff;
86 *pnt
++ = (label
>>4) & 0xff;
87 *pnt
++ = ((label
<<4)+1) & 0xff; /* S=1 */
90 /* type == RD_TYPE_AS */
92 decode_rd_as (u_char
*pnt
, struct rd_as
*rd_as
)
94 rd_as
->as
= (u_int16_t
) *pnt
++ << 8;
95 rd_as
->as
|= (u_int16_t
) *pnt
++;
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
;
103 /* type == RD_TYPE_AS4 */
105 decode_rd_as4 (u_char
*pnt
, struct rd_as
*rd_as
)
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
++;
112 rd_as
->val
= ((u_int16_t
) *pnt
++ << 8);
113 rd_as
->val
|= (u_int16_t
) *pnt
;
116 /* type == RD_TYPE_IP */
118 decode_rd_ip (u_char
*pnt
, struct rd_ip
*rd_ip
)
120 memcpy (&rd_ip
->ip
, pnt
, 4);
123 rd_ip
->val
= ((u_int16_t
) *pnt
++ << 8);
124 rd_ip
->val
|= (u_int16_t
) *pnt
;
128 /* type == RD_TYPE_VNC_ETH */
130 decode_rd_vnc_eth (u_char
*pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
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
);
139 bgp_nlri_parse_vpn (struct peer
*peer
, struct attr
*attr
,
140 struct bgp_nlri
*packet
)
150 struct prefix_rd prd
;
155 u_int32_t addpath_id
;
160 /* Check peer status. */
161 if (peer
->status
!= Established
)
165 prd
.family
= AF_UNSPEC
;
169 lim
= pnt
+ packet
->length
;
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
));
177 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
178 for (; pnt
< lim
; pnt
+= psize
)
180 /* Clear prefix structure. */
181 memset (&p
, 0, sizeof (struct prefix
));
186 /* When packet overflow occurs return immediately. */
187 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
190 addpath_id
= ntohl(*((uint32_t*) pnt
));
191 pnt
+= BGP_ADDPATH_ID_LEN
;
194 /* Fetch prefix length. */
196 p
.family
= afi2family (packet
->afi
);
197 psize
= PSIZE (prefixlen
);
199 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
*8)
201 zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d less than VPNv4 min length)",
202 peer
->host
, prefixlen
);
206 /* sanity check against packet data */
207 if ((pnt
+ psize
) > lim
)
209 zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d exceeds packet size %u)",
211 prefixlen
, (uint
)(lim
-pnt
));
215 /* sanity check against storage for the IP address portion */
216 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
) sizeof(p
.u
))
218 zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds storage size %zu)",
220 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8, sizeof(p
.u
));
224 /* Sanity check against max bitlen of the address family */
225 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen (&p
))
227 zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds family (%u) max byte len %u)",
229 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8,
230 p
.family
, prefix_blen (&p
));
235 label
= decode_label (pnt
);
238 /* Copyr label to prefix. */
241 /* Copy routing distinguisher to rd. */
242 memcpy (&prd
.val
, pnt
+ 3, 8);
244 /* Decode RD type. */
245 type
= decode_rd_type (pnt
+ 3);
250 decode_rd_as (pnt
+ 5, &rd_as
);
254 decode_rd_as4 (pnt
+ 5, &rd_as
);
258 decode_rd_ip (pnt
+ 5, &rd_ip
);
262 case RD_TYPE_VNC_ETH
:
267 zlog_err ("Unknown RD type %d", type
);
268 break; /* just report */
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
);
277 bgp_update (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
278 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
, 0);
280 rfapiProcessUpdate(peer
, NULL
, &p
, &prd
, attr
, packet
->afi
,
281 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
288 rfapiProcessWithdraw(peer
, NULL
, &p
, &prd
, attr
, packet
->afi
,
289 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
, 0);
291 bgp_withdraw (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
292 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
);
295 /* Packet length consistency check. */
298 zlog_err ("%s [Error] Update packet error / VPNv4 (%zu data remaining after parsing)",
299 peer
->host
, lim
- pnt
);
304 #undef VPN_PREFIXLEN_MIN_BYTES
308 str2prefix_rd (const char *str
, struct prefix_rd
*prd
)
310 int ret
; /* ret of called functions */
311 int lret
; /* local ret, of this func */
314 struct stream
*s
= NULL
;
320 prd
->family
= AF_UNSPEC
;
324 p
= strchr (str
, ':');
328 if (! all_digit (p
+ 1))
331 half
= XMALLOC (MTYPE_TMP
, (p
- str
) + 1);
332 memcpy (half
, str
, (p
- str
));
333 half
[p
- str
] = '\0';
335 p2
= strchr (str
, '.');
339 if (! all_digit (half
))
342 stream_putw (s
, RD_TYPE_AS
);
343 stream_putw (s
, atoi (half
));
344 stream_putl (s
, atol (p
+ 1));
348 ret
= inet_aton (half
, &addr
);
352 stream_putw (s
, RD_TYPE_IP
);
353 stream_put_in_addr (s
, &addr
);
354 stream_putw (s
, atol (p
+ 1));
356 memcpy (prd
->val
, s
->data
, 8);
363 XFREE(MTYPE_TMP
, half
);
368 str2tag (const char *str
, u_char
*tag
)
378 l
= strtoul (str
, &endptr
, 10);
380 if (*endptr
!= '\0' || errno
|| l
> UINT32_MAX
)
385 tag
[0] = (u_char
)(t
>> 12);
386 tag
[1] = (u_char
)(t
>> 4);
387 tag
[2] = (u_char
)(t
<< 4);
393 prefix_rd2str (struct prefix_rd
*prd
, char *buf
, size_t size
)
400 if (size
< RD_ADDRSTRLEN
)
405 type
= decode_rd_type (pnt
);
407 if (type
== RD_TYPE_AS
)
409 decode_rd_as (pnt
+ 2, &rd_as
);
410 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
413 else if (type
== RD_TYPE_AS4
)
415 decode_rd_as4 (pnt
+ 2, &rd_as
);
416 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
419 else if (type
== RD_TYPE_IP
)
421 decode_rd_ip (pnt
+ 2, &rd_ip
);
422 snprintf (buf
, size
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
426 else if (type
== RD_TYPE_VNC_ETH
)
428 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
430 *(pnt
+2), /* MAC[0] */
443 /* For testing purpose, static route of MPLS-VPN. */
444 DEFUN (vpnv4_network
,
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 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
449 "Specify Route Distinguisher\n"
450 "VPN Route Distinguisher\n"
454 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[0], argv
[1], argv
[2], NULL
);
457 DEFUN (vpnv4_network_route_map
,
458 vpnv4_network_route_map_cmd
,
459 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
460 "Specify a network to announce via BGP\n"
461 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
462 "Specify Route Distinguisher\n"
463 "VPN Route Distinguisher\n"
469 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[0], argv
[1], argv
[2], argv
[3]);
472 /* For testing purpose, static route of MPLS-VPN. */
473 DEFUN (no_vpnv4_network
,
474 no_vpnv4_network_cmd
,
475 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
477 "Specify a network to announce via BGP\n"
478 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
479 "Specify Route Distinguisher\n"
480 "VPN Route Distinguisher\n"
484 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[0], argv
[1], argv
[2]);
488 show_adj_route_vpn (struct vty
*vty
, struct peer
*peer
, struct prefix_rd
*prd
, u_char use_json
)
491 struct bgp_table
*table
;
497 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
498 json_object
*json
= NULL
;
499 json_object
*json_scode
= NULL
;
500 json_object
*json_ocode
= NULL
;
501 json_object
*json_routes
= NULL
;
502 json_object
*json_array
= NULL
;
504 bgp
= bgp_get_default ();
508 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
514 json_scode
= json_object_new_object();
515 json_ocode
= json_object_new_object();
516 json_routes
= json_object_new_object();
517 json
= json_object_new_object();
519 json_object_string_add(json_scode
, "suppressed", "s");
520 json_object_string_add(json_scode
, "damped", "d");
521 json_object_string_add(json_scode
, "history", "h");
522 json_object_string_add(json_scode
, "valid", "*");
523 json_object_string_add(json_scode
, "best", ">");
524 json_object_string_add(json_scode
, "internal", "i");
526 json_object_string_add(json_ocode
, "igp", "i");
527 json_object_string_add(json_ocode
, "egp", "e");
528 json_object_string_add(json_ocode
, "incomplete", "?");
531 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][SAFI_MPLS_VPN
]); rn
;
532 rn
= bgp_route_next (rn
))
534 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
537 if ((table
= rn
->info
) != NULL
)
540 json_array
= json_object_new_array();
546 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
548 if ((attr
= rm
->info
) != NULL
)
554 json_object_int_add(json
, "bgpTableVersion", 0);
555 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
556 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
557 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
561 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
562 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
563 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
565 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
566 VTY_NEWLINE
, VTY_NEWLINE
);
567 vty_out (vty
, v4_header
, VTY_NEWLINE
);
576 struct rd_ip rd_ip
= {0};
578 struct rd_vnc_eth rd_vnc_eth
;
584 /* Decode RD type. */
585 type
= decode_rd_type (pnt
);
586 /* Decode RD value. */
587 if (type
== RD_TYPE_AS
)
588 decode_rd_as (pnt
+ 2, &rd_as
);
589 else if (type
== RD_TYPE_AS4
)
590 decode_rd_as4 (pnt
+ 2, &rd_as
);
591 else if (type
== RD_TYPE_IP
)
592 decode_rd_ip (pnt
+ 2, &rd_ip
);
594 else if (type
== RD_TYPE_VNC_ETH
)
595 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
601 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
602 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
603 else if (type
== RD_TYPE_IP
)
604 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
605 json_object_string_add(json_routes
, "routeDistinguisher", buffer
);
609 vty_out (vty
, "Route Distinguisher: ");
611 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
612 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
613 else if (type
== RD_TYPE_IP
)
614 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
616 else if (type
== RD_TYPE_VNC_ETH
)
617 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
618 rd_vnc_eth
.local_nve_id
,
619 rd_vnc_eth
.macaddr
.octet
[0],
620 rd_vnc_eth
.macaddr
.octet
[1],
621 rd_vnc_eth
.macaddr
.octet
[2],
622 rd_vnc_eth
.macaddr
.octet
[3],
623 rd_vnc_eth
.macaddr
.octet
[4],
624 rd_vnc_eth
.macaddr
.octet
[5]);
627 vty_out (vty
, "%s", VTY_NEWLINE
);
631 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_MPLS_VPN
, use_json
, json_array
);
640 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
641 json_object_object_add(json_routes
, buf_a
, json_array
);
647 json_object_object_add(json
, "routes", json_routes
);
648 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
649 json_object_free(json
);
656 bgp_show_type_normal
,
657 bgp_show_type_regexp
,
658 bgp_show_type_prefix_list
,
659 bgp_show_type_filter_list
,
660 bgp_show_type_neighbor
,
661 bgp_show_type_cidr_only
,
662 bgp_show_type_prefix_longer
,
663 bgp_show_type_community_all
,
664 bgp_show_type_community
,
665 bgp_show_type_community_exact
,
666 bgp_show_type_community_list
,
667 bgp_show_type_community_list_exact
671 bgp_show_mpls_vpn (struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
672 enum bgp_show_type type
, void *output_arg
, int tags
, u_char use_json
)
675 struct bgp_table
*table
;
681 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
682 char v4_header_tag
[] = " Network Next Hop In tag/Out tag%s";
683 unsigned long output_count
= 0;
684 unsigned long total_count
= 0;
685 json_object
*json
= NULL
;
686 json_object
*json_mroute
= NULL
;
687 json_object
*json_nroute
= NULL
;
688 json_object
*json_array
= NULL
;
689 json_object
*json_scode
= NULL
;
690 json_object
*json_ocode
= NULL
;
692 bgp
= bgp_get_default ();
696 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
702 json_scode
= json_object_new_object();
703 json_ocode
= json_object_new_object();
704 json
= json_object_new_object();
705 json_mroute
= json_object_new_object();
706 json_nroute
= json_object_new_object();
708 json_object_string_add(json_scode
, "suppressed", "s");
709 json_object_string_add(json_scode
, "damped", "d");
710 json_object_string_add(json_scode
, "history", "h");
711 json_object_string_add(json_scode
, "valid", "*");
712 json_object_string_add(json_scode
, "best", ">");
713 json_object_string_add(json_scode
, "internal", "i");
715 json_object_string_add(json_ocode
, "igp", "i");
716 json_object_string_add(json_ocode
, "egp", "e");
717 json_object_string_add(json_ocode
, "incomplete", "?");
720 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
))
722 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
726 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
; rn
= bgp_route_next (rn
))
728 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
731 if ((table
= rn
->info
) != NULL
)
735 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
739 json_array
= json_object_new_array();
743 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
745 if (type
== bgp_show_type_neighbor
)
747 union sockunion
*su
= output_arg
;
749 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
758 json_object_int_add(json
, "bgpTableVersion", 0);
759 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
760 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
761 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
767 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
770 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
771 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
772 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
774 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
775 VTY_NEWLINE
, VTY_NEWLINE
);
776 vty_out (vty
, v4_header
, VTY_NEWLINE
);
786 struct rd_ip rd_ip
= {0};
788 struct rd_vnc_eth rd_vnc_eth
;
794 /* Decode RD type. */
795 type
= decode_rd_type (pnt
);
796 /* Decode RD value. */
797 if (type
== RD_TYPE_AS
)
798 decode_rd_as (pnt
+ 2, &rd_as
);
799 else if (type
== RD_TYPE_AS4
)
800 decode_rd_as4 (pnt
+ 2, &rd_as
);
801 else if (type
== RD_TYPE_IP
)
802 decode_rd_ip (pnt
+ 2, &rd_ip
);
804 else if (type
== RD_TYPE_VNC_ETH
)
805 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
811 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
812 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
813 else if (type
== RD_TYPE_IP
)
814 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
815 json_object_string_add(json_nroute
, "routeDistinguisher", buffer
);
819 vty_out (vty
, "Route Distinguisher: ");
821 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
822 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
823 else if (type
== RD_TYPE_IP
)
824 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
826 else if (type
== RD_TYPE_VNC_ETH
)
827 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
828 rd_vnc_eth
.local_nve_id
,
829 rd_vnc_eth
.macaddr
.octet
[0],
830 rd_vnc_eth
.macaddr
.octet
[1],
831 rd_vnc_eth
.macaddr
.octet
[2],
832 rd_vnc_eth
.macaddr
.octet
[3],
833 rd_vnc_eth
.macaddr
.octet
[4],
834 rd_vnc_eth
.macaddr
.octet
[5]);
836 vty_out (vty
, "%s", VTY_NEWLINE
);
841 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
843 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
853 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
854 json_object_object_add(json_mroute
, buf_a
, json_array
);
864 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
865 json_object_object_add(json_nroute
, buf_a
, json_mroute
);
872 json_object_object_add(json
, "routes", json_nroute
);
873 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
874 json_object_free(json
);
878 if (output_count
== 0)
879 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
881 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
882 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
888 DEFUN (show_bgp_ivp4_vpn
,
889 show_bgp_ipv4_vpn_cmd
,
890 "show bgp ipv4 vpn {json}",
894 "Display VPN NLRI specific information\n")
896 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
899 DEFUN (show_bgp_ipv6_vpn
,
900 show_bgp_ipv6_vpn_cmd
,
901 "show bgp ipv6 vpn {json}",
905 "Display VPN NLRI specific information\n")
907 return bgp_show_mpls_vpn (vty
, AFI_IP6
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
910 DEFUN (show_bgp_ipv4_vpn_rd
,
911 show_bgp_ipv4_vpn_rd_cmd
,
912 "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn {json}",
916 "Display VPN NLRI specific information\n"
917 "Display information for a route distinguisher\n"
918 "VPN Route Distinguisher\n"
922 struct prefix_rd prd
;
924 ret
= str2prefix_rd (argv
[0], &prd
);
927 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
930 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
933 DEFUN (show_bgp_ipv6_vpn_rd
,
934 show_bgp_ipv6_vpn_rd_cmd
,
935 "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn {json}",
939 "Display VPN NLRI specific information\n"
940 "Display information for a route distinguisher\n"
941 "VPN Route Distinguisher\n"
945 struct prefix_rd prd
;
947 ret
= str2prefix_rd (argv
[0], &prd
);
950 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
954 return bgp_show_mpls_vpn (vty
, AFI_IP6
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
957 DEFUN (show_ip_bgp_vpnv4_all
,
958 show_ip_bgp_vpnv4_all_cmd
,
959 "show ip bgp vpnv4 all",
963 "Display VPNv4 NLRI specific information\n"
964 "Display information about all VPNv4 NLRIs\n")
966 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
969 DEFUN (show_ip_bgp_vpnv4_rd
,
970 show_ip_bgp_vpnv4_rd_cmd
,
971 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
975 "Display VPNv4 NLRI specific information\n"
976 "Display information for a route distinguisher\n"
977 "VPN Route Distinguisher\n")
980 struct prefix_rd prd
;
982 ret
= str2prefix_rd (argv
[0], &prd
);
985 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
988 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, 0);
991 DEFUN (show_ip_bgp_vpnv4_all_tags
,
992 show_ip_bgp_vpnv4_all_tags_cmd
,
993 "show ip bgp vpnv4 all tags",
997 "Display VPNv4 NLRI specific information\n"
998 "Display information about all VPNv4 NLRIs\n"
999 "Display BGP tags for prefixes\n")
1001 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 1, 0);
1004 DEFUN (show_ip_bgp_vpnv4_rd_tags
,
1005 show_ip_bgp_vpnv4_rd_tags_cmd
,
1006 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
1010 "Display VPNv4 NLRI specific information\n"
1011 "Display information for a route distinguisher\n"
1012 "VPN Route Distinguisher\n"
1013 "Display BGP tags for prefixes\n")
1016 struct prefix_rd prd
;
1018 ret
= str2prefix_rd (argv
[0], &prd
);
1021 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1024 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 1, 0);
1027 DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes
,
1028 show_ip_bgp_vpnv4_all_neighbor_routes_cmd
,
1029 "show ip bgp vpnv4 all neighbors A.B.C.D routes {json}",
1033 "Display VPNv4 NLRI specific information\n"
1034 "Display information about all VPNv4 NLRIs\n"
1035 "Detailed information on TCP and BGP neighbor connections\n"
1036 "Neighbor to display information about\n"
1037 "Display routes learned from neighbor\n"
1038 "JavaScript Object Notation\n")
1043 u_char uj
= use_json(argc
, argv
);
1045 ret
= str2sockunion (argv
[0], &su
);
1050 json_object
*json_no
= NULL
;
1051 json_no
= json_object_new_object();
1052 json_object_string_add(json_no
, "warning", "Malformed address");
1053 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1054 json_object_free(json_no
);
1057 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1061 peer
= peer_lookup (NULL
, &su
);
1062 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1066 json_object
*json_no
= NULL
;
1067 json_no
= json_object_new_object();
1068 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1069 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1070 json_object_free(json_no
);
1073 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1077 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
1080 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes
,
1081 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd
,
1082 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes {json}",
1086 "Display VPNv4 NLRI specific information\n"
1087 "Display information for a route distinguisher\n"
1088 "VPN Route Distinguisher\n"
1089 "Detailed information on TCP and BGP neighbor connections\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
);
1100 ret
= str2prefix_rd (argv
[0], &prd
);
1105 json_object
*json_no
= NULL
;
1106 json_no
= json_object_new_object();
1107 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1108 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1109 json_object_free(json_no
);
1112 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1116 ret
= str2sockunion (argv
[1], &su
);
1121 json_object
*json_no
= NULL
;
1122 json_no
= json_object_new_object();
1123 json_object_string_add(json_no
, "warning", "Malformed address");
1124 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1125 json_object_free(json_no
);
1128 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1132 peer
= peer_lookup (NULL
, &su
);
1133 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1137 json_object
*json_no
= NULL
;
1138 json_no
= json_object_new_object();
1139 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1140 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1141 json_object_free(json_no
);
1144 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1148 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
1151 DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes
,
1152 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd
,
1153 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes {json}",
1157 "Display VPNv4 NLRI specific information\n"
1158 "Display information about all VPNv4 NLRIs\n"
1159 "Detailed information on TCP and BGP neighbor connections\n"
1160 "Neighbor to display information about\n"
1161 "Display the routes advertised to a BGP neighbor\n"
1162 "JavaScript Object Notation\n")
1167 u_char uj
= use_json(argc
, argv
);
1169 ret
= str2sockunion (argv
[0], &su
);
1174 json_object
*json_no
= NULL
;
1175 json_no
= json_object_new_object();
1176 json_object_string_add(json_no
, "warning", "Malformed address");
1177 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1178 json_object_free(json_no
);
1181 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1184 peer
= peer_lookup (NULL
, &su
);
1185 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1189 json_object
*json_no
= NULL
;
1190 json_no
= json_object_new_object();
1191 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1192 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1193 json_object_free(json_no
);
1196 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1200 return show_adj_route_vpn (vty
, peer
, NULL
, uj
);
1203 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes
,
1204 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd
,
1205 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes {json}",
1209 "Display VPNv4 NLRI specific information\n"
1210 "Display information for a route distinguisher\n"
1211 "VPN Route Distinguisher\n"
1212 "Detailed information on TCP and BGP neighbor connections\n"
1213 "Neighbor to display information about\n"
1214 "Display the routes advertised to a BGP neighbor\n"
1215 "JavaScript Object Notation\n")
1219 struct prefix_rd prd
;
1221 u_char uj
= use_json(argc
, argv
);
1223 ret
= str2sockunion (argv
[1], &su
);
1228 json_object
*json_no
= NULL
;
1229 json_no
= json_object_new_object();
1230 json_object_string_add(json_no
, "warning", "Malformed address");
1231 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1232 json_object_free(json_no
);
1235 vty_out (vty
, "Malformed address: %s%s", argv
[0], VTY_NEWLINE
);
1238 peer
= peer_lookup (NULL
, &su
);
1239 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1243 json_object
*json_no
= NULL
;
1244 json_no
= json_object_new_object();
1245 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1246 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1247 json_object_free(json_no
);
1250 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1254 ret
= str2prefix_rd (argv
[0], &prd
);
1259 json_object
*json_no
= NULL
;
1260 json_no
= json_object_new_object();
1261 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1262 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1263 json_object_free(json_no
);
1266 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1270 return show_adj_route_vpn (vty
, peer
, &prd
, uj
);
1274 bgp_mplsvpn_init (void)
1276 install_element (BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1277 install_element (BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1278 install_element (BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1280 install_element (VIEW_NODE
, &show_bgp_ipv4_vpn_cmd
);
1281 install_element (VIEW_NODE
, &show_bgp_ipv4_vpn_rd_cmd
);
1282 install_element (VIEW_NODE
, &show_bgp_ipv6_vpn_cmd
);
1283 install_element (VIEW_NODE
, &show_bgp_ipv6_vpn_rd_cmd
);
1284 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_cmd
);
1285 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_cmd
);
1286 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_tags_cmd
);
1287 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_tags_cmd
);
1288 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd
);
1289 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd
);
1290 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd
);
1291 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd
);