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"
44 #define BGP_VPNVX_HELP_STR \
49 argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
, int *index
, afi_t
*afi
)
52 if (argv_find (argv
, argc
, "vpnv4", index
))
58 else if (argv_find (argv
, argc
, "vpnv6", index
))
68 decode_rd_type (u_char
*pnt
)
72 v
= ((u_int16_t
) *pnt
++ << 8);
75 * VNC L2 stores LHI in lower byte, so omit it
77 if (v
!= RD_TYPE_VNC_ETH
)
78 v
|= (u_int16_t
) *pnt
;
79 #else /* duplicate code for clarity */
80 v
|= (u_int16_t
) *pnt
;
87 encode_rd_type (u_int16_t v
, u_char
*pnt
)
89 *((u_int16_t
*)pnt
) = htons(v
);
93 decode_label (u_char
*pnt
)
97 l
= ((u_int32_t
) *pnt
++ << 12);
98 l
|= (u_int32_t
) *pnt
++ << 4;
99 l
|= (u_int32_t
) ((*pnt
& 0xf0) >> 4);
104 encode_label(u_int32_t label
,
109 *pnt
++ = (label
>>12) & 0xff;
110 *pnt
++ = (label
>>4) & 0xff;
111 *pnt
++ = ((label
<<4)+1) & 0xff; /* S=1 */
114 /* type == RD_TYPE_AS */
116 decode_rd_as (u_char
*pnt
, struct rd_as
*rd_as
)
118 rd_as
->as
= (u_int16_t
) *pnt
++ << 8;
119 rd_as
->as
|= (u_int16_t
) *pnt
++;
121 rd_as
->val
= ((u_int32_t
) *pnt
++ << 24);
122 rd_as
->val
|= ((u_int32_t
) *pnt
++ << 16);
123 rd_as
->val
|= ((u_int32_t
) *pnt
++ << 8);
124 rd_as
->val
|= (u_int32_t
) *pnt
;
127 /* type == RD_TYPE_AS4 */
129 decode_rd_as4 (u_char
*pnt
, struct rd_as
*rd_as
)
131 rd_as
->as
= (u_int32_t
) *pnt
++ << 24;
132 rd_as
->as
|= (u_int32_t
) *pnt
++ << 16;
133 rd_as
->as
|= (u_int32_t
) *pnt
++ << 8;
134 rd_as
->as
|= (u_int32_t
) *pnt
++;
136 rd_as
->val
= ((u_int16_t
) *pnt
++ << 8);
137 rd_as
->val
|= (u_int16_t
) *pnt
;
140 /* type == RD_TYPE_IP */
142 decode_rd_ip (u_char
*pnt
, struct rd_ip
*rd_ip
)
144 memcpy (&rd_ip
->ip
, pnt
, 4);
147 rd_ip
->val
= ((u_int16_t
) *pnt
++ << 8);
148 rd_ip
->val
|= (u_int16_t
) *pnt
;
152 /* type == RD_TYPE_VNC_ETH */
154 decode_rd_vnc_eth (u_char
*pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
156 rd_vnc_eth
->type
= RD_TYPE_VNC_ETH
;
157 rd_vnc_eth
->local_nve_id
= pnt
[1];
158 memcpy (rd_vnc_eth
->macaddr
.octet
, pnt
+ 2, ETHER_ADDR_LEN
);
163 bgp_nlri_parse_vpn (struct peer
*peer
, struct attr
*attr
,
164 struct bgp_nlri
*packet
)
174 struct prefix_rd prd
;
179 u_int32_t addpath_id
;
184 /* Check peer status. */
185 if (peer
->status
!= Established
)
189 prd
.family
= AF_UNSPEC
;
193 lim
= pnt
+ packet
->length
;
198 addpath_encoded
= (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
199 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
201 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
202 for (; pnt
< lim
; pnt
+= psize
)
204 /* Clear prefix structure. */
205 memset (&p
, 0, sizeof (struct prefix
));
210 /* When packet overflow occurs return immediately. */
211 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
214 addpath_id
= ntohl(*((uint32_t*) pnt
));
215 pnt
+= BGP_ADDPATH_ID_LEN
;
218 /* Fetch prefix length. */
220 p
.family
= afi2family (packet
->afi
);
221 psize
= PSIZE (prefixlen
);
223 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
*8)
225 zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d less than VPNv4 min length)",
226 peer
->host
, prefixlen
);
230 /* sanity check against packet data */
231 if ((pnt
+ psize
) > lim
)
233 zlog_err ("%s [Error] Update packet error / VPNv4 (prefix length %d exceeds packet size %u)",
235 prefixlen
, (uint
)(lim
-pnt
));
239 /* sanity check against storage for the IP address portion */
240 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
) sizeof(p
.u
))
242 zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds storage size %zu)",
244 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8, sizeof(p
.u
));
248 /* Sanity check against max bitlen of the address family */
249 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen (&p
))
251 zlog_err ("%s [Error] Update packet error / VPNv4 (psize %d exceeds family (%u) max byte len %u)",
253 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8,
254 p
.family
, prefix_blen (&p
));
259 label
= decode_label (pnt
);
262 /* Copyr label to prefix. */
265 /* Copy routing distinguisher to rd. */
266 memcpy (&prd
.val
, pnt
+ 3, 8);
268 /* Decode RD type. */
269 type
= decode_rd_type (pnt
+ 3);
274 decode_rd_as (pnt
+ 5, &rd_as
);
278 decode_rd_as4 (pnt
+ 5, &rd_as
);
282 decode_rd_ip (pnt
+ 5, &rd_ip
);
286 case RD_TYPE_VNC_ETH
:
291 zlog_err ("Unknown RD type %d", type
);
292 break; /* just report */
295 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8;/* exclude label & RD */
296 memcpy (&p
.u
.prefix
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
297 psize
- VPN_PREFIXLEN_MIN_BYTES
);
301 bgp_update (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
302 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
, 0);
304 rfapiProcessUpdate(peer
, NULL
, &p
, &prd
, attr
, packet
->afi
,
305 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
312 rfapiProcessWithdraw(peer
, NULL
, &p
, &prd
, attr
, packet
->afi
,
313 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
, 0);
315 bgp_withdraw (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
316 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
);
319 /* Packet length consistency check. */
322 zlog_err ("%s [Error] Update packet error / VPNv4 (%zu data remaining after parsing)",
323 peer
->host
, lim
- pnt
);
328 #undef VPN_PREFIXLEN_MIN_BYTES
332 str2prefix_rd (const char *str
, struct prefix_rd
*prd
)
334 int ret
; /* ret of called functions */
335 int lret
; /* local ret, of this func */
338 struct stream
*s
= NULL
;
344 prd
->family
= AF_UNSPEC
;
348 p
= strchr (str
, ':');
352 if (! all_digit (p
+ 1))
355 half
= XMALLOC (MTYPE_TMP
, (p
- str
) + 1);
356 memcpy (half
, str
, (p
- str
));
357 half
[p
- str
] = '\0';
359 p2
= strchr (str
, '.');
363 unsigned long as_val
;
365 if (! all_digit (half
))
371 stream_putw (s
, RD_TYPE_AS4
);
372 stream_putl (s
, as_val
);
373 stream_putw (s
, atol (p
+ 1));
377 stream_putw (s
, RD_TYPE_AS
);
378 stream_putw (s
, as_val
);
379 stream_putl (s
, atol (p
+ 1));
384 ret
= inet_aton (half
, &addr
);
388 stream_putw (s
, RD_TYPE_IP
);
389 stream_put_in_addr (s
, &addr
);
390 stream_putw (s
, atol (p
+ 1));
392 memcpy (prd
->val
, s
->data
, 8);
399 XFREE(MTYPE_TMP
, half
);
404 str2tag (const char *str
, u_char
*tag
)
414 l
= strtoul (str
, &endptr
, 10);
416 if (*endptr
!= '\0' || errno
|| l
> UINT32_MAX
)
421 tag
[0] = (u_char
)(t
>> 12);
422 tag
[1] = (u_char
)(t
>> 4);
423 tag
[2] = (u_char
)(t
<< 4);
429 prefix_rd2str (struct prefix_rd
*prd
, char *buf
, size_t size
)
436 if (size
< RD_ADDRSTRLEN
)
441 type
= decode_rd_type (pnt
);
443 if (type
== RD_TYPE_AS
)
445 decode_rd_as (pnt
+ 2, &rd_as
);
446 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
449 else if (type
== RD_TYPE_AS4
)
451 decode_rd_as4 (pnt
+ 2, &rd_as
);
452 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
455 else if (type
== RD_TYPE_IP
)
457 decode_rd_ip (pnt
+ 2, &rd_ip
);
458 snprintf (buf
, size
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
462 else if (type
== RD_TYPE_VNC_ETH
)
464 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
466 *(pnt
+2), /* MAC[0] */
479 /* For testing purpose, static route of MPLS-VPN. */
480 DEFUN (vpnv4_network
,
482 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
483 "Specify a network to announce via BGP\n"
485 "Specify Route Distinguisher\n"
486 "VPN Route Distinguisher\n"
490 int idx_ipv4_prefixlen
= 1;
491 int idx_ext_community
= 3;
493 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, NULL
);
496 DEFUN (vpnv4_network_route_map
,
497 vpnv4_network_route_map_cmd
,
498 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
499 "Specify a network to announce via BGP\n"
501 "Specify Route Distinguisher\n"
502 "VPN Route Distinguisher\n"
508 int idx_ipv4_prefixlen
= 1;
509 int idx_ext_community
= 3;
512 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
);
515 /* For testing purpose, static route of MPLS-VPN. */
516 DEFUN (no_vpnv4_network
,
517 no_vpnv4_network_cmd
,
518 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
520 "Specify a network to announce via BGP\n"
522 "Specify Route Distinguisher\n"
523 "VPN Route Distinguisher\n"
527 int idx_ipv4_prefixlen
= 2;
528 int idx_ext_community
= 4;
530 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
533 DEFUN (vpnv6_network
,
535 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD [route-map WORD]",
536 "Specify a network to announce via BGP\n"
537 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
538 "Specify Route Distinguisher\n"
539 "VPN Route Distinguisher\n"
543 int idx_ipv6_prefix
= 1;
544 int idx_ext_community
= 3;
547 if (argv
[idx_word_2
])
548 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, argv
[idx_word_2
]->arg
);
550 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, NULL
);
553 /* For testing purpose, static route of MPLS-VPN. */
554 DEFUN (no_vpnv6_network
,
555 no_vpnv6_network_cmd
,
556 "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD",
558 "Specify a network to announce via BGP\n"
559 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
560 "Specify Route Distinguisher\n"
561 "VPN Route Distinguisher\n"
565 int idx_ipv6_prefix
= 2;
566 int idx_ext_community
= 4;
568 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
572 show_adj_route_vpn (struct vty
*vty
, struct peer
*peer
, struct prefix_rd
*prd
, u_char use_json
, afi_t afi
)
575 struct bgp_table
*table
;
581 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
582 json_object
*json
= NULL
;
583 json_object
*json_scode
= NULL
;
584 json_object
*json_ocode
= NULL
;
585 json_object
*json_routes
= NULL
;
586 json_object
*json_array
= NULL
;
588 bgp
= bgp_get_default ();
592 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
598 json_scode
= json_object_new_object();
599 json_ocode
= json_object_new_object();
600 json_routes
= json_object_new_object();
601 json
= json_object_new_object();
603 json_object_string_add(json_scode
, "suppressed", "s");
604 json_object_string_add(json_scode
, "damped", "d");
605 json_object_string_add(json_scode
, "history", "h");
606 json_object_string_add(json_scode
, "valid", "*");
607 json_object_string_add(json_scode
, "best", ">");
608 json_object_string_add(json_scode
, "internal", "i");
610 json_object_string_add(json_ocode
, "igp", "i");
611 json_object_string_add(json_ocode
, "egp", "e");
612 json_object_string_add(json_ocode
, "incomplete", "?");
615 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
616 rn
= bgp_route_next (rn
))
618 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
621 if ((table
= rn
->info
) != NULL
)
624 json_array
= json_object_new_array();
630 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
632 if ((attr
= rm
->info
) != NULL
)
638 json_object_int_add(json
, "bgpTableVersion", 0);
639 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
640 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
641 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
645 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
646 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
647 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
649 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
650 VTY_NEWLINE
, VTY_NEWLINE
);
651 vty_out (vty
, v4_header
, VTY_NEWLINE
);
660 struct rd_ip rd_ip
= {0};
662 struct rd_vnc_eth rd_vnc_eth
;
668 /* Decode RD type. */
669 type
= decode_rd_type (pnt
);
670 /* Decode RD value. */
671 if (type
== RD_TYPE_AS
)
672 decode_rd_as (pnt
+ 2, &rd_as
);
673 else if (type
== RD_TYPE_AS4
)
674 decode_rd_as4 (pnt
+ 2, &rd_as
);
675 else if (type
== RD_TYPE_IP
)
676 decode_rd_ip (pnt
+ 2, &rd_ip
);
678 else if (type
== RD_TYPE_VNC_ETH
)
679 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
685 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
686 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
687 else if (type
== RD_TYPE_IP
)
688 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
689 json_object_string_add(json_routes
, "routeDistinguisher", buffer
);
693 vty_out (vty
, "Route Distinguisher: ");
695 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
696 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
697 else if (type
== RD_TYPE_IP
)
698 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
700 else if (type
== RD_TYPE_VNC_ETH
)
701 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
702 rd_vnc_eth
.local_nve_id
,
703 rd_vnc_eth
.macaddr
.octet
[0],
704 rd_vnc_eth
.macaddr
.octet
[1],
705 rd_vnc_eth
.macaddr
.octet
[2],
706 rd_vnc_eth
.macaddr
.octet
[3],
707 rd_vnc_eth
.macaddr
.octet
[4],
708 rd_vnc_eth
.macaddr
.octet
[5]);
711 vty_out (vty
, "%s", VTY_NEWLINE
);
715 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_MPLS_VPN
, use_json
, json_array
);
724 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
725 json_object_object_add(json_routes
, buf_a
, json_array
);
731 json_object_object_add(json
, "routes", json_routes
);
732 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
733 json_object_free(json
);
740 bgp_show_type_normal
,
741 bgp_show_type_regexp
,
742 bgp_show_type_prefix_list
,
743 bgp_show_type_filter_list
,
744 bgp_show_type_neighbor
,
745 bgp_show_type_cidr_only
,
746 bgp_show_type_prefix_longer
,
747 bgp_show_type_community_all
,
748 bgp_show_type_community
,
749 bgp_show_type_community_exact
,
750 bgp_show_type_community_list
,
751 bgp_show_type_community_list_exact
755 bgp_show_mpls_vpn (struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
756 enum bgp_show_type type
, void *output_arg
, int tags
, u_char use_json
)
759 struct bgp_table
*table
;
765 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
766 char v4_header_tag
[] = " Network Next Hop In tag/Out tag%s";
767 unsigned long output_count
= 0;
768 unsigned long total_count
= 0;
769 json_object
*json
= NULL
;
770 json_object
*json_mroute
= NULL
;
771 json_object
*json_nroute
= NULL
;
772 json_object
*json_array
= NULL
;
773 json_object
*json_scode
= NULL
;
774 json_object
*json_ocode
= NULL
;
776 bgp
= bgp_get_default ();
780 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
786 json_scode
= json_object_new_object();
787 json_ocode
= json_object_new_object();
788 json
= json_object_new_object();
789 json_mroute
= json_object_new_object();
790 json_nroute
= json_object_new_object();
792 json_object_string_add(json_scode
, "suppressed", "s");
793 json_object_string_add(json_scode
, "damped", "d");
794 json_object_string_add(json_scode
, "history", "h");
795 json_object_string_add(json_scode
, "valid", "*");
796 json_object_string_add(json_scode
, "best", ">");
797 json_object_string_add(json_scode
, "internal", "i");
799 json_object_string_add(json_ocode
, "igp", "i");
800 json_object_string_add(json_ocode
, "egp", "e");
801 json_object_string_add(json_ocode
, "incomplete", "?");
804 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
))
806 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
810 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
; rn
= bgp_route_next (rn
))
812 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
815 if ((table
= rn
->info
) != NULL
)
819 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
823 json_array
= json_object_new_array();
827 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
829 if (type
== bgp_show_type_neighbor
)
831 union sockunion
*su
= output_arg
;
833 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
842 json_object_int_add(json
, "bgpTableVersion", 0);
843 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
844 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
845 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
851 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
854 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
855 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
856 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
858 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
859 VTY_NEWLINE
, VTY_NEWLINE
);
860 vty_out (vty
, v4_header
, VTY_NEWLINE
);
870 struct rd_ip rd_ip
= {0};
872 struct rd_vnc_eth rd_vnc_eth
;
878 /* Decode RD type. */
879 type
= decode_rd_type (pnt
);
880 /* Decode RD value. */
881 if (type
== RD_TYPE_AS
)
882 decode_rd_as (pnt
+ 2, &rd_as
);
883 else if (type
== RD_TYPE_AS4
)
884 decode_rd_as4 (pnt
+ 2, &rd_as
);
885 else if (type
== RD_TYPE_IP
)
886 decode_rd_ip (pnt
+ 2, &rd_ip
);
888 else if (type
== RD_TYPE_VNC_ETH
)
889 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
895 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
896 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
897 else if (type
== RD_TYPE_IP
)
898 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
899 json_object_string_add(json_nroute
, "routeDistinguisher", buffer
);
903 vty_out (vty
, "Route Distinguisher: ");
905 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
906 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
907 else if (type
== RD_TYPE_IP
)
908 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
910 else if (type
== RD_TYPE_VNC_ETH
)
911 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
912 rd_vnc_eth
.local_nve_id
,
913 rd_vnc_eth
.macaddr
.octet
[0],
914 rd_vnc_eth
.macaddr
.octet
[1],
915 rd_vnc_eth
.macaddr
.octet
[2],
916 rd_vnc_eth
.macaddr
.octet
[3],
917 rd_vnc_eth
.macaddr
.octet
[4],
918 rd_vnc_eth
.macaddr
.octet
[5]);
920 vty_out (vty
, "%s", VTY_NEWLINE
);
925 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
927 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
937 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
938 json_object_object_add(json_mroute
, buf_a
, json_array
);
948 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
949 json_object_object_add(json_nroute
, buf_a
, json_mroute
);
956 json_object_object_add(json
, "routes", json_nroute
);
957 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
958 json_object_free(json
);
962 if (output_count
== 0)
963 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
965 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
966 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
972 DEFUN (show_bgp_ip_vpn_rd
,
973 show_bgp_ip_vpn_rd_cmd
,
974 "show [ip] bgp "BGP_AFI_CMD_STR
" vpn [rd ASN:nn_or_IP-address:nn] [json]",
979 "Display VPN NLRI specific information\n"
980 "Display information for a route distinguisher\n"
981 "VPN Route Distinguisher\n"
984 int idx_ext_community
= 5;
986 struct prefix_rd prd
;
990 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
992 if (argv
[idx_ext_community
]->arg
)
994 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
997 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1000 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
1004 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
1010 DEFUN (show_ip_bgp_vpn_all
,
1011 show_ip_bgp_vpn_all_cmd
,
1012 "show [ip] bgp <vpnv4|vpnv6>",
1021 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1022 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
1026 DEFUN (show_ip_bgp_vpn_rd
,
1027 show_ip_bgp_vpn_rd_cmd
,
1028 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn",
1033 "Display information for a route distinguisher\n"
1034 "VPN Route Distinguisher\n")
1036 int idx_ext_community
= 5;
1038 struct prefix_rd prd
;
1042 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1044 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1047 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1050 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 0, 0);
1055 DEFUN (show_ip_bgp_vpn_all_tags
,
1056 show_ip_bgp_vpn_all_tags_cmd
,
1057 "show [ip] bgp <vpnv4|vpnv6> all tags",
1062 "Display information about all VPNv4/VPNV6 NLRIs\n"
1063 "Display BGP tags for prefixes\n")
1068 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1069 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 1, 0);
1073 DEFUN (show_ip_bgp_vpn_rd_tags
,
1074 show_ip_bgp_vpn_rd_tags_cmd
,
1075 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
1080 "Display information for a route distinguisher\n"
1081 "VPN Route Distinguisher\n"
1082 "Display BGP tags for prefixes\n")
1084 int idx_ext_community
= 5;
1086 struct prefix_rd prd
;
1090 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1092 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1095 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1098 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 1, 0);
1103 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1104 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1105 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1110 "Display information about all VPNv4/VPNv6 NLRIs\n"
1111 "Detailed information on TCP and BGP neighbor connections\n"
1112 "Neighbor to display information about\n"
1113 "Display routes learned from neighbor\n"
1120 u_char uj
= use_json(argc
, argv
);
1124 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1126 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1131 json_object
*json_no
= NULL
;
1132 json_no
= json_object_new_object();
1133 json_object_string_add(json_no
, "warning", "Malformed address");
1134 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1135 json_object_free(json_no
);
1138 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1142 peer
= peer_lookup (NULL
, &su
);
1143 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1147 json_object
*json_no
= NULL
;
1148 json_no
= json_object_new_object();
1149 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1150 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1151 json_object_free(json_no
);
1154 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1158 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
1163 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1164 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1165 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
1170 "Display information for a route distinguisher\n"
1171 "VPN Route Distinguisher\n"
1172 "Detailed information on TCP and BGP neighbor connections\n"
1173 "Neighbor to display information about\n"
1174 "Display routes learned from neighbor\n"
1177 int idx_ext_community
= 5;
1182 struct prefix_rd prd
;
1183 u_char uj
= use_json(argc
, argv
);
1187 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1189 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1194 json_object
*json_no
= NULL
;
1195 json_no
= json_object_new_object();
1196 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1197 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1198 json_object_free(json_no
);
1201 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1205 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1210 json_object
*json_no
= NULL
;
1211 json_no
= json_object_new_object();
1212 json_object_string_add(json_no
, "warning", "Malformed address");
1213 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1214 json_object_free(json_no
);
1217 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1221 peer
= peer_lookup (NULL
, &su
);
1222 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1226 json_object
*json_no
= NULL
;
1227 json_no
= json_object_new_object();
1228 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1229 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1230 json_object_free(json_no
);
1233 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1237 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
1242 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1243 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
1244 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1249 "Display information about all VPNv4/VPNv6 NLRIs\n"
1250 "Detailed information on TCP and BGP neighbor connections\n"
1251 "Neighbor to display information about\n"
1252 "Display the routes advertised to a BGP neighbor\n"
1259 u_char uj
= use_json(argc
, argv
);
1263 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1265 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1270 json_object
*json_no
= NULL
;
1271 json_no
= json_object_new_object();
1272 json_object_string_add(json_no
, "warning", "Malformed address");
1273 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1274 json_object_free(json_no
);
1277 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1280 peer
= peer_lookup (NULL
, &su
);
1281 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1285 json_object
*json_no
= NULL
;
1286 json_no
= json_object_new_object();
1287 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
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
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1296 return show_adj_route_vpn (vty
, peer
, NULL
, uj
, afi
);
1301 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
1302 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
1303 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1308 "Display information for a route distinguisher\n"
1309 "VPN Route Distinguisher\n"
1310 "Detailed information on TCP and BGP neighbor connections\n"
1311 "Neighbor to display information about\n"
1312 "Display the routes advertised to a BGP neighbor\n"
1315 int idx_ext_community
= 5;
1319 struct prefix_rd prd
;
1321 u_char uj
= use_json(argc
, argv
);
1325 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1327 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1332 json_object
*json_no
= NULL
;
1333 json_no
= json_object_new_object();
1334 json_object_string_add(json_no
, "warning", "Malformed address");
1335 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1336 json_object_free(json_no
);
1339 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1342 peer
= peer_lookup (NULL
, &su
);
1343 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1347 json_object
*json_no
= NULL
;
1348 json_no
= json_object_new_object();
1349 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1350 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1351 json_object_free(json_no
);
1354 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1358 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1363 json_object
*json_no
= NULL
;
1364 json_no
= json_object_new_object();
1365 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1366 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1367 json_object_free(json_no
);
1370 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1374 return show_adj_route_vpn (vty
, peer
, &prd
, uj
, afi
);
1380 bgp_mplsvpn_init (void)
1382 install_element (BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1383 install_element (BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1384 install_element (BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1386 install_element (BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
1387 install_element (BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
1389 install_element (VIEW_NODE
, &show_bgp_ip_vpn_rd_cmd
);
1390 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
1391 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1392 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
1393 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
1394 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
1395 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
1396 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
1397 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);