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"
39 #include "bgpd/bgp_vpn.h"
42 #include "bgpd/rfapi/rfapi_backend.h"
45 extern int argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
,
46 int *index
, afi_t
*afi
)
49 if (argv_find(argv
, argc
, "vpnv4", index
)) {
53 } else if (argv_find(argv
, argc
, "vpnv6", index
)) {
61 u_int16_t
decode_rd_type(u_char
*pnt
)
65 v
= ((u_int16_t
)*pnt
++ << 8);
68 * VNC L2 stores LHI in lower byte, so omit it
70 if (v
!= RD_TYPE_VNC_ETH
)
72 #else /* duplicate code for clarity */
79 void encode_rd_type(u_int16_t v
, u_char
*pnt
)
81 *((u_int16_t
*)pnt
) = htons(v
);
84 u_int32_t
decode_label(u_char
*pnt
)
88 l
= ((u_int32_t
)*pnt
++ << 12);
89 l
|= (u_int32_t
)*pnt
++ << 4;
90 l
|= (u_int32_t
)((*pnt
& 0xf0) >> 4);
94 void encode_label(u_int32_t label
, u_char
*pnt
)
98 *pnt
++ = (label
>> 12) & 0xff;
99 *pnt
++ = (label
>> 4) & 0xff;
100 *pnt
++ = ((label
<< 4) + 1) & 0xff; /* S=1 */
103 /* type == RD_TYPE_AS */
104 void decode_rd_as(u_char
*pnt
, struct rd_as
*rd_as
)
106 rd_as
->as
= (u_int16_t
)*pnt
++ << 8;
107 rd_as
->as
|= (u_int16_t
)*pnt
++;
109 rd_as
->val
= ((u_int32_t
)*pnt
++ << 24);
110 rd_as
->val
|= ((u_int32_t
)*pnt
++ << 16);
111 rd_as
->val
|= ((u_int32_t
)*pnt
++ << 8);
112 rd_as
->val
|= (u_int32_t
)*pnt
;
115 /* type == RD_TYPE_AS4 */
116 void decode_rd_as4(u_char
*pnt
, struct rd_as
*rd_as
)
118 rd_as
->as
= (u_int32_t
)*pnt
++ << 24;
119 rd_as
->as
|= (u_int32_t
)*pnt
++ << 16;
120 rd_as
->as
|= (u_int32_t
)*pnt
++ << 8;
121 rd_as
->as
|= (u_int32_t
)*pnt
++;
123 rd_as
->val
= ((u_int16_t
)*pnt
++ << 8);
124 rd_as
->val
|= (u_int16_t
)*pnt
;
127 /* type == RD_TYPE_IP */
128 void decode_rd_ip(u_char
*pnt
, struct rd_ip
*rd_ip
)
130 memcpy(&rd_ip
->ip
, pnt
, 4);
133 rd_ip
->val
= ((u_int16_t
)*pnt
++ << 8);
134 rd_ip
->val
|= (u_int16_t
)*pnt
;
138 /* type == RD_TYPE_VNC_ETH */
139 void decode_rd_vnc_eth(u_char
*pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
141 rd_vnc_eth
->type
= RD_TYPE_VNC_ETH
;
142 rd_vnc_eth
->local_nve_id
= pnt
[1];
143 memcpy(rd_vnc_eth
->macaddr
.octet
, pnt
+ 2, ETHER_ADDR_LEN
);
147 int bgp_nlri_parse_vpn(struct peer
*peer
, struct attr
*attr
,
148 struct bgp_nlri
*packet
)
158 struct prefix_rd prd
;
163 u_int32_t addpath_id
;
165 /* Check peer status. */
166 if (peer
->status
!= Established
)
170 prd
.family
= AF_UNSPEC
;
174 lim
= pnt
+ packet
->length
;
180 (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
181 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
182 PEER_CAP_ADDPATH_AF_TX_RCV
));
184 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
185 for (; pnt
< lim
; pnt
+= psize
) {
186 /* Clear prefix structure. */
187 memset(&p
, 0, sizeof(struct prefix
));
189 if (addpath_encoded
) {
191 /* When packet overflow occurs return immediately. */
192 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
195 addpath_id
= ntohl(*((uint32_t *)pnt
));
196 pnt
+= BGP_ADDPATH_ID_LEN
;
199 /* Fetch prefix length. */
201 p
.family
= afi2family(packet
->afi
);
202 psize
= PSIZE(prefixlen
);
204 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
* 8) {
206 "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
207 peer
->host
, prefixlen
);
211 /* sanity check against packet data */
212 if ((pnt
+ psize
) > lim
) {
214 "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
215 peer
->host
, prefixlen
, (uint
)(lim
- pnt
));
219 /* sanity check against storage for the IP address portion */
220 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
)sizeof(p
.u
)) {
222 "%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
224 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
229 /* Sanity check against max bitlen of the address family */
230 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen(&p
)) {
232 "%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
234 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
* 8,
235 p
.family
, prefix_blen(&p
));
239 /* Copyr label to prefix. */
242 /* Copy routing distinguisher to rd. */
243 memcpy(&prd
.val
, pnt
+ 3, 8);
245 /* Decode RD type. */
246 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 */
273 - VPN_PREFIXLEN_MIN_BYTES
* 8; /* exclude label & RD */
274 memcpy(&p
.u
.prefix
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
275 psize
- VPN_PREFIXLEN_MIN_BYTES
);
278 bgp_update(peer
, &p
, addpath_id
, attr
, packet
->afi
,
279 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
280 BGP_ROUTE_NORMAL
, &prd
, tagpnt
, 0, NULL
);
282 bgp_withdraw(peer
, &p
, addpath_id
, attr
, packet
->afi
,
283 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
,
284 BGP_ROUTE_NORMAL
, &prd
, tagpnt
, NULL
);
287 /* Packet length consistency check. */
290 "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
291 peer
->host
, lim
- pnt
);
296 #undef VPN_PREFIXLEN_MIN_BYTES
299 int str2prefix_rd(const char *str
, struct prefix_rd
*prd
)
301 int ret
; /* ret of called functions */
302 int lret
; /* local ret, of this func */
305 struct stream
*s
= NULL
;
311 prd
->family
= AF_UNSPEC
;
315 p
= strchr(str
, ':');
319 if (!all_digit(p
+ 1))
322 half
= XMALLOC(MTYPE_TMP
, (p
- str
) + 1);
323 memcpy(half
, str
, (p
- str
));
324 half
[p
- str
] = '\0';
326 p2
= strchr(str
, '.');
329 unsigned long as_val
;
331 if (!all_digit(half
))
335 if (as_val
> 0xffff) {
336 stream_putw(s
, RD_TYPE_AS4
);
337 stream_putl(s
, as_val
);
338 stream_putw(s
, atol(p
+ 1));
340 stream_putw(s
, RD_TYPE_AS
);
341 stream_putw(s
, as_val
);
342 stream_putl(s
, atol(p
+ 1));
345 ret
= inet_aton(half
, &addr
);
349 stream_putw(s
, RD_TYPE_IP
);
350 stream_put_in_addr(s
, &addr
);
351 stream_putw(s
, atol(p
+ 1));
353 memcpy(prd
->val
, s
->data
, 8);
360 XFREE(MTYPE_TMP
, half
);
364 char *prefix_rd2str(struct prefix_rd
*prd
, char *buf
, size_t size
)
371 if (size
< RD_ADDRSTRLEN
)
376 type
= decode_rd_type(pnt
);
378 if (type
== RD_TYPE_AS
) {
379 decode_rd_as(pnt
+ 2, &rd_as
);
380 snprintf(buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
382 } else if (type
== RD_TYPE_AS4
) {
383 decode_rd_as4(pnt
+ 2, &rd_as
);
384 snprintf(buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
386 } else if (type
== RD_TYPE_IP
) {
387 decode_rd_ip(pnt
+ 2, &rd_ip
);
388 snprintf(buf
, size
, "%s:%d", inet_ntoa(rd_ip
.ip
), rd_ip
.val
);
392 else if (type
== RD_TYPE_VNC_ETH
) {
393 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
394 *(pnt
+ 1), /* LHI */
395 *(pnt
+ 2), /* MAC[0] */
396 *(pnt
+ 3), *(pnt
+ 4), *(pnt
+ 5), *(pnt
+ 6),
405 /* For testing purpose, static route of MPLS-VPN. */
406 DEFUN (vpnv4_network
,
408 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
409 "Specify a network to announce via BGP\n"
411 "Specify Route Distinguisher\n"
412 "VPN Route Distinguisher\n"
413 "VPN NLRI label (tag)\n"
414 "VPN NLRI label (tag)\n"
417 int idx_ipv4_prefixlen
= 1;
418 int idx_ext_community
= 3;
420 return bgp_static_set_safi(
421 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
422 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
, NULL
, 0,
423 NULL
, NULL
, NULL
, NULL
);
426 DEFUN (vpnv4_network_route_map
,
427 vpnv4_network_route_map_cmd
,
428 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575) route-map WORD",
429 "Specify a network to announce via BGP\n"
431 "Specify Route Distinguisher\n"
432 "VPN Route Distinguisher\n"
433 "VPN NLRI label (tag)\n"
434 "VPN NLRI label (tag)\n"
439 int idx_ipv4_prefixlen
= 1;
440 int idx_ext_community
= 3;
443 return bgp_static_set_safi(
444 AFI_IP
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
445 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
446 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
449 /* For testing purpose, static route of MPLS-VPN. */
450 DEFUN (no_vpnv4_network
,
451 no_vpnv4_network_cmd
,
452 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
454 "Specify a network to announce via BGP\n"
456 "Specify Route Distinguisher\n"
457 "VPN Route Distinguisher\n"
458 "VPN NLRI label (tag)\n"
459 "VPN NLRI label (tag)\n"
462 int idx_ipv4_prefixlen
= 2;
463 int idx_ext_community
= 4;
465 return bgp_static_unset_safi(AFI_IP
, SAFI_MPLS_VPN
, vty
,
466 argv
[idx_ipv4_prefixlen
]->arg
,
467 argv
[idx_ext_community
]->arg
,
468 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
471 DEFUN (vpnv6_network
,
473 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575) [route-map WORD]",
474 "Specify a network to announce via BGP\n"
475 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
476 "Specify Route Distinguisher\n"
477 "VPN Route Distinguisher\n"
478 "VPN NLRI label (tag)\n"
479 "VPN NLRI label (tag)\n"
484 int idx_ipv6_prefix
= 1;
485 int idx_ext_community
= 3;
489 return bgp_static_set_safi(
490 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
491 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
492 argv
[idx_word_2
]->arg
, 0, NULL
, NULL
, NULL
, NULL
);
494 return bgp_static_set_safi(
495 AFI_IP6
, SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
,
496 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
497 NULL
, 0, NULL
, NULL
, NULL
, NULL
);
500 /* For testing purpose, static route of MPLS-VPN. */
501 DEFUN (no_vpnv6_network
,
502 no_vpnv6_network_cmd
,
503 "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
505 "Specify a network to announce via BGP\n"
506 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
507 "Specify Route Distinguisher\n"
508 "VPN Route Distinguisher\n"
509 "VPN NLRI label (tag)\n"
510 "VPN NLRI label (tag)\n"
513 int idx_ipv6_prefix
= 2;
514 int idx_ext_community
= 4;
516 return bgp_static_unset_safi(AFI_IP6
, SAFI_MPLS_VPN
, vty
,
517 argv
[idx_ipv6_prefix
]->arg
,
518 argv
[idx_ext_community
]->arg
,
519 argv
[idx_label
]->arg
, 0, NULL
, NULL
, NULL
);
522 int bgp_show_mpls_vpn(struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
523 enum bgp_show_type type
, void *output_arg
, int tags
,
527 struct bgp_table
*table
;
534 " Network Next Hop Metric LocPrf Weight Path%s";
535 char v4_header_tag
[] =
536 " Network Next Hop In tag/Out tag%s";
537 unsigned long output_count
= 0;
538 unsigned long total_count
= 0;
539 json_object
*json
= NULL
;
540 json_object
*json_mroute
= NULL
;
541 json_object
*json_nroute
= NULL
;
542 json_object
*json_array
= NULL
;
543 json_object
*json_scode
= NULL
;
544 json_object
*json_ocode
= NULL
;
546 bgp
= bgp_get_default();
549 vty_out(vty
, "No BGP process is configured%s",
555 json_scode
= json_object_new_object();
556 json_ocode
= json_object_new_object();
557 json
= json_object_new_object();
558 json_mroute
= json_object_new_object();
559 json_nroute
= json_object_new_object();
561 json_object_string_add(json_scode
, "suppressed", "s");
562 json_object_string_add(json_scode
, "damped", "d");
563 json_object_string_add(json_scode
, "history", "h");
564 json_object_string_add(json_scode
, "valid", "*");
565 json_object_string_add(json_scode
, "best", ">");
566 json_object_string_add(json_scode
, "internal", "i");
568 json_object_string_add(json_ocode
, "igp", "i");
569 json_object_string_add(json_ocode
, "egp", "e");
570 json_object_string_add(json_ocode
, "incomplete", "?");
573 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
)) {
574 vty_out(vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
578 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
579 rn
= bgp_route_next(rn
)) {
580 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
583 if ((table
= rn
->info
) != NULL
) {
586 for (rm
= bgp_table_top(table
); rm
;
587 rm
= bgp_route_next(rm
)) {
590 json_array
= json_object_new_array();
594 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
595 if (type
== bgp_show_type_neighbor
) {
596 union sockunion
*su
=
599 if (ri
->peer
->su_remote
== NULL
612 json_object_string_add(
617 json_object_object_add(
621 json_object_object_add(
633 "BGP table version is 0, local router ID is %s%s",
638 "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
641 "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
655 struct rd_ip rd_ip
= {0};
657 struct rd_vnc_eth rd_vnc_eth
= {
664 /* Decode RD type. */
665 type
= decode_rd_type(pnt
);
666 /* Decode RD value. */
667 if (type
== RD_TYPE_AS
)
668 decode_rd_as(pnt
+ 2,
670 else if (type
== RD_TYPE_AS4
)
671 decode_rd_as4(pnt
+ 2,
673 else if (type
== RD_TYPE_IP
)
674 decode_rd_ip(pnt
+ 2,
686 if (type
== RD_TYPE_AS
687 || type
== RD_TYPE_AS4
)
699 json_object_string_add(
701 "routeDistinguisher",
705 "Route Distinguisher: ");
707 if (type
== RD_TYPE_AS
708 || type
== RD_TYPE_AS4
)
725 "%u:%02x:%02x:%02x:%02x:%02x:%02x",
753 route_vty_out_tag(vty
, &rm
->p
,
758 route_vty_out(vty
, &rm
->p
, ri
,
769 sprintf(buf_a
, "%s/%d",
774 json_object_object_add(
775 json_mroute
, buf_a
, json_array
);
784 sprintf(buf_a
, "%s/%d",
785 inet_ntop(p
->family
, &p
->u
.prefix
,
788 json_object_object_add(json_nroute
, buf_a
,
795 json_object_object_add(json
, "routes", json_nroute
);
796 vty_out(vty
, "%s%s", json_object_to_json_string_ext(
797 json
, JSON_C_TO_STRING_PRETTY
),
799 json_object_free(json
);
801 if (output_count
== 0)
802 vty_out(vty
, "No prefixes displayed, %ld exist%s",
803 total_count
, VTY_NEWLINE
);
806 "%sDisplayed %ld routes and %ld total paths%s",
807 VTY_NEWLINE
, output_count
, total_count
,
814 DEFUN (show_bgp_ip_vpn_all_rd
,
815 show_bgp_ip_vpn_all_rd_cmd
,
816 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
821 "Display VPN NLRI specific information\n"
822 "Display information for a route distinguisher\n"
823 "VPN Route Distinguisher\n"
828 struct prefix_rd prd
;
832 if (argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
833 if (argc
>= 7 && argv
[idx_rd
]->arg
) {
834 ret
= str2prefix_rd(argv
[idx_rd
]->arg
, &prd
);
837 "%% Malformed Route Distinguisher%s",
841 return bgp_show_mpls_vpn(vty
, afi
, &prd
,
842 bgp_show_type_normal
, NULL
, 0,
843 use_json(argc
, argv
));
845 return bgp_show_mpls_vpn(vty
, afi
, NULL
,
846 bgp_show_type_normal
, NULL
, 0,
847 use_json(argc
, argv
));
853 DEFUN (show_ip_bgp_vpn_rd
,
854 show_ip_bgp_vpn_rd_cmd
,
855 "show [ip] bgp "BGP_AFI_CMD_STR
" vpn rd ASN:nn_or_IP-address:nn",
860 "Address Family modifier\n"
861 "Display information for a route distinguisher\n"
862 "VPN Route Distinguisher\n")
864 int idx_ext_community
= argc
- 1;
866 struct prefix_rd prd
;
870 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
871 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
873 vty_out(vty
, "%% Malformed Route Distinguisher%s",
877 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
883 #ifdef KEEP_OLD_VPN_COMMANDS
884 DEFUN (show_ip_bgp_vpn_all
,
885 show_ip_bgp_vpn_all_cmd
,
886 "show [ip] bgp <vpnv4|vpnv6>",
895 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
896 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
901 DEFUN (show_ip_bgp_vpn_all_tags
,
902 show_ip_bgp_vpn_all_tags_cmd
,
903 "show [ip] bgp <vpnv4|vpnv6> all tags",
908 "Display information about all VPNv4/VPNV6 NLRIs\n"
909 "Display BGP tags for prefixes\n")
914 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
))
915 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
920 DEFUN (show_ip_bgp_vpn_rd_tags
,
921 show_ip_bgp_vpn_rd_tags_cmd
,
922 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
927 "Display information for a route distinguisher\n"
928 "VPN Route Distinguisher\n"
929 "Display BGP tags for prefixes\n")
931 int idx_ext_community
= 5;
933 struct prefix_rd prd
;
937 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
938 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
940 vty_out(vty
, "%% Malformed Route Distinguisher%s",
944 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_normal
,
950 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
951 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
952 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
957 "Display information about all VPNv4/VPNv6 NLRIs\n"
958 "Detailed information on TCP and BGP neighbor connections\n"
959 "Neighbor to display information about\n"
960 "Display routes learned from neighbor\n"
967 u_char uj
= use_json(argc
, argv
);
971 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
972 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
975 json_object
*json_no
= NULL
;
976 json_no
= json_object_new_object();
977 json_object_string_add(json_no
, "warning",
978 "Malformed address");
980 json_object_to_json_string(json_no
),
982 json_object_free(json_no
);
984 vty_out(vty
, "Malformed address: %s%s",
985 argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
989 peer
= peer_lookup(NULL
, &su
);
990 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
992 json_object
*json_no
= NULL
;
993 json_no
= json_object_new_object();
994 json_object_string_add(
996 "No such neighbor or address family");
998 json_object_to_json_string(json_no
),
1000 json_object_free(json_no
);
1003 "%% No such neighbor or address family%s",
1008 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_neighbor
,
1014 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1015 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1016 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
1021 "Display information for a route distinguisher\n"
1022 "VPN Route Distinguisher\n"
1023 "Detailed information on TCP and BGP neighbor connections\n"
1024 "Neighbor to display information about\n"
1025 "Display routes learned from neighbor\n"
1028 int idx_ext_community
= 5;
1033 struct prefix_rd prd
;
1034 u_char uj
= use_json(argc
, argv
);
1038 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1039 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1042 json_object
*json_no
= NULL
;
1043 json_no
= json_object_new_object();
1044 json_object_string_add(
1046 "Malformed Route Distinguisher");
1047 vty_out(vty
, "%s%s",
1048 json_object_to_json_string(json_no
),
1050 json_object_free(json_no
);
1053 "%% Malformed Route Distinguisher%s",
1058 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1061 json_object
*json_no
= NULL
;
1062 json_no
= json_object_new_object();
1063 json_object_string_add(json_no
, "warning",
1064 "Malformed address");
1065 vty_out(vty
, "%s%s",
1066 json_object_to_json_string(json_no
),
1068 json_object_free(json_no
);
1070 vty_out(vty
, "Malformed address: %s%s",
1071 argv
[idx_ext_community
]->arg
,
1076 peer
= peer_lookup(NULL
, &su
);
1077 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1079 json_object
*json_no
= NULL
;
1080 json_no
= json_object_new_object();
1081 json_object_string_add(
1083 "No such neighbor or address family");
1084 vty_out(vty
, "%s%s",
1085 json_object_to_json_string(json_no
),
1087 json_object_free(json_no
);
1090 "%% No such neighbor or address family%s",
1095 return bgp_show_mpls_vpn(vty
, afi
, &prd
, bgp_show_type_neighbor
,
1101 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1102 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
1103 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1108 "Display information about all VPNv4/VPNv6 NLRIs\n"
1109 "Detailed information on TCP and BGP neighbor connections\n"
1110 "Neighbor to display information about\n"
1111 "Display the routes advertised to a BGP neighbor\n"
1118 u_char uj
= use_json(argc
, argv
);
1122 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1123 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1126 json_object
*json_no
= NULL
;
1127 json_no
= json_object_new_object();
1128 json_object_string_add(json_no
, "warning",
1129 "Malformed address");
1130 vty_out(vty
, "%s%s",
1131 json_object_to_json_string(json_no
),
1133 json_object_free(json_no
);
1135 vty_out(vty
, "Malformed address: %s%s",
1136 argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1139 peer
= peer_lookup(NULL
, &su
);
1140 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1142 json_object
*json_no
= NULL
;
1143 json_no
= json_object_new_object();
1144 json_object_string_add(
1146 "No such neighbor or address family");
1147 vty_out(vty
, "%s%s",
1148 json_object_to_json_string(json_no
),
1150 json_object_free(json_no
);
1153 "%% No such neighbor or address family%s",
1157 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_IP
,
1163 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
1164 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
1165 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-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 the routes advertised to a BGP neighbor\n"
1177 int idx_ext_community
= 5;
1181 struct prefix_rd prd
;
1183 u_char uj
= use_json(argc
, argv
);
1187 if (argv_find_and_parse_vpnvx(argv
, argc
, &idx
, &afi
)) {
1188 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1191 json_object
*json_no
= NULL
;
1192 json_no
= json_object_new_object();
1193 json_object_string_add(json_no
, "warning",
1194 "Malformed address");
1195 vty_out(vty
, "%s%s",
1196 json_object_to_json_string(json_no
),
1198 json_object_free(json_no
);
1200 vty_out(vty
, "Malformed address: %s%s",
1201 argv
[idx_ext_community
]->arg
,
1205 peer
= peer_lookup(NULL
, &su
);
1206 if (!peer
|| !peer
->afc
[afi
][SAFI_MPLS_VPN
]) {
1208 json_object
*json_no
= NULL
;
1209 json_no
= json_object_new_object();
1210 json_object_string_add(
1212 "No such neighbor or address family");
1213 vty_out(vty
, "%s%s",
1214 json_object_to_json_string(json_no
),
1216 json_object_free(json_no
);
1219 "%% No such neighbor or address family%s",
1224 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1227 json_object
*json_no
= NULL
;
1228 json_no
= json_object_new_object();
1229 json_object_string_add(
1231 "Malformed Route Distinguisher");
1232 vty_out(vty
, "%s%s",
1233 json_object_to_json_string(json_no
),
1235 json_object_free(json_no
);
1238 "%% Malformed Route Distinguisher%s",
1243 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_IP
,
1248 #endif /* KEEP_OLD_VPN_COMMANDS */
1250 void bgp_mplsvpn_init(void)
1252 install_element(BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1253 install_element(BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1254 install_element(BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1256 install_element(BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
1257 install_element(BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
1259 install_element(VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
1260 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1261 #ifdef KEEP_OLD_VPN_COMMANDS
1262 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
1263 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
1264 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
1265 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
1266 install_element(VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
1267 install_element(VIEW_NODE
,
1268 &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
1269 install_element(VIEW_NODE
,
1270 &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
1271 #endif /* KEEP_OLD_VPN_COMMANDS */