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 routes and %ld total paths%s",
892 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
898 DEFUN (show_bgp_ivp4_vpn
,
899 show_bgp_ipv4_vpn_cmd
,
900 "show [ip] bgp ipv4 vpn [json]",
905 "Display VPN NLRI specific information\n"
908 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
911 DEFUN (show_bgp_ipv6_vpn
,
912 show_bgp_ipv6_vpn_cmd
,
913 "show [ip] bgp ipv6 vpn [json]",
918 "Display VPN NLRI specific information\n"
921 return bgp_show_mpls_vpn (vty
, AFI_IP6
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
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]",
931 "Display VPN NLRI specific information\n"
932 "Display information for a route distinguisher\n"
933 "VPN Route Distinguisher\n"
936 int idx_ext_community
= 5;
938 struct prefix_rd prd
;
940 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
943 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
946 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
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]",
956 "Display VPN NLRI specific information\n"
957 "Display information for a route distinguisher\n"
958 "VPN Route Distinguisher\n"
961 int idx_ext_community
= 5;
963 struct prefix_rd prd
;
965 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
968 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
972 return bgp_show_mpls_vpn (vty
, AFI_IP6
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
975 DEFUN (show_ip_bgp_vpnv4_all
,
976 show_ip_bgp_vpnv4_all_cmd
,
977 "show [ip] bgp vpnv4 all",
982 "Display information about all VPNv4 NLRIs\n")
984 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
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",
994 "Display information for a route distinguisher\n"
995 "VPN Route Distinguisher\n")
997 int idx_ext_community
= 5;
999 struct prefix_rd prd
;
1001 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1004 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1007 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 0, 0);
1010 DEFUN (show_ip_bgp_vpnv4_all_tags
,
1011 show_ip_bgp_vpnv4_all_tags_cmd
,
1012 "show [ip] bgp vpnv4 all tags",
1017 "Display information about all VPNv4 NLRIs\n"
1018 "Display BGP tags for prefixes\n")
1020 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_normal
, NULL
, 1, 0);
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",
1030 "Display information for a route distinguisher\n"
1031 "VPN Route Distinguisher\n"
1032 "Display BGP tags for prefixes\n")
1034 int idx_ext_community
= 5;
1036 struct prefix_rd prd
;
1038 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1041 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1044 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_normal
, NULL
, 1, 0);
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]",
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"
1064 u_char uj
= use_json(argc
, argv
);
1066 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
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
);
1078 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1082 peer
= peer_lookup (NULL
, &su
);
1083 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
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
);
1094 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1098 return bgp_show_mpls_vpn (vty
, AFI_IP
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
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]",
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"
1115 int idx_ext_community
= 5;
1120 struct prefix_rd prd
;
1121 u_char uj
= use_json(argc
, argv
);
1123 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
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
);
1135 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1139 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
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
);
1151 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1155 peer
= peer_lookup (NULL
, &su
);
1156 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
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
);
1167 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1171 return bgp_show_mpls_vpn (vty
, AFI_IP
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
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]",
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"
1191 u_char uj
= use_json(argc
, argv
);
1193 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
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
);
1205 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1208 peer
= peer_lookup (NULL
, &su
);
1209 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
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
);
1220 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1224 return show_adj_route_vpn (vty
, peer
, NULL
, uj
);
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]",
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"
1241 int idx_ext_community
= 5;
1245 struct prefix_rd prd
;
1247 u_char uj
= use_json(argc
, argv
);
1249 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
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
);
1261 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1264 peer
= peer_lookup (NULL
, &su
);
1265 if (! peer
|| ! peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
])
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
);
1276 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1280 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
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
);
1292 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1296 return show_adj_route_vpn (vty
, peer
, &prd
, uj
);
1300 bgp_mplsvpn_init (void)
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
);
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
);