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
;
177 /* Check peer status. */
178 if (peer
->status
!= Established
)
182 prd
.family
= AF_UNSPEC
;
186 lim
= pnt
+ packet
->length
;
191 addpath_encoded
= (CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
) &&
192 CHECK_FLAG (peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_TX_RCV
));
194 #define VPN_PREFIXLEN_MIN_BYTES (3 + 8) /* label + RD */
195 for (; pnt
< lim
; pnt
+= psize
)
197 /* Clear prefix structure. */
198 memset (&p
, 0, sizeof (struct prefix
));
203 /* When packet overflow occurs return immediately. */
204 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
207 addpath_id
= ntohl(*((uint32_t*) pnt
));
208 pnt
+= BGP_ADDPATH_ID_LEN
;
211 /* Fetch prefix length. */
213 p
.family
= afi2family (packet
->afi
);
214 psize
= PSIZE (prefixlen
);
216 if (prefixlen
< VPN_PREFIXLEN_MIN_BYTES
*8)
218 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
219 peer
->host
, prefixlen
);
223 /* sanity check against packet data */
224 if ((pnt
+ psize
) > lim
)
226 zlog_err ("%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
228 prefixlen
, (uint
)(lim
-pnt
));
232 /* sanity check against storage for the IP address portion */
233 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > (ssize_t
) sizeof(p
.u
))
235 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds storage size %zu)",
237 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8, sizeof(p
.u
));
241 /* Sanity check against max bitlen of the address family */
242 if ((psize
- VPN_PREFIXLEN_MIN_BYTES
) > prefix_blen (&p
))
244 zlog_err ("%s [Error] Update packet error / VPN (psize %d exceeds family (%u) max byte len %u)",
246 prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8,
247 p
.family
, prefix_blen (&p
));
251 /* Copyr label to prefix. */
254 /* Copy routing distinguisher to rd. */
255 memcpy (&prd
.val
, pnt
+ 3, 8);
257 /* Decode RD type. */
258 type
= decode_rd_type (pnt
+ 3);
263 decode_rd_as (pnt
+ 5, &rd_as
);
267 decode_rd_as4 (pnt
+ 5, &rd_as
);
271 decode_rd_ip (pnt
+ 5, &rd_ip
);
275 case RD_TYPE_VNC_ETH
:
280 zlog_err ("Unknown RD type %d", type
);
281 break; /* just report */
284 p
.prefixlen
= prefixlen
- VPN_PREFIXLEN_MIN_BYTES
*8;/* exclude label & RD */
285 memcpy (&p
.u
.prefix
, pnt
+ VPN_PREFIXLEN_MIN_BYTES
,
286 psize
- VPN_PREFIXLEN_MIN_BYTES
);
290 bgp_update (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
291 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
, 0);
295 bgp_withdraw (peer
, &p
, addpath_id
, attr
, packet
->afi
, SAFI_MPLS_VPN
,
296 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, &prd
, tagpnt
);
299 /* Packet length consistency check. */
302 zlog_err ("%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
303 peer
->host
, lim
- pnt
);
308 #undef VPN_PREFIXLEN_MIN_BYTES
312 str2prefix_rd (const char *str
, struct prefix_rd
*prd
)
314 int ret
; /* ret of called functions */
315 int lret
; /* local ret, of this func */
318 struct stream
*s
= NULL
;
324 prd
->family
= AF_UNSPEC
;
328 p
= strchr (str
, ':');
332 if (! all_digit (p
+ 1))
335 half
= XMALLOC (MTYPE_TMP
, (p
- str
) + 1);
336 memcpy (half
, str
, (p
- str
));
337 half
[p
- str
] = '\0';
339 p2
= strchr (str
, '.');
343 unsigned long as_val
;
345 if (! all_digit (half
))
351 stream_putw (s
, RD_TYPE_AS4
);
352 stream_putl (s
, as_val
);
353 stream_putw (s
, atol (p
+ 1));
357 stream_putw (s
, RD_TYPE_AS
);
358 stream_putw (s
, as_val
);
359 stream_putl (s
, atol (p
+ 1));
364 ret
= inet_aton (half
, &addr
);
368 stream_putw (s
, RD_TYPE_IP
);
369 stream_put_in_addr (s
, &addr
);
370 stream_putw (s
, atol (p
+ 1));
372 memcpy (prd
->val
, s
->data
, 8);
379 XFREE(MTYPE_TMP
, half
);
384 str2tag (const char *str
, u_char
*tag
)
394 l
= strtoul (str
, &endptr
, 10);
396 if (*endptr
!= '\0' || errno
|| l
> UINT32_MAX
)
401 tag
[0] = (u_char
)(t
>> 12);
402 tag
[1] = (u_char
)(t
>> 4);
403 tag
[2] = (u_char
)(t
<< 4);
409 prefix_rd2str (struct prefix_rd
*prd
, char *buf
, size_t size
)
416 if (size
< RD_ADDRSTRLEN
)
421 type
= decode_rd_type (pnt
);
423 if (type
== RD_TYPE_AS
)
425 decode_rd_as (pnt
+ 2, &rd_as
);
426 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
429 else if (type
== RD_TYPE_AS4
)
431 decode_rd_as4 (pnt
+ 2, &rd_as
);
432 snprintf (buf
, size
, "%u:%d", rd_as
.as
, rd_as
.val
);
435 else if (type
== RD_TYPE_IP
)
437 decode_rd_ip (pnt
+ 2, &rd_ip
);
438 snprintf (buf
, size
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
442 else if (type
== RD_TYPE_VNC_ETH
)
444 snprintf(buf
, size
, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
446 *(pnt
+2), /* MAC[0] */
459 /* For testing purpose, static route of MPLS-VPN. */
460 DEFUN (vpnv4_network
,
462 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
463 "Specify a network to announce via BGP\n"
465 "Specify Route Distinguisher\n"
466 "VPN Route Distinguisher\n"
470 int idx_ipv4_prefixlen
= 1;
471 int idx_ext_community
= 3;
473 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, NULL
);
476 DEFUN (vpnv4_network_route_map
,
477 vpnv4_network_route_map_cmd
,
478 "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
479 "Specify a network to announce via BGP\n"
481 "Specify Route Distinguisher\n"
482 "VPN Route Distinguisher\n"
488 int idx_ipv4_prefixlen
= 1;
489 int idx_ext_community
= 3;
492 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
);
495 /* For testing purpose, static route of MPLS-VPN. */
496 DEFUN (no_vpnv4_network
,
497 no_vpnv4_network_cmd
,
498 "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD",
500 "Specify a network to announce via BGP\n"
502 "Specify Route Distinguisher\n"
503 "VPN Route Distinguisher\n"
507 int idx_ipv4_prefixlen
= 2;
508 int idx_ext_community
= 4;
510 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
513 DEFUN (vpnv6_network
,
515 "network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD [route-map WORD]",
516 "Specify a network to announce via BGP\n"
517 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
518 "Specify Route Distinguisher\n"
519 "VPN Route Distinguisher\n"
525 int idx_ipv6_prefix
= 1;
526 int idx_ext_community
= 3;
529 if (argv
[idx_word_2
])
530 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
);
532 return bgp_static_set_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
, NULL
);
535 /* For testing purpose, static route of MPLS-VPN. */
536 DEFUN (no_vpnv6_network
,
537 no_vpnv6_network_cmd
,
538 "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn tag WORD",
540 "Specify a network to announce via BGP\n"
541 "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
542 "Specify Route Distinguisher\n"
543 "VPN Route Distinguisher\n"
547 int idx_ipv6_prefix
= 2;
548 int idx_ext_community
= 4;
550 return bgp_static_unset_safi (SAFI_MPLS_VPN
, vty
, argv
[idx_ipv6_prefix
]->arg
, argv
[idx_ext_community
]->arg
, argv
[idx_word
]->arg
);
553 #if defined(KEEP_OLD_VPN_COMMANDS)
555 show_adj_route_vpn (struct vty
*vty
, struct peer
*peer
, struct prefix_rd
*prd
, u_char use_json
, afi_t afi
)
558 struct bgp_table
*table
;
564 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
565 json_object
*json
= NULL
;
566 json_object
*json_scode
= NULL
;
567 json_object
*json_ocode
= NULL
;
568 json_object
*json_routes
= NULL
;
569 json_object
*json_array
= NULL
;
571 bgp
= bgp_get_default ();
575 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
581 json_scode
= json_object_new_object();
582 json_ocode
= json_object_new_object();
583 json_routes
= json_object_new_object();
584 json
= json_object_new_object();
586 json_object_string_add(json_scode
, "suppressed", "s");
587 json_object_string_add(json_scode
, "damped", "d");
588 json_object_string_add(json_scode
, "history", "h");
589 json_object_string_add(json_scode
, "valid", "*");
590 json_object_string_add(json_scode
, "best", ">");
591 json_object_string_add(json_scode
, "internal", "i");
593 json_object_string_add(json_ocode
, "igp", "i");
594 json_object_string_add(json_ocode
, "egp", "e");
595 json_object_string_add(json_ocode
, "incomplete", "?");
598 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
;
599 rn
= bgp_route_next (rn
))
601 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
604 if ((table
= rn
->info
) != NULL
)
607 json_array
= json_object_new_array();
613 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
615 if ((attr
= rm
->info
) != NULL
)
621 json_object_int_add(json
, "bgpTableVersion", 0);
622 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
623 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
624 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
628 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
629 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
630 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
632 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
633 VTY_NEWLINE
, VTY_NEWLINE
);
634 vty_out (vty
, v4_header
, VTY_NEWLINE
);
643 struct rd_ip rd_ip
= {0};
645 struct rd_vnc_eth rd_vnc_eth
= {0};
651 /* Decode RD type. */
652 type
= decode_rd_type (pnt
);
653 /* Decode RD value. */
654 if (type
== RD_TYPE_AS
)
655 decode_rd_as (pnt
+ 2, &rd_as
);
656 else if (type
== RD_TYPE_AS4
)
657 decode_rd_as4 (pnt
+ 2, &rd_as
);
658 else if (type
== RD_TYPE_IP
)
659 decode_rd_ip (pnt
+ 2, &rd_ip
);
661 else if (type
== RD_TYPE_VNC_ETH
)
662 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
668 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
669 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
670 else if (type
== RD_TYPE_IP
)
671 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
672 json_object_string_add(json_routes
, "routeDistinguisher", buffer
);
676 vty_out (vty
, "Route Distinguisher: ");
678 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
679 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
680 else if (type
== RD_TYPE_IP
)
681 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
683 else if (type
== RD_TYPE_VNC_ETH
)
684 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
685 rd_vnc_eth
.local_nve_id
,
686 rd_vnc_eth
.macaddr
.octet
[0],
687 rd_vnc_eth
.macaddr
.octet
[1],
688 rd_vnc_eth
.macaddr
.octet
[2],
689 rd_vnc_eth
.macaddr
.octet
[3],
690 rd_vnc_eth
.macaddr
.octet
[4],
691 rd_vnc_eth
.macaddr
.octet
[5]);
694 vty_out (vty
, "%s", VTY_NEWLINE
);
698 route_vty_out_tmp (vty
, &rm
->p
, attr
, SAFI_MPLS_VPN
, use_json
, json_array
);
707 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
708 json_object_object_add(json_routes
, buf_a
, json_array
);
714 json_object_object_add(json
, "routes", json_routes
);
715 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
716 json_object_free(json
);
723 bgp_show_mpls_vpn (struct vty
*vty
, afi_t afi
, struct prefix_rd
*prd
,
724 enum bgp_show_type type
, void *output_arg
, int tags
, u_char use_json
)
727 struct bgp_table
*table
;
733 char v4_header
[] = " Network Next Hop Metric LocPrf Weight Path%s";
734 char v4_header_tag
[] = " Network Next Hop In tag/Out tag%s";
735 unsigned long output_count
= 0;
736 unsigned long total_count
= 0;
737 json_object
*json
= NULL
;
738 json_object
*json_mroute
= NULL
;
739 json_object
*json_nroute
= NULL
;
740 json_object
*json_array
= NULL
;
741 json_object
*json_scode
= NULL
;
742 json_object
*json_ocode
= NULL
;
744 bgp
= bgp_get_default ();
748 vty_out (vty
, "No BGP process is configured%s", VTY_NEWLINE
);
754 json_scode
= json_object_new_object();
755 json_ocode
= json_object_new_object();
756 json
= json_object_new_object();
757 json_mroute
= json_object_new_object();
758 json_nroute
= json_object_new_object();
760 json_object_string_add(json_scode
, "suppressed", "s");
761 json_object_string_add(json_scode
, "damped", "d");
762 json_object_string_add(json_scode
, "history", "h");
763 json_object_string_add(json_scode
, "valid", "*");
764 json_object_string_add(json_scode
, "best", ">");
765 json_object_string_add(json_scode
, "internal", "i");
767 json_object_string_add(json_ocode
, "igp", "i");
768 json_object_string_add(json_ocode
, "egp", "e");
769 json_object_string_add(json_ocode
, "incomplete", "?");
772 if ((afi
!= AFI_IP
) && (afi
!= AFI_IP6
))
774 vty_out (vty
, "Afi %d not supported%s", afi
, VTY_NEWLINE
);
778 for (rn
= bgp_table_top (bgp
->rib
[afi
][SAFI_MPLS_VPN
]); rn
; rn
= bgp_route_next (rn
))
780 if (prd
&& memcmp (rn
->p
.u
.val
, prd
->val
, 8) != 0)
783 if ((table
= rn
->info
) != NULL
)
787 for (rm
= bgp_table_top (table
); rm
; rm
= bgp_route_next (rm
))
791 json_array
= json_object_new_array();
795 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
797 if (type
== bgp_show_type_neighbor
)
799 union sockunion
*su
= output_arg
;
801 if (ri
->peer
->su_remote
== NULL
|| ! sockunion_same(ri
->peer
->su_remote
, su
))
810 json_object_int_add(json
, "bgpTableVersion", 0);
811 json_object_string_add(json
, "bgpLocalRouterId", inet_ntoa (bgp
->router_id
));
812 json_object_object_add(json
, "bgpStatusCodes", json_scode
);
813 json_object_object_add(json
, "bgpOriginCodes", json_ocode
);
819 vty_out (vty
, v4_header_tag
, VTY_NEWLINE
);
822 vty_out (vty
, "BGP table version is 0, local router ID is %s%s",
823 inet_ntoa (bgp
->router_id
), VTY_NEWLINE
);
824 vty_out (vty
, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
826 vty_out (vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
827 VTY_NEWLINE
, VTY_NEWLINE
);
828 vty_out (vty
, v4_header
, VTY_NEWLINE
);
838 struct rd_ip rd_ip
= {0};
840 struct rd_vnc_eth rd_vnc_eth
= {0};
846 /* Decode RD type. */
847 type
= decode_rd_type (pnt
);
848 /* Decode RD value. */
849 if (type
== RD_TYPE_AS
)
850 decode_rd_as (pnt
+ 2, &rd_as
);
851 else if (type
== RD_TYPE_AS4
)
852 decode_rd_as4 (pnt
+ 2, &rd_as
);
853 else if (type
== RD_TYPE_IP
)
854 decode_rd_ip (pnt
+ 2, &rd_ip
);
856 else if (type
== RD_TYPE_VNC_ETH
)
857 decode_rd_vnc_eth (pnt
, &rd_vnc_eth
);
863 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
864 sprintf (buffer
, "%u:%d", rd_as
.as
, rd_as
.val
);
865 else if (type
== RD_TYPE_IP
)
866 sprintf (buffer
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
867 json_object_string_add(json_nroute
, "routeDistinguisher", buffer
);
871 vty_out (vty
, "Route Distinguisher: ");
873 if (type
== RD_TYPE_AS
|| type
== RD_TYPE_AS4
)
874 vty_out (vty
, "%u:%d", rd_as
.as
, rd_as
.val
);
875 else if (type
== RD_TYPE_IP
)
876 vty_out (vty
, "%s:%d", inet_ntoa (rd_ip
.ip
), rd_ip
.val
);
878 else if (type
== RD_TYPE_VNC_ETH
)
879 vty_out (vty
, "%u:%02x:%02x:%02x:%02x:%02x:%02x",
880 rd_vnc_eth
.local_nve_id
,
881 rd_vnc_eth
.macaddr
.octet
[0],
882 rd_vnc_eth
.macaddr
.octet
[1],
883 rd_vnc_eth
.macaddr
.octet
[2],
884 rd_vnc_eth
.macaddr
.octet
[3],
885 rd_vnc_eth
.macaddr
.octet
[4],
886 rd_vnc_eth
.macaddr
.octet
[5]);
888 vty_out (vty
, "%s", VTY_NEWLINE
);
893 route_vty_out_tag (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
895 route_vty_out (vty
, &rm
->p
, ri
, 0, SAFI_MPLS_VPN
, json_array
);
905 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
906 json_object_object_add(json_mroute
, buf_a
, json_array
);
916 sprintf(buf_a
, "%s/%d", inet_ntop (p
->family
, &p
->u
.prefix
, buf_b
, BUFSIZ
), p
->prefixlen
);
917 json_object_object_add(json_nroute
, buf_a
, json_mroute
);
924 json_object_object_add(json
, "routes", json_nroute
);
925 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
926 json_object_free(json
);
930 if (output_count
== 0)
931 vty_out (vty
, "No prefixes displayed, %ld exist%s", total_count
, VTY_NEWLINE
);
933 vty_out (vty
, "%sDisplayed %ld routes and %ld total paths%s",
934 VTY_NEWLINE
, output_count
, total_count
, VTY_NEWLINE
);
940 #ifdef KEEP_OLD_VPN_COMMANDS
941 DEFUN (show_ip_bgp_vpn_all
,
942 show_ip_bgp_vpn_all_cmd
,
943 "show [ip] bgp <vpnv4|vpnv6>",
952 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
953 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
959 DEFUN (show_bgp_ip_vpn_all_rd
,
960 show_bgp_ip_vpn_all_rd_cmd
,
961 "show bgp "BGP_AFI_CMD_STR
" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
966 "Display VPN NLRI specific information\n"
967 "Display information for a route distinguisher\n"
968 "VPN Route Distinguisher\n"
973 struct prefix_rd prd
;
977 if (argv_find_and_parse_afi (argv
, argc
, &idx
, &afi
))
979 if (argc
>= 7 && argv
[idx_rd
]->arg
)
981 ret
= str2prefix_rd (argv
[idx_rd
]->arg
, &prd
);
984 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
987 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
991 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, use_json (argc
, argv
));
997 DEFUN (show_ip_bgp_vpn_rd
,
998 show_ip_bgp_vpn_rd_cmd
,
999 "show [ip] bgp "BGP_AFI_CMD_STR
" vpn rd ASN:nn_or_IP-address:nn",
1004 "Address Family modifier\n"
1005 "Display information for a route distinguisher\n"
1006 "VPN Route Distinguisher\n")
1008 int idx_ext_community
= argc
-1;
1010 struct prefix_rd prd
;
1014 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1016 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1019 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1022 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 0, 0);
1027 #ifdef KEEP_OLD_VPN_COMMANDS
1028 DEFUN (show_ip_bgp_vpn_all
,
1029 show_ip_bgp_vpn_all_cmd
,
1030 "show [ip] bgp <vpnv4|vpnv6>",
1039 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1040 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 0, 0);
1044 DEFUN (show_ip_bgp_vpn_all_tags
,
1045 show_ip_bgp_vpn_all_tags_cmd
,
1046 "show [ip] bgp <vpnv4|vpnv6> all tags",
1051 "Display information about all VPNv4/VPNV6 NLRIs\n"
1052 "Display BGP tags for prefixes\n")
1057 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1058 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_normal
, NULL
, 1, 0);
1062 DEFUN (show_ip_bgp_vpn_rd_tags
,
1063 show_ip_bgp_vpn_rd_tags_cmd
,
1064 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
1069 "Display information for a route distinguisher\n"
1070 "VPN Route Distinguisher\n"
1071 "Display BGP tags for prefixes\n")
1073 int idx_ext_community
= 5;
1075 struct prefix_rd prd
;
1079 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1081 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1084 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1087 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_normal
, NULL
, 1, 0);
1092 DEFUN (show_ip_bgp_vpn_all_neighbor_routes
,
1093 show_ip_bgp_vpn_all_neighbor_routes_cmd
,
1094 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D routes [json]",
1099 "Display information about all VPNv4/VPNv6 NLRIs\n"
1100 "Detailed information on TCP and BGP neighbor connections\n"
1101 "Neighbor to display information about\n"
1102 "Display routes learned from neighbor\n"
1109 u_char uj
= use_json(argc
, argv
);
1113 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1115 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1120 json_object
*json_no
= NULL
;
1121 json_no
= json_object_new_object();
1122 json_object_string_add(json_no
, "warning", "Malformed address");
1123 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1124 json_object_free(json_no
);
1127 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1131 peer
= peer_lookup (NULL
, &su
);
1132 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1136 json_object
*json_no
= NULL
;
1137 json_no
= json_object_new_object();
1138 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1139 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1140 json_object_free(json_no
);
1143 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1147 return bgp_show_mpls_vpn (vty
, afi
, NULL
, bgp_show_type_neighbor
, &su
, 0, uj
);
1152 DEFUN (show_ip_bgp_vpn_rd_neighbor_routes
,
1153 show_ip_bgp_vpn_rd_neighbor_routes_cmd
,
1154 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
1159 "Display information for a route distinguisher\n"
1160 "VPN Route Distinguisher\n"
1161 "Detailed information on TCP and BGP neighbor connections\n"
1162 "Neighbor to display information about\n"
1163 "Display routes learned from neighbor\n"
1166 int idx_ext_community
= 5;
1171 struct prefix_rd prd
;
1172 u_char uj
= use_json(argc
, argv
);
1176 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1178 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1183 json_object
*json_no
= NULL
;
1184 json_no
= json_object_new_object();
1185 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1186 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1187 json_object_free(json_no
);
1190 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1194 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1199 json_object
*json_no
= NULL
;
1200 json_no
= json_object_new_object();
1201 json_object_string_add(json_no
, "warning", "Malformed address");
1202 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1203 json_object_free(json_no
);
1206 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1210 peer
= peer_lookup (NULL
, &su
);
1211 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1215 json_object
*json_no
= NULL
;
1216 json_no
= json_object_new_object();
1217 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1218 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1219 json_object_free(json_no
);
1222 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1226 return bgp_show_mpls_vpn (vty
, afi
, &prd
, bgp_show_type_neighbor
, &su
, 0, uj
);
1231 DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes
,
1232 show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
,
1233 "show [ip] bgp <vpnv4|vpnv6> all neighbors A.B.C.D advertised-routes [json]",
1238 "Display information about all VPNv4/VPNv6 NLRIs\n"
1239 "Detailed information on TCP and BGP neighbor connections\n"
1240 "Neighbor to display information about\n"
1241 "Display the routes advertised to a BGP neighbor\n"
1248 u_char uj
= use_json(argc
, argv
);
1252 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1254 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1259 json_object
*json_no
= NULL
;
1260 json_no
= json_object_new_object();
1261 json_object_string_add(json_no
, "warning", "Malformed address");
1262 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1263 json_object_free(json_no
);
1266 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ipv4
]->arg
, VTY_NEWLINE
);
1269 peer
= peer_lookup (NULL
, &su
);
1270 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1274 json_object
*json_no
= NULL
;
1275 json_no
= json_object_new_object();
1276 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1277 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1278 json_object_free(json_no
);
1281 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1285 return show_adj_route_vpn (vty
, peer
, NULL
, uj
, afi
);
1290 DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes
,
1291 show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
,
1292 "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
1297 "Display information for a route distinguisher\n"
1298 "VPN Route Distinguisher\n"
1299 "Detailed information on TCP and BGP neighbor connections\n"
1300 "Neighbor to display information about\n"
1301 "Display the routes advertised to a BGP neighbor\n"
1304 int idx_ext_community
= 5;
1308 struct prefix_rd prd
;
1310 u_char uj
= use_json(argc
, argv
);
1314 if (argv_find_and_parse_vpnvx (argv
, argc
, &idx
, &afi
))
1316 ret
= str2sockunion (argv
[idx_ipv4
]->arg
, &su
);
1321 json_object
*json_no
= NULL
;
1322 json_no
= json_object_new_object();
1323 json_object_string_add(json_no
, "warning", "Malformed address");
1324 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1325 json_object_free(json_no
);
1328 vty_out (vty
, "Malformed address: %s%s", argv
[idx_ext_community
]->arg
, VTY_NEWLINE
);
1331 peer
= peer_lookup (NULL
, &su
);
1332 if (! peer
|| ! peer
->afc
[afi
][SAFI_MPLS_VPN
])
1336 json_object
*json_no
= NULL
;
1337 json_no
= json_object_new_object();
1338 json_object_string_add(json_no
, "warning", "No such neighbor or address family");
1339 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1340 json_object_free(json_no
);
1343 vty_out (vty
, "%% No such neighbor or address family%s", VTY_NEWLINE
);
1347 ret
= str2prefix_rd (argv
[idx_ext_community
]->arg
, &prd
);
1352 json_object
*json_no
= NULL
;
1353 json_no
= json_object_new_object();
1354 json_object_string_add(json_no
, "warning", "Malformed Route Distinguisher");
1355 vty_out (vty
, "%s%s", json_object_to_json_string(json_no
), VTY_NEWLINE
);
1356 json_object_free(json_no
);
1359 vty_out (vty
, "%% Malformed Route Distinguisher%s", VTY_NEWLINE
);
1363 return show_adj_route_vpn (vty
, peer
, &prd
, uj
, afi
);
1367 #endif /* KEEP_OLD_VPN_COMMANDS */
1370 bgp_mplsvpn_init (void)
1372 install_element (BGP_VPNV4_NODE
, &vpnv4_network_cmd
);
1373 install_element (BGP_VPNV4_NODE
, &vpnv4_network_route_map_cmd
);
1374 install_element (BGP_VPNV4_NODE
, &no_vpnv4_network_cmd
);
1376 install_element (BGP_VPNV6_NODE
, &vpnv6_network_cmd
);
1377 install_element (BGP_VPNV6_NODE
, &no_vpnv6_network_cmd
);
1379 install_element (VIEW_NODE
, &show_bgp_ip_vpn_all_rd_cmd
);
1380 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1381 #ifdef KEEP_OLD_VPN_COMMANDS
1382 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_cmd
);
1383 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_cmd
);
1384 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_tags_cmd
);
1385 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_tags_cmd
);
1386 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_routes_cmd
);
1387 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_routes_cmd
);
1388 install_element (VIEW_NODE
, &show_ip_bgp_vpn_all_neighbor_advertised_routes_cmd
);
1389 install_element (VIEW_NODE
, &show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd
);
1390 #endif /* KEEP_OLD_VPN_COMMANDS */