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"
449 "Specify Route Distinguisher\n"
450 "VPN Route Distinguisher\n"
454 int idx_ipv4_prefixlen
= 1;
455 int idx_ext_community
= 3;
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
);
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"
465 "Specify Route Distinguisher\n"
466 "VPN Route Distinguisher\n"
472 int idx_ipv4_prefixlen
= 1;
473 int idx_ext_community
= 3;
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
);
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",
484 "Specify a network to announce via BGP\n"
486 "Specify Route Distinguisher\n"
487 "VPN Route Distinguisher\n"
491 int idx_ipv4_prefixlen
= 2;
492 int idx_ext_community
= 4;
494 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
498 show_adj_route_vpn (struct vty
*vty
, struct peer
*peer
, struct prefix_rd
*prd
, u_char use_json
)
501 struct bgp_table
*table
;
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
;
514 bgp
= bgp_get_default ();
518 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
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();
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");
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", "?");
541 for (rn
= bgp_table_top (bgp
->rib
[AFI_IP
][SAFI_MPLS_VPN
]); rn
;
542 rn
= bgp_route_next (rn
))
544 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
547 if ((table
= rn
->info
) != NULL
)
550 json_array
= json_object_new_array();
556 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
558 if ((attr
= rm
->info
) != NULL
)
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
);
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",
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
);
586 struct rd_ip rd_ip
= {0};
588 struct rd_vnc_eth rd_vnc_eth
;
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
);
604 else if (type
== RD_TYPE_VNC_ETH
)
605 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
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
);
619 vty_out (vty
, "Route Distinguisher: ");
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
);
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]);
637 vty_out (vty
, "%s", VTY_NEWLINE
);
641 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_MPLS_VPN
, use_json
, json_array
);
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
);
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
);
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
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
)
685 struct bgp_table
*table
;
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
;
702 bgp
= bgp_get_default ();
706 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
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();
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");
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", "?");
730 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
))
732 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
736 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
; rn
= bgp_route_next (rn
))
738 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
741 if ((table
= rn
->info
) != NULL
)
745 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
749 json_array
= json_object_new_array();
753 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
755 if (type
== bgp_show_type_neighbor
)
757 union sockunion
*su
= output_arg
;
759 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
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
);
777 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
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",
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
);
796 struct rd_ip rd_ip
= {0};
798 struct rd_vnc_eth rd_vnc_eth
;
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
);
814 else if (type
== RD_TYPE_VNC_ETH
)
815 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
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
);
829 vty_out (vty
, "Route Distinguisher: ");
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
);
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]);
846 vty_out (vty
, "%s", VTY_NEWLINE
);
851 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
853 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
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
);
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
);
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
);
888 if (output_count
== 0)
889 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
891 vty_out (vty
, "%sDisplayed %ld out of %ld total prefixes%s",
892 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
898 DEFUN (show_bgp_ivp4_vpn
,
899 show_bgp_ipv4_vpn_cmd
,
900 "show bgp ipv4 vpn [json]",
904 "Display VPN NLRI specific information\n")
906 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
909 DEFUN (show_bgp_ipv6_vpn
,
910 show_bgp_ipv6_vpn_cmd
,
911 "show bgp ipv6 vpn [json]",
915 "Display VPN NLRI specific information\n")
917 return bgp_show_mpls_vpn (vty
, AFI_IP6
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
920 DEFUN (show_bgp_ipv4_vpn_rd
,
921 show_bgp_ipv4_vpn_rd_cmd
,
922 "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn [json]",
926 "Display VPN NLRI specific information\n"
927 "Display information for a route distinguisher\n"
928 "VPN Route Distinguisher\n"
931 int idx_ext_community
= 5;
933 struct prefix_rd prd
;
935 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
938 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
941 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
944 DEFUN (show_bgp_ipv6_vpn_rd
,
945 show_bgp_ipv6_vpn_rd_cmd
,
946 "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn [json]",
950 "Display VPN NLRI specific information\n"
951 "Display information for a route distinguisher\n"
952 "VPN Route Distinguisher\n"
955 int idx_ext_community
= 5;
957 struct prefix_rd prd
;
959 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
962 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
966 return bgp_show_mpls_vpn (vty
, AFI_IP6
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
969 DEFUN (show_ip_bgp_vpnv4_all
,
970 show_ip_bgp_vpnv4_all_cmd
,
971 "show ip bgp vpnv4 all",
976 "Display information about all VPNv4 NLRIs\n")
978 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
981 DEFUN (show_ip_bgp_vpnv4_rd
,
982 show_ip_bgp_vpnv4_rd_cmd
,
983 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn",
988 "Display information for a route distinguisher\n"
989 "VPN Route Distinguisher\n")
991 int idx_ext_community
= 5;
993 struct prefix_rd prd
;
995 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
998 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1001 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, 0);
1004 DEFUN (show_ip_bgp_vpnv4_all_tags
,
1005 show_ip_bgp_vpnv4_all_tags_cmd
,
1006 "show ip bgp vpnv4 all tags",
1011 "Display information about all VPNv4 NLRIs\n"
1012 "Display BGP tags for prefixes\n")
1014 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 1, 0);
1017 DEFUN (show_ip_bgp_vpnv4_rd_tags
,
1018 show_ip_bgp_vpnv4_rd_tags_cmd
,
1019 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn tags",
1024 "Display information for a route distinguisher\n"
1025 "VPN Route Distinguisher\n"
1026 "Display BGP tags for prefixes\n")
1028 int idx_ext_community
= 5;
1030 struct prefix_rd prd
;
1032 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1035 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1038 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 1, 0);
1041 DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes
,
1042 show_ip_bgp_vpnv4_all_neighbor_routes_cmd
,
1043 "show ip bgp vpnv4 all neighbors A.B.C.D routes [json]",
1048 "Display information about all VPNv4 NLRIs\n"
1049 "Detailed information on TCP and BGP neighbor connections\n"
1050 "Neighbor to display information about\n"
1051 "Display routes learned from neighbor\n"
1052 "JavaScript Object Notation\n")
1058 u_char uj
= use_json(argc
, argv
);
1060 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1065 json_object
*json_no
= NULL
;
1066 json_no
= json_object_new_object();
1067 json_object_string_add(json_no
, "warning", "Malformed address");
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
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1076 peer
= peer_lookup (NULL
, &su
);
1077 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1081 json_object
*json_no
= NULL
;
1082 json_no
= json_object_new_object();
1083 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1084 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1085 json_object_free(json_no
);
1088 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1092 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
1095 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes
,
1096 show_ip_bgp_vpnv4_rd_neighbor_routes_cmd
,
1097 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
1102 "Display information for a route distinguisher\n"
1103 "VPN Route Distinguisher\n"
1104 "Detailed information on TCP and BGP neighbor connections\n"
1105 "Neighbor to display information about\n"
1106 "Display routes learned from neighbor\n"
1107 "JavaScript Object Notation\n")
1109 int idx_ext_community
= 5;
1114 struct prefix_rd prd
;
1115 u_char uj
= use_json(argc
, argv
);
1117 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1122 json_object
*json_no
= NULL
;
1123 json_no
= json_object_new_object();
1124 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
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 Route Distinguisher%s", VTY_NEWLINE
);
1133 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1138 json_object
*json_no
= NULL
;
1139 json_no
= json_object_new_object();
1140 json_object_string_add(json_no
, "warning", "Malformed address");
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
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1149 peer
= peer_lookup (NULL
, &su
);
1150 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1154 json_object
*json_no
= NULL
;
1155 json_no
= json_object_new_object();
1156 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1157 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1158 json_object_free(json_no
);
1161 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1165 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
1168 DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes
,
1169 show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd
,
1170 "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes [json]",
1175 "Display information about all VPNv4 NLRIs\n"
1176 "Detailed information on TCP and BGP neighbor connections\n"
1177 "Neighbor to display information about\n"
1178 "Display the routes advertised to a BGP neighbor\n"
1179 "JavaScript Object Notation\n")
1185 u_char uj
= use_json(argc
, argv
);
1187 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1192 json_object
*json_no
= NULL
;
1193 json_no
= json_object_new_object();
1194 json_object_string_add(json_no
, "warning", "Malformed address");
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
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1202 peer
= peer_lookup (NULL
, &su
);
1203 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1207 json_object
*json_no
= NULL
;
1208 json_no
= json_object_new_object();
1209 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1210 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1211 json_object_free(json_no
);
1214 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1218 return show_adj_route_vpn (vty
, peer
, NULL
, uj
);
1221 DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes
,
1222 show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd
,
1223 "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1228 "Display information for a route distinguisher\n"
1229 "VPN Route Distinguisher\n"
1230 "Detailed information on TCP and BGP neighbor connections\n"
1231 "Neighbor to display information about\n"
1232 "Display the routes advertised to a BGP neighbor\n"
1233 "JavaScript Object Notation\n")
1235 int idx_ext_community
= 5;
1239 struct prefix_rd prd
;
1241 u_char uj
= use_json(argc
, argv
);
1243 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1248 json_object
*json_no
= NULL
;
1249 json_no
= json_object_new_object();
1250 json_object_string_add(json_no
, "warning", "Malformed address");
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
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1258 peer
= peer_lookup (NULL
, &su
);
1259 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
1263 json_object
*json_no
= NULL
;
1264 json_no
= json_object_new_object();
1265 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1266 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1267 json_object_free(json_no
);
1270 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1274 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1279 json_object
*json_no
= NULL
;
1280 json_no
= json_object_new_object();
1281 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1282 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1283 json_object_free(json_no
);
1286 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1290 return show_adj_route_vpn (vty
, peer
, &prd
, uj
);
1294 bgp_mplsvpn_init (void)
1296 install_element (BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1297 install_element (BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1298 install_element (BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1300 install_element (VIEW_NODE
, &show_bgp_ipv4_vpn_cmd
);
1301 install_element (VIEW_NODE
, &show_bgp_ipv4_vpn_rd_cmd
);
1302 install_element (VIEW_NODE
, &show_bgp_ipv6_vpn_cmd
);
1303 install_element (VIEW_NODE
, &show_bgp_ipv6_vpn_rd_cmd
);
1304 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_cmd
);
1305 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_cmd
);
1306 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_tags_cmd
);
1307 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_tags_cmd
);
1308 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_neighbor_routes_cmd
);
1309 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_neighbor_routes_cmd
);
1310 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd
);
1311 install_element (VIEW_NODE
, &show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd
);