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"
45 argv_find_and_parse_vpnvx(struct cmd_token
**argv
, int argc
, int *index
, afi_t
*afi
)
48 if (argv_find (argv
, argc
, "vpnv4", index
))
54 else if (argv_find (argv
, argc
, "vpnv6", index
))
64 decode_rd_type (u_char
*pnt
)
68 v
= ((u_int16_t
) *pnt
++ << 8);
71 * VNC L2 stores LHI in lower byte, so omit it
73 if (v
!= RD_TYPE_VNC_ETH
)
74 v
|= (u_int16_t
) *pnt
;
75 #else /* duplicate code for clarity */
76 v
|= (u_int16_t
) *pnt
;
83 encode_rd_type (u_int16_t v
, u_char
*pnt
)
85 *((u_int16_t
*)pnt
) = htons(v
);
89 decode_label (u_char
*pnt
)
93 l
= ((u_int32_t
) *pnt
++ << 12);
94 l
|= (u_int32_t
) *pnt
++ << 4;
95 l
|= (u_int32_t
) ((*pnt
& 0xf0) >> 4);
100 encode_label(u_int32_t label
,
105 *pnt
++ = (label
>>12) & 0xff;
106 *pnt
++ = (label
>>4) & 0xff;
107 *pnt
++ = ((label
<<4)+1) & 0xff; /* S=1 */
110 /* type == RD_TYPE_AS */
112 decode_rd_as (u_char
*pnt
, struct rd_as
*rd_as
)
114 rd_as
->as
= (u_int16_t
) *pnt
++ << 8;
115 rd_as
->as
|= (u_int16_t
) *pnt
++;
117 rd_as
->val
= ((u_int32_t
) *pnt
++ << 24);
118 rd_as
->val
|= ((u_int32_t
) *pnt
++ << 16);
119 rd_as
->val
|= ((u_int32_t
) *pnt
++ << 8);
120 rd_as
->val
|= (u_int32_t
) *pnt
;
123 /* type == RD_TYPE_AS4 */
125 decode_rd_as4 (u_char
*pnt
, struct rd_as
*rd_as
)
127 rd_as
->as
= (u_int32_t
) *pnt
++ << 24;
128 rd_as
->as
|= (u_int32_t
) *pnt
++ << 16;
129 rd_as
->as
|= (u_int32_t
) *pnt
++ << 8;
130 rd_as
->as
|= (u_int32_t
) *pnt
++;
132 rd_as
->val
= ((u_int16_t
) *pnt
++ << 8);
133 rd_as
->val
|= (u_int16_t
) *pnt
;
136 /* type == RD_TYPE_IP */
138 decode_rd_ip (u_char
*pnt
, struct rd_ip
*rd_ip
)
140 memcpy (&rd_ip
->ip
, pnt
, 4);
143 rd_ip
->val
= ((u_int16_t
) *pnt
++ << 8);
144 rd_ip
->val
|= (u_int16_t
) *pnt
;
148 /* type == RD_TYPE_VNC_ETH */
150 decode_rd_vnc_eth (u_char
*pnt
, struct rd_vnc_eth
*rd_vnc_eth
)
152 rd_vnc_eth
->type
= RD_TYPE_VNC_ETH
;
153 rd_vnc_eth
->local_nve_id
= pnt
[1];
154 memcpy (rd_vnc_eth
->macaddr
.octet
, pnt
+ 2, ETHER_ADDR_LEN
);
159 bgp_nlri_parse_vpn (struct peer
*peer
, struct attr
*attr
,
160 struct bgp_nlri
*packet
)
170 struct prefix_rd prd
;
175 u_int32_t addpath_id
;
180 /* Check peer status. */
181 if (peer
->status
!= Established
)
185 prd
.family
= AF_UNSPEC
;
189 lim
= pnt
+ packet
->length
;
194 addpath_encoded
= (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
195 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
197 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
198 for (; pnt
< lim
; pnt
+= psize
)
200 /* Clear prefix structure. */
201 memset (&p
, 0, sizeof (struct prefix
));
206 /* When packet overflow occurs return immediately. */
207 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
210 addpath_id
= ntohl(*((uint32_t*) pnt
));
211 pnt
+= BGP_ADDPATH_ID_LEN
;
214 /* Fetch prefix length. */
216 p
.family
= afi2family (packet
->afi
);
217 psize
= PSIZE (prefixlen
);
219 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
*8)
221 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
222 peer
->host
, prefixlen
);
226 /* sanity check against packet data */
227 if ((pnt
+ psize
) > lim
)
229 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
231 prefixlen
, (uint
)(lim
-pnt
));
235 /* sanity check against storage for the IP address portion */
236 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
) sizeof(p
.u
))
238 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
240 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8, sizeof(p
.u
));
244 /* Sanity check against max bitlen of the address family */
245 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen (&p
))
247 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
249 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8,
250 p
.family
, prefix_blen (&p
));
255 label
= decode_label (pnt
);
258 /* Copyr label to prefix. */
261 /* Copy routing distinguisher to rd. */
262 memcpy (&prd
.val
, pnt
+ 3, 8);
264 /* Decode RD type. */
265 type
= decode_rd_type (pnt
+ 3);
270 decode_rd_as (pnt
+ 5, &rd_as
);
274 decode_rd_as4 (pnt
+ 5, &rd_as
);
278 decode_rd_ip (pnt
+ 5, &rd_ip
);
282 case RD_TYPE_VNC_ETH
:
287 zlog_err ("Unknown RD type %d", type
);
288 break; /* just report */
291 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8;/* exclude label & RD */
292 memcpy (&p
.u
.prefix
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
293 psize
- VPN_PREFIXLEN_MIN_BYTES
);
297 bgp_update (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
298 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
, 0);
300 rfapiProcessUpdate(peer
, NULL
, &p
, &prd
, attr
, packet
->afi
,
301 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
308 rfapiProcessWithdraw(peer
, NULL
, &p
, &prd
, attr
, packet
->afi
,
309 SAFI_MPLS_VPN
, ZEBRA_ROUTE_BGP
, 0);
311 bgp_withdraw (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
312 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
);
315 /* Packet length consistency check. */
318 zlog_err ("%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
319 peer
->host
, lim
- pnt
);
324 #undef VPN_PREFIXLEN_MIN_BYTES
328 str2prefix_rd (const char *str
, struct prefix_rd
*prd
)
330 int ret
; /* ret of called functions */
331 int lret
; /* local ret, of this func */
334 struct stream
*s
= NULL
;
340 prd
->family
= AF_UNSPEC
;
344 p
= strchr (str
, ':');
348 if (! all_digit (p
+ 1))
351 half
= XMALLOC (MTYPE_TMP
, (p
- str
) + 1);
352 memcpy (half
, str
, (p
- str
));
353 half
[p
- str
] = '\0';
355 p2
= strchr (str
, '.');
359 unsigned long as_val
;
361 if (! all_digit (half
))
367 stream_putw (s
, RD_TYPE_AS4
);
368 stream_putl (s
, as_val
);
369 stream_putw (s
, atol (p
+ 1));
373 stream_putw (s
, RD_TYPE_AS
);
374 stream_putw (s
, as_val
);
375 stream_putl (s
, atol (p
+ 1));
380 ret
= inet_aton (half
, &addr
);
384 stream_putw (s
, RD_TYPE_IP
);
385 stream_put_in_addr (s
, &addr
);
386 stream_putw (s
, atol (p
+ 1));
388 memcpy (prd
->val
, s
->data
, 8);
395 XFREE(MTYPE_TMP
, half
);
400 str2tag (const char *str
, u_char
*tag
)
410 l
= strtoul (str
, &endptr
, 10);
412 if (*endptr
!= '\0' || errno
|| l
> UINT32_MAX
)
417 tag
[0] = (u_char
)(t
>> 12);
418 tag
[1] = (u_char
)(t
>> 4);
419 tag
[2] = (u_char
)(t
<< 4);
425 prefix_rd2str (struct prefix_rd
*prd
, char *buf
, size_t size
)
432 if (size
< RD_ADDRSTRLEN
)
437 type
= decode_rd_type (pnt
);
439 if (type
== RD_TYPE_AS
)
441 decode_rd_as (pnt
+ 2, &rd_as
);
442 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
445 else if (type
== RD_TYPE_AS4
)
447 decode_rd_as4 (pnt
+ 2, &rd_as
);
448 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
451 else if (type
== RD_TYPE_IP
)
453 decode_rd_ip (pnt
+ 2, &rd_ip
);
454 snprintf (buf
, size
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
458 else if (type
== RD_TYPE_VNC_ETH
)
460 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
462 *(pnt
+2), /* MAC[0] */
475 /* For testing purpose, static route of MPLS-VPN. */
476 DEFUN (vpnv4_network
,
478 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
479 "Specify a network to announce via BGP\n"
481 "Specify Route Distinguisher\n"
482 "VPN Route Distinguisher\n"
486 int idx_ipv4_prefixlen
= 1;
487 int idx_ext_community
= 3;
489 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, NULL
);
492 DEFUN (vpnv4_network_route_map
,
493 vpnv4_network_route_map_cmd
,
494 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
495 "Specify a network to announce via BGP\n"
497 "Specify Route Distinguisher\n"
498 "VPN Route Distinguisher\n"
504 int idx_ipv4_prefixlen
= 1;
505 int idx_ext_community
= 3;
508 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
);
511 /* For testing purpose, static route of MPLS-VPN. */
512 DEFUN (no_vpnv4_network
,
513 no_vpnv4_network_cmd
,
514 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
516 "Specify a network to announce via BGP\n"
518 "Specify Route Distinguisher\n"
519 "VPN Route Distinguisher\n"
523 int idx_ipv4_prefixlen
= 2;
524 int idx_ext_community
= 4;
526 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
529 DEFUN (vpnv6_network
,
531 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD [route-map WORD]",
532 "Specify a network to announce via BGP\n"
533 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
534 "Specify Route Distinguisher\n"
535 "VPN Route Distinguisher\n"
541 int idx_ipv6_prefix
= 1;
542 int idx_ext_community
= 3;
545 if (argv
[idx_word_2
])
546 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
);
548 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, NULL
);
551 /* For testing purpose, static route of MPLS-VPN. */
552 DEFUN (no_vpnv6_network
,
553 no_vpnv6_network_cmd
,
554 "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD",
556 "Specify a network to announce via BGP\n"
557 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
558 "Specify Route Distinguisher\n"
559 "VPN Route Distinguisher\n"
563 int idx_ipv6_prefix
= 2;
564 int idx_ext_community
= 4;
566 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
570 show_adj_route_vpn (struct vty
*vty
, struct peer
*peer
, struct prefix_rd
*prd
, u_char use_json
, afi_t afi
)
573 struct bgp_table
*table
;
579 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
580 json_object
*json
= NULL
;
581 json_object
*json_scode
= NULL
;
582 json_object
*json_ocode
= NULL
;
583 json_object
*json_routes
= NULL
;
584 json_object
*json_array
= NULL
;
586 bgp
= bgp_get_default ();
590 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
596 json_scode
= json_object_new_object();
597 json_ocode
= json_object_new_object();
598 json_routes
= json_object_new_object();
599 json
= json_object_new_object();
601 json_object_string_add(json_scode
, "suppressed", "s");
602 json_object_string_add(json_scode
, "damped", "d");
603 json_object_string_add(json_scode
, "history", "h");
604 json_object_string_add(json_scode
, "valid", "*");
605 json_object_string_add(json_scode
, "best", ">");
606 json_object_string_add(json_scode
, "internal", "i");
608 json_object_string_add(json_ocode
, "igp", "i");
609 json_object_string_add(json_ocode
, "egp", "e");
610 json_object_string_add(json_ocode
, "incomplete", "?");
613 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
614 rn
= bgp_route_next (rn
))
616 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
619 if ((table
= rn
->info
) != NULL
)
622 json_array
= json_object_new_array();
628 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
630 if ((attr
= rm
->info
) != NULL
)
636 json_object_int_add(json
, "bgpTableVersion", 0);
637 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
638 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
639 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
643 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
644 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
645 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
647 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
648 VTY_NEWLINE
, VTY_NEWLINE
);
649 vty_out (vty
, v4_header
, VTY_NEWLINE
);
658 struct rd_ip rd_ip
= {0};
660 struct rd_vnc_eth rd_vnc_eth
;
666 /* Decode RD type. */
667 type
= decode_rd_type (pnt
);
668 /* Decode RD value. */
669 if (type
== RD_TYPE_AS
)
670 decode_rd_as (pnt
+ 2, &rd_as
);
671 else if (type
== RD_TYPE_AS4
)
672 decode_rd_as4 (pnt
+ 2, &rd_as
);
673 else if (type
== RD_TYPE_IP
)
674 decode_rd_ip (pnt
+ 2, &rd_ip
);
676 else if (type
== RD_TYPE_VNC_ETH
)
677 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
683 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
684 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
685 else if (type
== RD_TYPE_IP
)
686 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
687 json_object_string_add(json_routes
, "routeDistinguisher", buffer
);
691 vty_out (vty
, "Route Distinguisher: ");
693 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
694 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
695 else if (type
== RD_TYPE_IP
)
696 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
698 else if (type
== RD_TYPE_VNC_ETH
)
699 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
700 rd_vnc_eth
.local_nve_id
,
701 rd_vnc_eth
.macaddr
.octet
[0],
702 rd_vnc_eth
.macaddr
.octet
[1],
703 rd_vnc_eth
.macaddr
.octet
[2],
704 rd_vnc_eth
.macaddr
.octet
[3],
705 rd_vnc_eth
.macaddr
.octet
[4],
706 rd_vnc_eth
.macaddr
.octet
[5]);
709 vty_out (vty
, "%s", VTY_NEWLINE
);
713 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_MPLS_VPN
, use_json
, json_array
);
722 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
723 json_object_object_add(json_routes
, buf_a
, json_array
);
729 json_object_object_add(json
, "routes", json_routes
);
730 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
731 json_object_free(json
);
738 bgp_show_type_normal
,
739 bgp_show_type_regexp
,
740 bgp_show_type_prefix_list
,
741 bgp_show_type_filter_list
,
742 bgp_show_type_neighbor
,
743 bgp_show_type_cidr_only
,
744 bgp_show_type_prefix_longer
,
745 bgp_show_type_community_all
,
746 bgp_show_type_community
,
747 bgp_show_type_community_exact
,
748 bgp_show_type_community_list
,
749 bgp_show_type_community_list_exact
753 bgp_show_mpls_vpn (struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
754 enum bgp_show_type type
, void *output_arg
, int tags
, u_char use_json
)
757 struct bgp_table
*table
;
763 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
764 char v4_header_tag
[] = " Network Next Hop In tag/Out tag%s";
765 unsigned long output_count
= 0;
766 unsigned long total_count
= 0;
767 json_object
*json
= NULL
;
768 json_object
*json_mroute
= NULL
;
769 json_object
*json_nroute
= NULL
;
770 json_object
*json_array
= NULL
;
771 json_object
*json_scode
= NULL
;
772 json_object
*json_ocode
= NULL
;
774 bgp
= bgp_get_default ();
778 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
784 json_scode
= json_object_new_object();
785 json_ocode
= json_object_new_object();
786 json
= json_object_new_object();
787 json_mroute
= json_object_new_object();
788 json_nroute
= json_object_new_object();
790 json_object_string_add(json_scode
, "suppressed", "s");
791 json_object_string_add(json_scode
, "damped", "d");
792 json_object_string_add(json_scode
, "history", "h");
793 json_object_string_add(json_scode
, "valid", "*");
794 json_object_string_add(json_scode
, "best", ">");
795 json_object_string_add(json_scode
, "internal", "i");
797 json_object_string_add(json_ocode
, "igp", "i");
798 json_object_string_add(json_ocode
, "egp", "e");
799 json_object_string_add(json_ocode
, "incomplete", "?");
802 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
))
804 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
808 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
; rn
= bgp_route_next (rn
))
810 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
813 if ((table
= rn
->info
) != NULL
)
817 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
821 json_array
= json_object_new_array();
825 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
827 if (type
== bgp_show_type_neighbor
)
829 union sockunion
*su
= output_arg
;
831 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
840 json_object_int_add(json
, "bgpTableVersion", 0);
841 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
842 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
843 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
849 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
852 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
853 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
854 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
856 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
857 VTY_NEWLINE
, VTY_NEWLINE
);
858 vty_out (vty
, v4_header
, VTY_NEWLINE
);
868 struct rd_ip rd_ip
= {0};
870 struct rd_vnc_eth rd_vnc_eth
;
876 /* Decode RD type. */
877 type
= decode_rd_type (pnt
);
878 /* Decode RD value. */
879 if (type
== RD_TYPE_AS
)
880 decode_rd_as (pnt
+ 2, &rd_as
);
881 else if (type
== RD_TYPE_AS4
)
882 decode_rd_as4 (pnt
+ 2, &rd_as
);
883 else if (type
== RD_TYPE_IP
)
884 decode_rd_ip (pnt
+ 2, &rd_ip
);
886 else if (type
== RD_TYPE_VNC_ETH
)
887 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
893 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
894 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
895 else if (type
== RD_TYPE_IP
)
896 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
897 json_object_string_add(json_nroute
, "routeDistinguisher", buffer
);
901 vty_out (vty
, "Route Distinguisher: ");
903 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
904 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
905 else if (type
== RD_TYPE_IP
)
906 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
908 else if (type
== RD_TYPE_VNC_ETH
)
909 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
910 rd_vnc_eth
.local_nve_id
,
911 rd_vnc_eth
.macaddr
.octet
[0],
912 rd_vnc_eth
.macaddr
.octet
[1],
913 rd_vnc_eth
.macaddr
.octet
[2],
914 rd_vnc_eth
.macaddr
.octet
[3],
915 rd_vnc_eth
.macaddr
.octet
[4],
916 rd_vnc_eth
.macaddr
.octet
[5]);
918 vty_out (vty
, "%s", VTY_NEWLINE
);
923 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
925 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
935 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
936 json_object_object_add(json_mroute
, buf_a
, json_array
);
946 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
947 json_object_object_add(json_nroute
, buf_a
, json_mroute
);
954 json_object_object_add(json
, "routes", json_nroute
);
955 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
956 json_object_free(json
);
960 if (output_count
== 0)
961 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
963 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
964 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
970 DEFUN (show_bgp_ip_vpn_rd
,
971 show_bgp_ip_vpn_rd_cmd
,
972 "show [ip] bgp "BGP_AFI_CMD_STR
" vpn [rd ASN:nn_or_IP-address:nn] [json]",
977 "Display VPN NLRI specific information\n"
978 "Display information for a route distinguisher\n"
979 "VPN Route Distinguisher\n"
982 int idx_ext_community
= 5;
984 struct prefix_rd prd
;
988 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
990 if (argv
[idx_ext_community
]->arg
)
992 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
995 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
998 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
1002 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
1008 #ifdef KEEP_OLD_VPN_COMMANDS
1009 DEFUN (show_ip_bgp_vpn_all
,
1010 show_ip_bgp_vpn_all_cmd
,
1011 "show [ip] bgp <vpnv4|vpnv6>",
1020 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1021 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
1025 DEFUN (show_ip_bgp_vpn_rd
,
1026 show_ip_bgp_vpn_rd_cmd
,
1027 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn",
1032 "Display information for a route distinguisher\n"
1033 "VPN Route Distinguisher\n")
1035 int idx_ext_community
= 5;
1037 struct prefix_rd prd
;
1041 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1043 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1046 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1049 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 0, 0);
1054 DEFUN (show_ip_bgp_vpn_all_tags
,
1055 show_ip_bgp_vpn_all_tags_cmd
,
1056 "show [ip] bgp <vpnv4|vpnv6> all tags",
1061 "Display information about all VPNv4/VPNV6 NLRIs\n"
1062 "Display BGP tags for prefixes\n")
1067 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1068 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 1, 0);
1072 DEFUN (show_ip_bgp_vpn_rd_tags
,
1073 show_ip_bgp_vpn_rd_tags_cmd
,
1074 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
1079 "Display information for a route distinguisher\n"
1080 "VPN Route Distinguisher\n"
1081 "Display BGP tags for prefixes\n")
1083 int idx_ext_community
= 5;
1085 struct prefix_rd prd
;
1089 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1091 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1094 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1097 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 1, 0);
1102 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1103 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1104 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1109 "Display information about all VPNv4/VPNv6 NLRIs\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"
1119 u_char uj
= use_json(argc
, argv
);
1123 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1125 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1130 json_object
*json_no
= NULL
;
1131 json_no
= json_object_new_object();
1132 json_object_string_add(json_no
, "warning", "Malformed address");
1133 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1134 json_object_free(json_no
);
1137 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1141 peer
= peer_lookup (NULL
, &su
);
1142 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1146 json_object
*json_no
= NULL
;
1147 json_no
= json_object_new_object();
1148 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1149 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1150 json_object_free(json_no
);
1153 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1157 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
1162 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1163 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1164 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
1169 "Display information for a route distinguisher\n"
1170 "VPN Route Distinguisher\n"
1171 "Detailed information on TCP and BGP neighbor connections\n"
1172 "Neighbor to display information about\n"
1173 "Display routes learned from neighbor\n"
1176 int idx_ext_community
= 5;
1181 struct prefix_rd prd
;
1182 u_char uj
= use_json(argc
, argv
);
1186 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1188 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1193 json_object
*json_no
= NULL
;
1194 json_no
= json_object_new_object();
1195 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1196 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1197 json_object_free(json_no
);
1200 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1204 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1209 json_object
*json_no
= NULL
;
1210 json_no
= json_object_new_object();
1211 json_object_string_add(json_no
, "warning", "Malformed address");
1212 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1213 json_object_free(json_no
);
1216 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1220 peer
= peer_lookup (NULL
, &su
);
1221 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1225 json_object
*json_no
= NULL
;
1226 json_no
= json_object_new_object();
1227 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1228 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1229 json_object_free(json_no
);
1232 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1236 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
1241 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1242 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
1243 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1248 "Display information about all VPNv4/VPNv6 NLRIs\n"
1249 "Detailed information on TCP and BGP neighbor connections\n"
1250 "Neighbor to display information about\n"
1251 "Display the routes advertised to a BGP neighbor\n"
1258 u_char uj
= use_json(argc
, argv
);
1262 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1264 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1269 json_object
*json_no
= NULL
;
1270 json_no
= json_object_new_object();
1271 json_object_string_add(json_no
, "warning", "Malformed address");
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
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1279 peer
= peer_lookup (NULL
, &su
);
1280 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1284 json_object
*json_no
= NULL
;
1285 json_no
= json_object_new_object();
1286 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1287 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1288 json_object_free(json_no
);
1291 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1295 return show_adj_route_vpn (vty
, peer
, NULL
, uj
, afi
);
1300 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
1301 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
1302 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1307 "Display information for a route distinguisher\n"
1308 "VPN Route Distinguisher\n"
1309 "Detailed information on TCP and BGP neighbor connections\n"
1310 "Neighbor to display information about\n"
1311 "Display the routes advertised to a BGP neighbor\n"
1314 int idx_ext_community
= 5;
1318 struct prefix_rd prd
;
1320 u_char uj
= use_json(argc
, argv
);
1324 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1326 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1331 json_object
*json_no
= NULL
;
1332 json_no
= json_object_new_object();
1333 json_object_string_add(json_no
, "warning", "Malformed address");
1334 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1335 json_object_free(json_no
);
1338 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1341 peer
= peer_lookup (NULL
, &su
);
1342 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1346 json_object
*json_no
= NULL
;
1347 json_no
= json_object_new_object();
1348 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1349 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1350 json_object_free(json_no
);
1353 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1357 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1362 json_object
*json_no
= NULL
;
1363 json_no
= json_object_new_object();
1364 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1365 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1366 json_object_free(json_no
);
1369 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1373 return show_adj_route_vpn (vty
, peer
, &prd
, uj
, afi
);
1377 #endif /* KEEP_OLD_VPN_COMMANDS */
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 #ifdef KEEP_OLD_VPN_COMMANDS
1391 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
1392 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1393 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
1394 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
1395 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
1396 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
1397 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
1398 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
1399 #endif /* KEEP_OLD_VPN_COMMANDS */