1 /* Ethernet-VPN Packet and vty Processing File
2 * Copyright (C) 2017 6WIND
4 * This file is part of FRRouting
6 * FRRouting 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 * FRRouting 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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "bgpd/bgpd.h"
28 #include "bgpd/bgp_table.h"
29 #include "bgpd/bgp_attr.h"
30 #include "bgpd/bgp_route.h"
31 #include "bgpd/bgp_mplsvpn.h"
32 #include "bgpd/bgp_vpn.h"
33 #include "bgpd/bgp_evpn_vty.h"
34 #include "bgpd/bgp_evpn.h"
35 #include "bgpd/bgp_evpn_private.h"
36 #include "bgpd/bgp_zebra.h"
37 #include "bgpd/bgp_vty.h"
38 #include "bgpd/bgp_ecommunity.h"
40 #define SHOW_DISPLAY_STANDARD 0
41 #define SHOW_DISPLAY_TAGS 1
42 #define SHOW_DISPLAY_OVERLAY 2
43 #define VNI_STR_LEN 32
46 * Context for VNI hash walk - used by callbacks.
51 struct in_addr vtep_ip
;
55 #if defined(HAVE_CUMULUS)
56 static void display_vrf_import_rt(struct vty
*vty
,
57 struct vrf_irt_node
*irt
,
61 u_char type
, sub_type
;
62 struct ecommunity_as eas
;
63 struct ecommunity_ip eip
;
64 struct listnode
*node
, *nnode
;
65 struct bgp
*tmp_bgp_vrf
= NULL
;
66 json_object
*json_rt
= NULL
;
67 json_object
*json_vrfs
= NULL
;
68 char rt_buf
[RT_ADDRSTRLEN
];
71 json_rt
= json_object_new_object();
72 json_vrfs
= json_object_new_array();
75 pnt
= (u_char
*)&irt
->rt
.val
;
78 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
81 memset(&eas
, 0, sizeof(eas
));
83 case ECOMMUNITY_ENCODE_AS
:
84 eas
.as
= (*pnt
++ << 8);
86 pnt
= ptr_get_be32(pnt
, &eas
.val
);
88 snprintf(rt_buf
, RT_ADDRSTRLEN
, "%u:%u", eas
.as
, eas
.val
);
91 json_object_string_add(json_rt
, "rt", rt_buf
);
93 vty_out(vty
, "Route-target: %s", rt_buf
);
97 case ECOMMUNITY_ENCODE_IP
:
98 memcpy(&eip
.ip
, pnt
, 4);
100 eip
.val
= (*pnt
++ << 8);
103 snprintf(rt_buf
, RT_ADDRSTRLEN
, "%s:%u", inet_ntoa(eip
.ip
),
107 json_object_string_add(json_rt
, "rt", rt_buf
);
109 vty_out(vty
, "Route-target: %s", rt_buf
);
113 case ECOMMUNITY_ENCODE_AS4
:
114 pnt
= ptr_get_be32(pnt
, &eas
.val
);
115 eas
.val
= (*pnt
++ << 8);
118 snprintf(rt_buf
, RT_ADDRSTRLEN
, "%u:%u", eas
.as
, eas
.val
);
121 json_object_string_add(json_rt
, "rt", rt_buf
);
123 vty_out(vty
, "Route-target: %s", rt_buf
);
133 "\nList of VRFs importing routes with this route-target:\n");
136 for (ALL_LIST_ELEMENTS(irt
->vrfs
, node
, nnode
, tmp_bgp_vrf
)) {
138 json_object_array_add(
140 json_object_new_string(
142 tmp_bgp_vrf
->vrf_id
)));
144 vty_out(vty
, " %s\n",
145 vrf_id_to_name(tmp_bgp_vrf
->vrf_id
));
149 json_object_object_add(json_rt
, "vrfs", json_vrfs
);
150 json_object_object_add(json
, rt_buf
, json_rt
);
154 static void show_vrf_import_rt_entry(struct hash_backet
*backet
,
157 json_object
*json
= NULL
;
158 struct vty
*vty
= NULL
;
159 struct vrf_irt_node
*irt
= (struct vrf_irt_node
*)backet
->data
;
161 vty
= (struct vty
*)args
[0];
162 json
= (struct json_object
*)args
[1];
164 display_vrf_import_rt(vty
, irt
, json
);
167 static void display_import_rt(struct vty
*vty
, struct irt_node
*irt
,
171 u_char type
, sub_type
;
172 struct ecommunity_as eas
;
173 struct ecommunity_ip eip
;
174 struct listnode
*node
, *nnode
;
175 struct bgpevpn
*tmp_vpn
;
176 json_object
*json_rt
= NULL
;
177 json_object
*json_vnis
= NULL
;
178 char rt_buf
[RT_ADDRSTRLEN
];
181 json_rt
= json_object_new_object();
182 json_vnis
= json_object_new_array();
185 /* TODO: This needs to go into a function */
187 pnt
= (u_char
*)&irt
->rt
.val
;
190 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
193 memset(&eas
, 0, sizeof(eas
));
195 case ECOMMUNITY_ENCODE_AS
:
196 eas
.as
= (*pnt
++ << 8);
198 pnt
= ptr_get_be32(pnt
, &eas
.val
);
200 snprintf(rt_buf
, RT_ADDRSTRLEN
, "%u:%u", eas
.as
, eas
.val
);
203 json_object_string_add(json_rt
, "rt", rt_buf
);
205 vty_out(vty
, "Route-target: %s", rt_buf
);
209 case ECOMMUNITY_ENCODE_IP
:
210 memcpy(&eip
.ip
, pnt
, 4);
212 eip
.val
= (*pnt
++ << 8);
215 snprintf(rt_buf
, RT_ADDRSTRLEN
, "%s:%u", inet_ntoa(eip
.ip
),
219 json_object_string_add(json_rt
, "rt", rt_buf
);
221 vty_out(vty
, "Route-target: %s", rt_buf
);
225 case ECOMMUNITY_ENCODE_AS4
:
226 pnt
= ptr_get_be32(pnt
, &eas
.val
);
227 eas
.val
= (*pnt
++ << 8);
230 snprintf(rt_buf
, RT_ADDRSTRLEN
, "%u:%u", eas
.as
, eas
.val
);
233 json_object_string_add(json_rt
, "rt", rt_buf
);
235 vty_out(vty
, "Route-target: %s", rt_buf
);
245 "\nList of VNIs importing routes with this route-target:\n");
248 for (ALL_LIST_ELEMENTS(irt
->vnis
, node
, nnode
, tmp_vpn
)) {
250 json_object_array_add(
251 json_vnis
, json_object_new_int64(tmp_vpn
->vni
));
253 vty_out(vty
, " %u\n", tmp_vpn
->vni
);
257 json_object_object_add(json_rt
, "vnis", json_vnis
);
258 json_object_object_add(json
, rt_buf
, json_rt
);
262 static void show_import_rt_entry(struct hash_backet
*backet
, void *args
[])
264 json_object
*json
= NULL
;
265 struct vty
*vty
= NULL
;
266 struct irt_node
*irt
= (struct irt_node
*)backet
->data
;
271 display_import_rt(vty
, irt
, json
);
276 static void bgp_evpn_show_route_rd_header(struct vty
*vty
,
277 struct bgp_node
*rd_rn
,
284 char rd_str
[RD_ADDRSTRLEN
];
286 pnt
= rd_rn
->p
.u
.val
;
288 /* Decode RD type. */
289 type
= decode_rd_type(pnt
);
294 vty_out(vty
, "Route Distinguisher: ");
298 decode_rd_as(pnt
+ 2, &rd_as
);
299 snprintf(rd_str
, RD_ADDRSTRLEN
, "%u:%d", rd_as
.as
, rd_as
.val
);
303 decode_rd_ip(pnt
+ 2, &rd_ip
);
304 snprintf(rd_str
, RD_ADDRSTRLEN
, "%s:%d", inet_ntoa(rd_ip
.ip
),
309 snprintf(rd_str
, RD_ADDRSTRLEN
, "Unknown RD type");
313 vty_out(vty
, "%s\n", rd_str
);
316 static void bgp_evpn_show_route_header(struct vty
*vty
, struct bgp
*bgp
,
320 " Network Next Hop Metric LocPrf Weight Path\n";
326 vty_out(vty
, "BGP table version is 0, local router ID is %s\n",
327 inet_ntoa(bgp
->router_id
));
329 "Status codes: s suppressed, d damped, h history, "
330 "* valid, > best, i - internal\n");
331 vty_out(vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete\n");
333 "EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]\n");
334 vty_out(vty
, "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n\n");
335 vty_out(vty
, "%s", ri_header
);
338 static void display_vni(struct vty
*vty
, struct bgpevpn
*vpn
, json_object
*json
)
340 char buf1
[RD_ADDRSTRLEN
];
342 struct listnode
*node
, *nnode
;
343 struct ecommunity
*ecom
;
344 json_object
*json_import_rtl
= NULL
;
345 json_object
*json_export_rtl
= NULL
;
348 json_import_rtl
= json_object_new_array();
349 json_export_rtl
= json_object_new_array();
350 json_object_int_add(json
, "vni", vpn
->vni
);
351 json_object_string_add(json
, "kernelFlag",
352 is_vni_live(vpn
) ? "Yes" : "No");
353 json_object_string_add(
355 prefix_rd2str(&vpn
->prd
, buf1
, sizeof(buf1
)));
356 json_object_string_add(json
, "originatorIp",
357 inet_ntoa(vpn
->originator_ip
));
358 json_object_string_add(json
, "advertiseGatewayMacip",
359 vpn
->advertise_gw_macip
? "Yes" : "No");
361 vty_out(vty
, "VNI: %d", vpn
->vni
);
362 if (is_vni_live(vpn
))
363 vty_out(vty
, " (known to the kernel)");
366 vty_out(vty
, " Tenant-Vrf: %s\n",
367 vrf_id_to_name(vpn
->tenant_vrf_id
));
368 vty_out(vty
, " RD: %s\n",
369 prefix_rd2str(&vpn
->prd
, buf1
, sizeof(buf1
)));
370 vty_out(vty
, " Originator IP: %s\n",
371 inet_ntoa(vpn
->originator_ip
));
372 vty_out(vty
, " Advertise-gw-macip : %s\n",
373 vpn
->advertise_gw_macip
? "Yes" : "No");
377 vty_out(vty
, " Import Route Target:\n");
379 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
380 ecom_str
= ecommunity_ecom2str(ecom
,
381 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
384 json_object_array_add(json_import_rtl
,
385 json_object_new_string(ecom_str
));
387 vty_out(vty
, " %s\n", ecom_str
);
389 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
393 json_object_object_add(json
, "importRts", json_import_rtl
);
395 vty_out(vty
, " Export Route Target:\n");
397 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
398 ecom_str
= ecommunity_ecom2str(ecom
,
399 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
402 json_object_array_add(json_export_rtl
,
403 json_object_new_string(ecom_str
));
405 vty_out(vty
, " %s\n", ecom_str
);
407 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
411 json_object_object_add(json
, "exportRts", json_export_rtl
);
414 static void evpn_show_vrf_routes(struct vty
*vty
,
417 struct bgp
*bgp_def
= NULL
;
421 u_int32_t prefix_cnt
, path_cnt
;
422 struct bgp_table
*table
;
424 prefix_cnt
= path_cnt
= 0;
425 bgp_def
= bgp_get_default();
429 table
= (struct bgp_table
*)bgp_vrf
->rib
[AFI_L2VPN
][SAFI_EVPN
];
430 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
431 char prefix_str
[BUFSIZ
];
433 bgp_evpn_route2str((struct prefix_evpn
*)&rn
->p
, prefix_str
,
437 /* Overall header/legend displayed once. */
439 bgp_evpn_show_route_header(vty
, bgp_def
, NULL
);
445 /* For EVPN, the prefix is displayed for each path (to fit in
446 * with code that already exists).
448 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
449 route_vty_out(vty
, &rn
->p
, ri
, 0, SAFI_EVPN
, NULL
);
455 vty_out(vty
, "No EVPN prefixes exist for this VRF");
457 vty_out(vty
, "\nDisplayed %u prefixes (%u paths)",
458 prefix_cnt
, path_cnt
);
461 static void show_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
, int type
,
462 struct vty
*vty
, struct in_addr vtep_ip
,
468 u_int32_t prefix_cnt
, path_cnt
;
470 prefix_cnt
= path_cnt
= 0;
472 for (rn
= bgp_table_top(vpn
->route_table
); rn
;
473 rn
= bgp_route_next(rn
)) {
474 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
475 int add_prefix_to_json
= 0;
476 char prefix_str
[BUFSIZ
];
477 json_object
*json_paths
= NULL
;
478 json_object
*json_prefix
= NULL
;
480 bgp_evpn_route2str((struct prefix_evpn
*)&rn
->p
, prefix_str
,
483 if (type
&& evp
->prefix
.route_type
!= type
)
487 json_prefix
= json_object_new_object();
490 /* Overall header/legend displayed once. */
492 bgp_evpn_show_route_header(vty
, bgp
, json
);
500 json_paths
= json_object_new_array();
502 /* For EVPN, the prefix is displayed for each path (to fit in
503 * with code that already exists).
505 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
506 json_object
*json_path
= NULL
;
509 && !IPV4_ADDR_SAME(&(vtep_ip
),
510 &(ri
->attr
->nexthop
)))
514 json_path
= json_object_new_array();
516 route_vty_out(vty
, &rn
->p
, ri
, 0, SAFI_EVPN
, json_path
);
519 json_object_array_add(json_paths
, json_path
);
522 add_prefix_to_json
= 1;
525 if (json
&& add_prefix_to_json
) {
526 json_object_string_add(json_prefix
, "prefix",
528 json_object_int_add(json_prefix
, "prefixLen",
530 json_object_object_add(json_prefix
, "paths",
532 json_object_object_add(json
, prefix_str
, json_prefix
);
537 json_object_int_add(json
, "numPrefix", prefix_cnt
);
538 json_object_int_add(json
, "numPaths", path_cnt
);
541 vty_out(vty
, "No EVPN prefixes %sexist for this VNI",
542 type
? "(of requested type) " : "");
544 vty_out(vty
, "\nDisplayed %u prefixes (%u paths)%s",
545 prefix_cnt
, path_cnt
,
546 type
? " (of requested type)" : "");
550 static void show_vni_routes_hash(struct hash_backet
*backet
, void *arg
)
552 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
553 struct vni_walk_ctx
*wctx
= arg
;
554 struct vty
*vty
= wctx
->vty
;
555 json_object
*json
= wctx
->json
;
556 json_object
*json_vni
= NULL
;
557 char vni_str
[VNI_STR_LEN
];
559 snprintf(vni_str
, VNI_STR_LEN
, "%d", vpn
->vni
);
561 json_vni
= json_object_new_object();
562 json_object_int_add(json_vni
, "vni", vpn
->vni
);
564 vty_out(vty
, "\nVNI: %d\n\n", vpn
->vni
);
567 show_vni_routes(wctx
->bgp
, vpn
, 0, wctx
->vty
, wctx
->vtep_ip
, json_vni
);
570 json_object_object_add(json
, vni_str
, json_vni
);
573 static void show_vni_entry(struct hash_backet
*backet
, void *args
[])
577 json_object
*json_vni
;
578 json_object
*json_import_rtl
;
579 json_object
*json_export_rtl
;
580 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
582 char buf2
[RD_ADDRSTRLEN
];
585 struct listnode
*node
, *nnode
;
586 struct ecommunity
*ecom
;
592 json_vni
= json_object_new_object();
593 json_import_rtl
= json_object_new_array();
594 json_export_rtl
= json_object_new_array();
598 if (is_vni_live(vpn
))
602 json_object_int_add(json_vni
, "vni", vpn
->vni
);
603 json_object_string_add(json_vni
, "inKernel",
604 is_vni_live(vpn
) ? "True" : "False");
605 json_object_string_add(json_vni
, "originatorIp",
606 inet_ntoa(vpn
->originator_ip
));
607 json_object_string_add(
609 prefix_rd2str(&vpn
->prd
, buf2
, sizeof(buf2
)));
611 vty_out(vty
, "%-1s %-10u %-15s %-21s", buf1
, vpn
->vni
,
612 inet_ntoa(vpn
->originator_ip
),
613 prefix_rd2str(&vpn
->prd
, buf2
, RD_ADDRSTRLEN
));
616 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
617 ecom_str
= ecommunity_ecom2str(ecom
,
618 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
621 json_object_array_add(json_import_rtl
,
622 json_object_new_string(ecom_str
));
624 if (listcount(vpn
->import_rtl
) > 1)
625 sprintf(rt_buf
, "%s, ...", ecom_str
);
627 sprintf(rt_buf
, "%s", ecom_str
);
628 vty_out(vty
, " %-25s", rt_buf
);
631 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
633 /* If there are multiple import RTs we break here and show only
640 json_object_object_add(json_vni
, "importRTs", json_import_rtl
);
642 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
643 ecom_str
= ecommunity_ecom2str(ecom
,
644 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
647 json_object_array_add(json_export_rtl
,
648 json_object_new_string(ecom_str
));
650 if (listcount(vpn
->export_rtl
) > 1)
651 sprintf(rt_buf
, "%s, ...", ecom_str
);
653 sprintf(rt_buf
, "%s", ecom_str
);
654 vty_out(vty
, " %-25s", rt_buf
);
657 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
659 /* If there are multiple export RTs we break here and show only
666 vty_out(vty
, "%-37s", vrf_id_to_name(vpn
->tenant_vrf_id
));
669 char vni_str
[VNI_STR_LEN
];
671 json_object_object_add(json_vni
, "exportRTs", json_export_rtl
);
672 snprintf(vni_str
, VNI_STR_LEN
, "%u", vpn
->vni
);
673 json_object_object_add(json
, vni_str
, json_vni
);
678 #endif /* HAVE_CUMULUS */
680 static int bgp_show_ethernet_vpn(struct vty
*vty
, struct prefix_rd
*prd
,
681 enum bgp_show_type type
, void *output_arg
,
682 int option
, u_char use_json
)
684 afi_t afi
= AFI_L2VPN
;
686 struct bgp_table
*table
;
693 unsigned long output_count
= 0;
694 unsigned long total_count
= 0;
695 json_object
*json
= NULL
;
696 json_object
*json_nroute
= NULL
;
697 json_object
*json_array
= NULL
;
698 json_object
*json_scode
= NULL
;
699 json_object
*json_ocode
= NULL
;
701 bgp
= bgp_get_default();
704 vty_out(vty
, "No BGP process is configured\n");
706 vty_out(vty
, "{}\n");
711 json_scode
= json_object_new_object();
712 json_ocode
= json_object_new_object();
713 json
= json_object_new_object();
714 json_nroute
= json_object_new_object();
716 json_object_string_add(json_scode
, "suppressed", "s");
717 json_object_string_add(json_scode
, "damped", "d");
718 json_object_string_add(json_scode
, "history", "h");
719 json_object_string_add(json_scode
, "valid", "*");
720 json_object_string_add(json_scode
, "best", ">");
721 json_object_string_add(json_scode
, "internal", "i");
723 json_object_string_add(json_ocode
, "igp", "i");
724 json_object_string_add(json_ocode
, "egp", "e");
725 json_object_string_add(json_ocode
, "incomplete", "?");
728 for (rn
= bgp_table_top(bgp
->rib
[afi
][SAFI_EVPN
]); rn
;
729 rn
= bgp_route_next(rn
)) {
731 continue; /* XXX json TODO */
733 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
736 if ((table
= rn
->info
) == NULL
)
741 for (rm
= bgp_table_top(table
); rm
; rm
= bgp_route_next(rm
))
742 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
744 if (type
== bgp_show_type_neighbor
) {
745 union sockunion
*su
= output_arg
;
747 if (ri
->peer
->su_remote
== NULL
749 ri
->peer
->su_remote
, su
))
755 == SHOW_DISPLAY_TAGS
) {
760 json_object_string_add(
765 json_object_object_add(
769 json_object_object_add(
775 if (option
== SHOW_DISPLAY_TAGS
)
780 == SHOW_DISPLAY_OVERLAY
)
785 "BGP table version is 0, local router ID is %s\n",
789 "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
791 "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n");
792 vty_out(vty
, V4_HEADER
);
805 /* Decode RD type. */
806 type
= decode_rd_type(pnt
);
807 /* Decode RD value. */
808 if (type
== RD_TYPE_AS
)
809 decode_rd_as(pnt
+ 2, &rd_as
);
810 else if (type
== RD_TYPE_AS4
)
811 decode_rd_as4(pnt
+ 2, &rd_as
);
812 else if (type
== RD_TYPE_IP
)
813 decode_rd_ip(pnt
+ 2, &rd_ip
);
816 if (type
== RD_TYPE_AS
817 || type
== RD_TYPE_AS4
)
818 sprintf(buffer
, "%u:%d",
821 else if (type
== RD_TYPE_IP
)
822 sprintf(buffer
, "%s:%d",
826 json_object_string_add(
828 "routeDistinguisher",
832 "Route Distinguisher: ");
833 if (type
== RD_TYPE_AS
)
838 else if (type
== RD_TYPE_AS4
)
843 else if (type
== RD_TYPE_IP
)
844 vty_out(vty
, "ip %s:%d",
848 vty_out(vty
, "\n\n");
853 json_array
= json_object_new_array();
856 if (option
== SHOW_DISPLAY_TAGS
)
857 route_vty_out_tag(vty
, &rm
->p
, ri
, 0,
860 else if (option
== SHOW_DISPLAY_OVERLAY
)
861 route_vty_out_overlay(vty
, &rm
->p
, ri
,
864 route_vty_out(vty
, &rm
->p
, ri
, 0,
865 SAFI_EVPN
, json_array
);
870 if (output_count
== 0)
871 vty_out(vty
, "No prefixes displayed, %ld exist\n", total_count
);
873 vty_out(vty
, "\nDisplayed %ld out of %ld total prefixes\n",
874 output_count
, total_count
);
878 DEFUN(show_ip_bgp_l2vpn_evpn
,
879 show_ip_bgp_l2vpn_evpn_cmd
,
880 "show [ip] bgp l2vpn evpn [json]",
881 SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR JSON_STR
)
883 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_normal
, NULL
, 0,
884 use_json(argc
, argv
));
887 DEFUN(show_ip_bgp_l2vpn_evpn_rd
,
888 show_ip_bgp_l2vpn_evpn_rd_cmd
,
889 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
895 "Display information for a route distinguisher\n"
896 "VPN Route Distinguisher\n" JSON_STR
)
898 int idx_ext_community
= 0;
900 struct prefix_rd prd
;
902 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
904 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
906 vty_out(vty
, "%% Malformed Route Distinguisher\n");
909 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_normal
, NULL
, 0,
910 use_json(argc
, argv
));
913 DEFUN(show_ip_bgp_l2vpn_evpn_all_tags
,
914 show_ip_bgp_l2vpn_evpn_all_tags_cmd
,
915 "show [ip] bgp l2vpn evpn all tags",
921 "Display information about all EVPN NLRIs\n"
922 "Display BGP tags for prefixes\n")
924 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_normal
, NULL
, 1,
928 DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags
,
929 show_ip_bgp_l2vpn_evpn_rd_tags_cmd
,
930 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN tags",
936 "Display information for a route distinguisher\n"
937 "VPN Route Distinguisher\n" "Display BGP tags for prefixes\n")
939 int idx_ext_community
= 0;
941 struct prefix_rd prd
;
943 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
945 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
947 vty_out(vty
, "%% Malformed Route Distinguisher\n");
950 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_normal
, NULL
, 1,
954 DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes
,
955 show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd
,
956 "show [ip] bgp l2vpn evpn all neighbors A.B.C.D routes [json]",
962 "Display information about all EVPN NLRIs\n"
963 "Detailed information on TCP and BGP neighbor connections\n"
964 "Neighbor to display information about\n"
965 "Display routes learned from neighbor\n" JSON_STR
)
971 u_char uj
= use_json(argc
, argv
);
973 argv_find(argv
, argc
, "A.B.C.D", &idx_ipv4
);
975 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
978 json_object
*json_no
= NULL
;
979 json_no
= json_object_new_object();
980 json_object_string_add(json_no
, "warning",
981 "Malformed address");
983 json_object_to_json_string(json_no
));
984 json_object_free(json_no
);
986 vty_out(vty
, "Malformed address: %s\n",
987 argv
[idx_ipv4
]->arg
);
991 peer
= peer_lookup(NULL
, &su
);
992 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
994 json_object
*json_no
= NULL
;
995 json_no
= json_object_new_object();
996 json_object_string_add(
998 "No such neighbor or address family");
1000 json_object_to_json_string(json_no
));
1001 json_object_free(json_no
);
1003 vty_out(vty
, "%% No such neighbor or address family\n");
1007 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_neighbor
, &su
, 0,
1011 DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes
,
1012 show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd
,
1013 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
1019 "Display information for a route distinguisher\n"
1020 "VPN Route Distinguisher\n"
1021 "Detailed information on TCP and BGP neighbor connections\n"
1022 "Neighbor to display information about\n"
1023 "Display routes learned from neighbor\n" JSON_STR
)
1025 int idx_ext_community
= 0;
1030 struct prefix_rd prd
;
1031 u_char uj
= use_json(argc
, argv
);
1033 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1034 argv_find(argv
, argc
, "A.B.C.D", &idx_ipv4
);
1036 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1039 json_object
*json_no
= NULL
;
1040 json_no
= json_object_new_object();
1041 json_object_string_add(json_no
, "warning",
1042 "Malformed Route Distinguisher");
1043 vty_out(vty
, "%s\n",
1044 json_object_to_json_string(json_no
));
1045 json_object_free(json_no
);
1047 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1051 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1054 json_object
*json_no
= NULL
;
1055 json_no
= json_object_new_object();
1056 json_object_string_add(json_no
, "warning",
1057 "Malformed address");
1058 vty_out(vty
, "%s\n",
1059 json_object_to_json_string(json_no
));
1060 json_object_free(json_no
);
1062 vty_out(vty
, "Malformed address: %s\n",
1063 argv
[idx_ext_community
]->arg
);
1067 peer
= peer_lookup(NULL
, &su
);
1068 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1070 json_object
*json_no
= NULL
;
1071 json_no
= json_object_new_object();
1072 json_object_string_add(
1074 "No such neighbor or address family");
1075 vty_out(vty
, "%s\n",
1076 json_object_to_json_string(json_no
));
1077 json_object_free(json_no
);
1079 vty_out(vty
, "%% No such neighbor or address family\n");
1083 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_neighbor
, &su
, 0,
1087 DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes
,
1088 show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd
,
1089 "show [ip] bgp l2vpn evpn all neighbors A.B.C.D advertised-routes [json]",
1095 "Display information about all EVPN NLRIs\n"
1096 "Detailed information on TCP and BGP neighbor connections\n"
1097 "Neighbor to display information about\n"
1098 "Display the routes advertised to a BGP neighbor\n" JSON_STR
)
1104 u_char uj
= use_json(argc
, argv
);
1106 argv_find(argv
, argc
, "A.B.C.D", &idx_ipv4
);
1108 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1111 json_object
*json_no
= NULL
;
1112 json_no
= json_object_new_object();
1113 json_object_string_add(json_no
, "warning",
1114 "Malformed address");
1115 vty_out(vty
, "%s\n",
1116 json_object_to_json_string(json_no
));
1117 json_object_free(json_no
);
1119 vty_out(vty
, "Malformed address: %s\n",
1120 argv
[idx_ipv4
]->arg
);
1123 peer
= peer_lookup(NULL
, &su
);
1124 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1126 json_object
*json_no
= NULL
;
1127 json_no
= json_object_new_object();
1128 json_object_string_add(
1130 "No such neighbor or address family");
1131 vty_out(vty
, "%s\n",
1132 json_object_to_json_string(json_no
));
1133 json_object_free(json_no
);
1135 vty_out(vty
, "%% No such neighbor or address family\n");
1139 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_L2VPN
, SAFI_EVPN
, uj
);
1142 DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes
,
1143 show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd
,
1144 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
1150 "Display information for a route distinguisher\n"
1151 "VPN Route Distinguisher\n"
1152 "Detailed information on TCP and BGP neighbor connections\n"
1153 "Neighbor to display information about\n"
1154 "Display the routes advertised to a BGP neighbor\n" JSON_STR
)
1156 int idx_ext_community
= 0;
1160 struct prefix_rd prd
;
1162 u_char uj
= use_json(argc
, argv
);
1164 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1165 argv_find(argv
, argc
, "A.B.C.D", &idx_ipv4
);
1167 ret
= str2sockunion(argv
[idx_ipv4
]->arg
, &su
);
1170 json_object
*json_no
= NULL
;
1171 json_no
= json_object_new_object();
1172 json_object_string_add(json_no
, "warning",
1173 "Malformed address");
1174 vty_out(vty
, "%s\n",
1175 json_object_to_json_string(json_no
));
1176 json_object_free(json_no
);
1178 vty_out(vty
, "Malformed address: %s\n",
1179 argv
[idx_ext_community
]->arg
);
1182 peer
= peer_lookup(NULL
, &su
);
1183 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1185 json_object
*json_no
= NULL
;
1186 json_no
= json_object_new_object();
1187 json_object_string_add(
1189 "No such neighbor or address family");
1190 vty_out(vty
, "%s\n",
1191 json_object_to_json_string(json_no
));
1192 json_object_free(json_no
);
1194 vty_out(vty
, "%% No such neighbor or address family\n");
1198 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1201 json_object
*json_no
= NULL
;
1202 json_no
= json_object_new_object();
1203 json_object_string_add(json_no
, "warning",
1204 "Malformed Route Distinguisher");
1205 vty_out(vty
, "%s\n",
1206 json_object_to_json_string(json_no
));
1207 json_object_free(json_no
);
1209 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1213 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_L2VPN
, SAFI_EVPN
, uj
);
1216 DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay
,
1217 show_ip_bgp_l2vpn_evpn_all_overlay_cmd
,
1218 "show [ip] bgp l2vpn evpn all overlay",
1224 "Display information about all EVPN NLRIs\n"
1225 "Display BGP Overlay Information for prefixes\n")
1227 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_normal
, NULL
,
1228 SHOW_DISPLAY_OVERLAY
,
1229 use_json(argc
, argv
));
1232 DEFUN(show_ip_bgp_evpn_rd_overlay
,
1233 show_ip_bgp_evpn_rd_overlay_cmd
,
1234 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN overlay",
1240 "Display information for a route distinguisher\n"
1241 "VPN Route Distinguisher\n"
1242 "Display BGP Overlay Information for prefixes\n")
1244 int idx_ext_community
= 0;
1246 struct prefix_rd prd
;
1248 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1250 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1252 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1255 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_normal
, NULL
,
1256 SHOW_DISPLAY_OVERLAY
,
1257 use_json(argc
, argv
));
1260 /* For testing purpose, static route of MPLS-VPN. */
1261 DEFUN(evpnrt5_network
,
1262 evpnrt5_network_cmd
,
1263 "network <A.B.C.D/M|X:X::X:X/M> rd ASN:NN_OR_IP-ADDRESS:NN ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X> routermac WORD [route-map WORD]",
1264 "Specify a network to announce via BGP\n"
1267 "Specify Route Distinguisher\n"
1268 "VPN Route Distinguisher\n"
1270 "Ethernet Tag Value\n"
1273 "Ethernet Segment Identifier\n"
1274 "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
1276 "Gateway IP ( A.B.C.D )\n"
1277 "Gateway IPv6 ( X:X::X:X )\n"
1278 "Router Mac Ext Comm\n"
1279 "Router Mac address Value ( aa:bb:cc:dd:ee:ff format)\n"
1280 "Route-map to modify the attributes\n"
1281 "Name of the route map\n")
1283 int idx_ipv4_prefixlen
= 1;
1284 int idx_route_distinguisher
= 3;
1289 int idx_routermac
= 13;
1291 return bgp_static_set_safi(
1292 AFI_L2VPN
, SAFI_EVPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1293 argv
[idx_route_distinguisher
]->arg
, argv
[idx_label
]->arg
,
1295 BGP_EVPN_IP_PREFIX_ROUTE
, argv
[idx_esi
]->arg
,
1296 argv
[idx_gwip
]->arg
, argv
[idx_ethtag
]->arg
,
1297 argv
[idx_routermac
]->arg
);
1300 /* For testing purpose, static route of MPLS-VPN. */
1301 DEFUN(no_evpnrt5_network
,
1302 no_evpnrt5_network_cmd
,
1303 "no network <A.B.C.D/M|X:X::X:X/M> rd ASN:NN_OR_IP-ADDRESS:NN ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X>",
1305 "Specify a network to announce via BGP\n"
1308 "Specify Route Distinguisher\n"
1309 "VPN Route Distinguisher\n"
1311 "Ethernet Tag Value\n"
1314 "Ethernet Segment Identifier\n"
1315 "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
1316 "Gateway IP\n" "Gateway IP ( A.B.C.D )\n" "Gateway IPv6 ( X:X::X:X )\n")
1318 int idx_ipv4_prefixlen
= 2;
1319 int idx_ext_community
= 4;
1324 return bgp_static_unset_safi(
1325 AFI_L2VPN
, SAFI_EVPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1326 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1327 BGP_EVPN_IP_PREFIX_ROUTE
, argv
[idx_esi
]->arg
,
1328 argv
[idx_gwip
]->arg
, argv
[idx_ethtag
]->arg
);
1331 #if defined(HAVE_CUMULUS)
1333 static void evpn_import_rt_delete_auto(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1335 evpn_rt_delete_auto(bgp
, vpn
->vni
, vpn
->import_rtl
);
1338 static void evpn_export_rt_delete_auto(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1340 evpn_rt_delete_auto(bgp
, vpn
->vni
, vpn
->export_rtl
);
1344 * Configure the Import RTs for a VNI (vty handler). Caller expected to
1345 * check that this is a change.
1347 static void evpn_configure_import_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1348 struct ecommunity
*ecomadd
)
1350 /* If the VNI is "live", we need to uninstall routes using the current
1351 * import RT(s) first before we update the import RT, and subsequently
1354 if (is_vni_live(vpn
))
1355 bgp_evpn_uninstall_routes(bgp
, vpn
);
1357 /* Cleanup the RT to VNI mapping and get rid of existing import RT. */
1358 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
1360 /* If the auto route-target is in use we must remove it */
1361 evpn_import_rt_delete_auto(bgp
, vpn
);
1363 /* Add new RT and rebuild the RT to VNI mapping */
1364 listnode_add_sort(vpn
->import_rtl
, ecomadd
);
1366 SET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
1367 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
1369 /* Install routes that match new import RT */
1370 if (is_vni_live(vpn
))
1371 bgp_evpn_install_routes(bgp
, vpn
);
1375 * Unconfigure Import RT(s) for a VNI (vty handler).
1377 static void evpn_unconfigure_import_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1378 struct ecommunity
*ecomdel
)
1380 struct listnode
*node
, *nnode
, *node_to_del
;
1381 struct ecommunity
*ecom
;
1383 /* Along the lines of "configure" except we have to reset to the
1386 if (is_vni_live(vpn
))
1387 bgp_evpn_uninstall_routes(bgp
, vpn
);
1389 /* Cleanup the RT to VNI mapping and get rid of existing import RT. */
1390 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
1392 /* Delete all import RTs */
1393 if (ecomdel
== NULL
) {
1394 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
))
1395 ecommunity_free(&ecom
);
1397 list_delete_all_node(vpn
->import_rtl
);
1400 /* Delete a specific import RT */
1404 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
1405 if (ecommunity_match(ecom
, ecomdel
)) {
1406 ecommunity_free(&ecom
);
1413 list_delete_node(vpn
->import_rtl
, node_to_del
);
1416 /* Reset to auto RT - this also rebuilds the RT to VNI mapping */
1417 if (list_isempty(vpn
->import_rtl
)) {
1418 UNSET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
1419 bgp_evpn_derive_auto_rt_import(bgp
, vpn
);
1421 /* Rebuild the RT to VNI mapping */
1423 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
1425 /* Install routes that match new import RT */
1426 if (is_vni_live(vpn
))
1427 bgp_evpn_install_routes(bgp
, vpn
);
1431 * Configure the Export RT for a VNI (vty handler). Caller expected to
1432 * check that this is a change. Note that only a single export RT is
1433 * allowed for a VNI and any change to configuration is implemented as
1434 * a "replace" (similar to other configuration).
1436 static void evpn_configure_export_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1437 struct ecommunity
*ecomadd
)
1439 /* If the auto route-target is in use we must remove it */
1440 evpn_export_rt_delete_auto(bgp
, vpn
);
1442 listnode_add_sort(vpn
->export_rtl
, ecomadd
);
1443 SET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
1445 if (is_vni_live(vpn
))
1446 bgp_evpn_handle_export_rt_change(bgp
, vpn
);
1450 * Unconfigure the Export RT for a VNI (vty handler)
1452 static void evpn_unconfigure_export_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1453 struct ecommunity
*ecomdel
)
1455 struct listnode
*node
, *nnode
, *node_to_del
;
1456 struct ecommunity
*ecom
;
1458 /* Delete all export RTs */
1459 if (ecomdel
== NULL
) {
1460 /* Reset to default and process all routes. */
1461 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
))
1462 ecommunity_free(&ecom
);
1464 list_delete_all_node(vpn
->export_rtl
);
1467 /* Delete a specific export RT */
1471 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
1472 if (ecommunity_match(ecom
, ecomdel
)) {
1473 ecommunity_free(&ecom
);
1480 list_delete_node(vpn
->export_rtl
, node_to_del
);
1483 if (list_isempty(vpn
->export_rtl
)) {
1484 UNSET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
1485 bgp_evpn_derive_auto_rt_export(bgp
, vpn
);
1488 if (is_vni_live(vpn
))
1489 bgp_evpn_handle_export_rt_change(bgp
, vpn
);
1493 * Configure RD for VRF
1495 static void evpn_configure_vrf_rd(struct bgp
*bgp_vrf
,
1496 struct prefix_rd
*rd
)
1498 /* If we have already advertise type-5 routes with a diffrent RD, we
1499 * have to delete and withdraw them first*/
1500 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 1);
1503 memcpy(&bgp_vrf
->vrf_prd
, rd
, sizeof(struct prefix_rd
));
1504 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_RD_CFGD
);
1506 /* We have a new RD for VRF.
1507 * Advertise all type-5 routes again with the new RD */
1508 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 0);
1512 * Unconfigure RD for VRF
1514 static void evpn_unconfigure_vrf_rd(struct bgp
*bgp_vrf
)
1516 /* If we have already advertise type-5 routes with a diffrent RD, we
1517 * have to delete and withdraw them first*/
1518 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 1);
1520 /* fall back to default RD */
1521 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf
);
1523 /* We have a new RD for VRF.
1524 * Advertise all type-5 routes again with the new RD */
1525 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 0);
1529 * Configure RD for a VNI (vty handler)
1531 static void evpn_configure_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1532 struct prefix_rd
*rd
)
1534 /* If the VNI is "live", we need to delete and withdraw this VNI's
1535 * local routes with the prior RD first. Then, after updating RD,
1536 * need to re-advertise.
1538 if (is_vni_live(vpn
))
1539 bgp_evpn_handle_rd_change(bgp
, vpn
, 1);
1542 memcpy(&vpn
->prd
, rd
, sizeof(struct prefix_rd
));
1543 SET_FLAG(vpn
->flags
, VNI_FLAG_RD_CFGD
);
1545 if (is_vni_live(vpn
))
1546 bgp_evpn_handle_rd_change(bgp
, vpn
, 0);
1550 * Unconfigure RD for a VNI (vty handler)
1552 static void evpn_unconfigure_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1554 /* If the VNI is "live", we need to delete and withdraw this VNI's
1555 * local routes with the prior RD first. Then, after resetting RD
1556 * to automatic value, need to re-advertise.
1558 if (is_vni_live(vpn
))
1559 bgp_evpn_handle_rd_change(bgp
, vpn
, 1);
1561 /* reset RD to default */
1562 bgp_evpn_derive_auto_rd(bgp
, vpn
);
1564 if (is_vni_live(vpn
))
1565 bgp_evpn_handle_rd_change(bgp
, vpn
, 0);
1569 * Create VNI, if not already present (VTY handler). Mark as configured.
1571 static struct bgpevpn
*evpn_create_update_vni(struct bgp
*bgp
, vni_t vni
)
1573 struct bgpevpn
*vpn
;
1578 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
1580 /* tenant vrf will be updated when we get local_vni_add from
1582 vpn
= bgp_evpn_new(bgp
, vni
, bgp
->router_id
, 0);
1585 "%u: Failed to allocate VNI entry for VNI %u - at Config",
1591 /* Mark as configured. */
1592 SET_FLAG(vpn
->flags
, VNI_FLAG_CFGD
);
1597 * Delete VNI. If VNI does not exist in the system (i.e., just
1598 * configuration), all that is needed is to free it. Otherwise,
1599 * any parameters configured for the VNI need to be reset (with
1600 * appropriate action) and the VNI marked as unconfigured; the
1601 * VNI will continue to exist, purely as a "learnt" entity.
1603 static int evpn_delete_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1605 assert(bgp
->vnihash
);
1607 if (!is_vni_live(vpn
)) {
1608 bgp_evpn_free(bgp
, vpn
);
1612 /* We need to take the unconfigure action for each parameter of this VNI
1613 * that is configured. Some optimization is possible, but not worth the
1614 * additional code for an operation that should be pretty rare.
1616 UNSET_FLAG(vpn
->flags
, VNI_FLAG_CFGD
);
1618 /* First, deal with the export side - RD and export RT changes. */
1619 if (is_rd_configured(vpn
))
1620 evpn_unconfigure_rd(bgp
, vpn
);
1621 if (is_export_rt_configured(vpn
))
1622 evpn_unconfigure_export_rt(bgp
, vpn
, NULL
);
1624 /* Next, deal with the import side. */
1625 if (is_import_rt_configured(vpn
))
1626 evpn_unconfigure_import_rt(bgp
, vpn
, NULL
);
1632 * Display import RT mapping to VRFs (vty handler)
1633 * bgp_def: default bgp instance
1635 static void evpn_show_vrf_import_rts(struct vty
*vty
,
1636 struct bgp
*bgp_def
,
1644 hash_iterate(bgp_def
->vrf_import_rt_hash
,
1645 (void (*)(struct hash_backet
*, void *))
1646 show_vrf_import_rt_entry
,
1651 * Display import RT mapping to VNIs (vty handler)
1653 static void evpn_show_import_rts(struct vty
*vty
, struct bgp
*bgp
,
1662 bgp
->import_rt_hash
,
1663 (void (*)(struct hash_backet
*, void *))show_import_rt_entry
,
1668 * Display EVPN routes for all VNIs - vty handler.
1670 static void evpn_show_routes_vni_all(struct vty
*vty
, struct bgp
*bgp
,
1671 struct in_addr vtep_ip
, json_object
*json
)
1674 struct vni_walk_ctx wctx
;
1676 num_vnis
= hashcount(bgp
->vnihash
);
1679 memset(&wctx
, 0, sizeof(struct vni_walk_ctx
));
1682 wctx
.vtep_ip
= vtep_ip
;
1684 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_backet
*,
1685 void *))show_vni_routes_hash
,
1690 * Display EVPN routes for a VNI -- for specific type-3 route (vty handler).
1692 static void evpn_show_route_vni_multicast(struct vty
*vty
, struct bgp
*bgp
,
1693 vni_t vni
, struct in_addr orig_ip
,
1696 struct bgpevpn
*vpn
;
1697 struct prefix_evpn p
;
1698 struct bgp_node
*rn
;
1699 struct bgp_info
*ri
;
1700 u_int32_t path_cnt
= 0;
1703 json_object
*json_paths
= NULL
;
1709 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
1711 vty_out(vty
, "VNI not found\n");
1715 /* See if route exists. */
1716 build_evpn_type3_prefix(&p
, orig_ip
);
1717 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
1718 if (!rn
|| !rn
->info
) {
1720 vty_out(vty
, "%% Network not in table\n");
1725 json_paths
= json_object_new_array();
1727 /* Prefix and num paths displayed once per prefix. */
1728 route_vty_out_detail_header(vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
1730 /* Display each path for this prefix. */
1731 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1732 json_object
*json_path
= NULL
;
1735 json_path
= json_object_new_array();
1737 route_vty_out_detail(vty
, bgp
, &rn
->p
, ri
, afi
, safi
,
1741 json_object_array_add(json_paths
, json_path
);
1748 json_object_object_add(json
, "paths", json_paths
);
1750 json_object_int_add(json
, "numPaths", path_cnt
);
1752 vty_out(vty
, "\nDisplayed %u paths for requested prefix\n",
1758 * Display EVPN routes for a VNI -- for specific MAC and/or IP (vty handler).
1759 * By definition, only matching type-2 route will be displayed.
1761 static void evpn_show_route_vni_macip(struct vty
*vty
, struct bgp
*bgp
,
1762 vni_t vni
, struct ethaddr
*mac
,
1763 struct ipaddr
*ip
, json_object
*json
)
1765 struct bgpevpn
*vpn
;
1766 struct prefix_evpn p
;
1767 struct bgp_node
*rn
;
1768 struct bgp_info
*ri
;
1769 u_int32_t path_cnt
= 0;
1772 json_object
*json_paths
= NULL
;
1778 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
1781 vty_out(vty
, "VNI not found\n");
1785 /* See if route exists. Look for both non-sticky and sticky. */
1786 build_evpn_type2_prefix(&p
, mac
, ip
);
1787 rn
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
1788 if (!rn
|| !rn
->info
) {
1790 vty_out(vty
, "%% Network not in table\n");
1795 json_paths
= json_object_new_array();
1797 /* Prefix and num paths displayed once per prefix. */
1798 route_vty_out_detail_header(vty
, bgp
, rn
, NULL
, afi
, safi
, json
);
1800 /* Display each path for this prefix. */
1801 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1802 json_object
*json_path
= NULL
;
1805 json_path
= json_object_new_array();
1807 route_vty_out_detail(vty
, bgp
, &rn
->p
, ri
, afi
, safi
,
1811 json_object_array_add(json_paths
, json_path
);
1818 json_object_object_add(json
, "paths", json_paths
);
1820 json_object_int_add(json
, "numPaths", path_cnt
);
1822 vty_out(vty
, "\nDisplayed %u paths for requested prefix\n",
1828 * Display EVPN routes for a VNI - vty handler.
1829 * If 'type' is non-zero, only routes matching that type are shown.
1830 * If the vtep_ip is non zero, only routes behind that vtep are shown
1832 static void evpn_show_routes_vni(struct vty
*vty
, struct bgp
*bgp
, vni_t vni
,
1833 int type
, struct in_addr vtep_ip
,
1836 struct bgpevpn
*vpn
;
1839 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
1842 vty_out(vty
, "VNI not found\n");
1846 /* Walk this VNI's route table and display appropriate routes. */
1847 show_vni_routes(bgp
, vpn
, type
, vty
, vtep_ip
, json
);
1851 * Display BGP EVPN routing table -- for specific RD and MAC and/or
1852 * IP (vty handler). By definition, only matching type-2 route will be
1855 static void evpn_show_route_rd_macip(struct vty
*vty
, struct bgp
*bgp
,
1856 struct prefix_rd
*prd
, struct ethaddr
*mac
,
1857 struct ipaddr
*ip
, json_object
*json
)
1859 struct prefix_evpn p
;
1860 struct bgp_node
*rn
;
1861 struct bgp_info
*ri
;
1864 u_int32_t path_cnt
= 0;
1865 json_object
*json_paths
= NULL
;
1866 char prefix_str
[BUFSIZ
];
1871 /* See if route exists. Look for both non-sticky and sticky. */
1872 build_evpn_type2_prefix(&p
, mac
, ip
);
1873 rn
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
1874 (struct prefix
*)&p
, prd
);
1875 if (!rn
|| !rn
->info
) {
1877 vty_out(vty
, "%% Network not in table\n");
1881 bgp_evpn_route2str((struct prefix_evpn
*)&p
, prefix_str
,
1882 sizeof(prefix_str
));
1884 /* Prefix and num paths displayed once per prefix. */
1885 route_vty_out_detail_header(vty
, bgp
, rn
, prd
, afi
, safi
, json
);
1888 json_paths
= json_object_new_array();
1890 /* Display each path for this prefix. */
1891 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1892 json_object
*json_path
= NULL
;
1895 json_path
= json_object_new_array();
1897 route_vty_out_detail(vty
, bgp
, &rn
->p
, ri
, afi
, safi
,
1901 json_object_array_add(json_paths
, json_path
);
1906 if (json
&& path_cnt
) {
1908 json_object_object_add(json
, prefix_str
, json_paths
);
1909 json_object_int_add(json
, "numPaths", path_cnt
);
1911 vty_out(vty
, "\nDisplayed %u paths for requested prefix\n",
1917 * Display BGP EVPN routing table -- for specific RD (vty handler)
1918 * If 'type' is non-zero, only routes matching that type are shown.
1920 static void evpn_show_route_rd(struct vty
*vty
, struct bgp
*bgp
,
1921 struct prefix_rd
*prd
, int type
,
1924 struct bgp_node
*rd_rn
;
1925 struct bgp_table
*table
;
1926 struct bgp_node
*rn
;
1927 struct bgp_info
*ri
;
1931 u_int32_t prefix_cnt
, path_cnt
;
1932 char rd_str
[RD_ADDRSTRLEN
];
1933 json_object
*json_rd
= NULL
;
1934 int add_rd_to_json
= 0;
1938 prefix_cnt
= path_cnt
= 0;
1940 prefix_rd2str((struct prefix_rd
*)prd
, rd_str
, sizeof(rd_str
));
1942 rd_rn
= bgp_node_lookup(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
1946 table
= (struct bgp_table
*)rd_rn
->info
;
1951 json_rd
= json_object_new_object();
1952 json_object_string_add(json_rd
, "rd", rd_str
);
1955 /* Display all prefixes with this RD. */
1956 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
1957 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
1958 json_object
*json_prefix
= NULL
;
1959 json_object
*json_paths
= NULL
;
1960 char prefix_str
[BUFSIZ
];
1961 int add_prefix_to_json
= 0;
1963 bgp_evpn_route2str((struct prefix_evpn
*)&rn
->p
, prefix_str
,
1964 sizeof(prefix_str
));
1966 if (type
&& evp
->prefix
.route_type
!= type
)
1970 json_prefix
= json_object_new_object();
1973 /* RD header and legend - once overall. */
1974 if (rd_header
&& !json
) {
1976 "EVPN type-2 prefix: [2]:[ESI]:[EthTag]:[MAClen]:[MAC]\n");
1978 "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
1980 "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
1984 /* Prefix and num paths displayed once per prefix. */
1985 route_vty_out_detail_header(vty
, bgp
, rn
, prd
, afi
,
1992 json_paths
= json_object_new_array();
1994 /* Display each path for this prefix. */
1995 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
1996 json_object
*json_path
= NULL
;
1999 json_path
= json_object_new_array();
2001 route_vty_out_detail(vty
, bgp
, &rn
->p
, ri
, afi
, safi
,
2005 json_object_array_add(json_paths
, json_path
);
2008 add_prefix_to_json
= 1;
2012 if (json
&& add_prefix_to_json
) {
2013 json_object_object_add(json_prefix
, "paths",
2015 json_object_object_add(json_rd
, prefix_str
,
2020 if (json
&& add_rd_to_json
)
2021 json_object_object_add(json
, rd_str
, json_rd
);
2024 json_object_int_add(json
, "numPrefix", prefix_cnt
);
2025 json_object_int_add(json
, "numPaths", path_cnt
);
2027 if (prefix_cnt
== 0)
2028 vty_out(vty
, "No prefixes exist with this RD%s\n",
2029 type
? " (of requested type)" : "");
2032 "\nDisplayed %u prefixes (%u paths) with this RD%s\n",
2033 prefix_cnt
, path_cnt
,
2034 type
? " (of requested type)" : "");
2039 * Display BGP EVPN routing table - all routes (vty handler).
2040 * If 'type' is non-zero, only routes matching that type are shown.
2042 static void evpn_show_all_routes(struct vty
*vty
, struct bgp
*bgp
, int type
,
2045 struct bgp_node
*rd_rn
;
2046 struct bgp_table
*table
;
2047 struct bgp_node
*rn
;
2048 struct bgp_info
*ri
;
2053 u_int32_t prefix_cnt
, path_cnt
;
2057 prefix_cnt
= path_cnt
= 0;
2059 /* EVPN routing table is a 2-level table with the first level being
2062 for (rd_rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_rn
;
2063 rd_rn
= bgp_route_next(rd_rn
)) {
2064 char rd_str
[RD_ADDRSTRLEN
];
2065 json_object
*json_rd
= NULL
; /* contains routes for an RD */
2066 int add_rd_to_json
= 0;
2068 table
= (struct bgp_table
*)rd_rn
->info
;
2072 prefix_rd2str((struct prefix_rd
*)&rd_rn
->p
, rd_str
,
2076 json_rd
= json_object_new_object();
2077 json_object_string_add(json_rd
, "rd", rd_str
);
2082 /* Display all prefixes for an RD */
2083 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
2084 json_object
*json_prefix
=
2085 NULL
; /* contains prefix under a RD */
2086 json_object
*json_paths
=
2087 NULL
; /* array of paths under a prefix*/
2088 struct prefix_evpn
*evp
= (struct prefix_evpn
*)&rn
->p
;
2089 char prefix_str
[BUFSIZ
];
2090 int add_prefix_to_json
= 0;
2092 bgp_evpn_route2str((struct prefix_evpn
*)&rn
->p
,
2093 prefix_str
, sizeof(prefix_str
));
2095 if (type
&& evp
->prefix
.route_type
!= type
)
2099 /* Overall header/legend displayed once. */
2101 bgp_evpn_show_route_header(vty
, bgp
,
2106 /* RD header - per RD. */
2108 bgp_evpn_show_route_rd_header(
2117 json_prefix
= json_object_new_object();
2118 json_paths
= json_object_new_array();
2119 json_object_string_add(json_prefix
, "prefix",
2121 json_object_int_add(json_prefix
, "prefixLen",
2125 /* For EVPN, the prefix is displayed for each path (to
2127 * with code that already exists).
2129 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2130 json_object
*json_path
= NULL
;
2132 add_prefix_to_json
= 1;
2136 json_path
= json_object_new_array();
2138 route_vty_out(vty
, &rn
->p
, ri
, 0, SAFI_EVPN
,
2142 json_object_array_add(json_paths
,
2146 if (json
&& add_prefix_to_json
) {
2147 json_object_object_add(json_prefix
, "paths",
2149 json_object_object_add(json_rd
, prefix_str
,
2154 if (json
&& add_rd_to_json
)
2155 json_object_object_add(json
, rd_str
, json_rd
);
2159 json_object_int_add(json
, "numPrefix", prefix_cnt
);
2160 json_object_int_add(json
, "numPaths", path_cnt
);
2162 if (prefix_cnt
== 0) {
2163 vty_out(vty
, "No EVPN prefixes %sexist\n",
2164 type
? "(of requested type) " : "");
2166 vty_out(vty
, "\nDisplayed %u prefixes (%u paths)%s\n",
2167 prefix_cnt
, path_cnt
,
2168 type
? " (of requested type)" : "");
2174 * Display specified VNI (vty handler)
2176 static void evpn_show_vni(struct vty
*vty
, struct bgp
*bgp
, vni_t vni
,
2179 struct bgpevpn
*vpn
;
2181 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2184 vty_out(vty
, "{}\n");
2186 vty_out(vty
, "VNI not found\n");
2191 display_vni(vty
, vpn
, json
);
2195 * Display a VNI (upon user query).
2197 static void evpn_show_all_vnis(struct vty
*vty
, struct bgp
*bgp
,
2203 num_vnis
= hashcount(bgp
->vnihash
);
2208 json_object_int_add(json
, "numVnis", num_vnis
);
2210 vty_out(vty
, "Number of VNIs: %u\n", num_vnis
);
2211 vty_out(vty
, "Flags: * - Kernel\n");
2212 vty_out(vty
, " %-10s %-15s %-21s %-25s %-25s %-37s\n", "VNI",
2213 "Orig IP", "RD", "Import RT",
2214 "Export RT", "Tenant-Vrf");
2219 hash_iterate(bgp
->vnihash
,
2220 (void (*)(struct hash_backet
*, void *))show_vni_entry
,
2225 * evpn - enable advertisement of default g/w
2227 static void evpn_set_advertise_default_gw(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2230 if (bgp
->advertise_gw_macip
)
2233 bgp
->advertise_gw_macip
= 1;
2234 bgp_zebra_advertise_gw_macip(bgp
, bgp
->advertise_gw_macip
, 0);
2236 if (vpn
->advertise_gw_macip
)
2239 vpn
->advertise_gw_macip
= 1;
2240 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
,
2247 * evpn - disable advertisement of default g/w
2249 static void evpn_unset_advertise_default_gw(struct bgp
*bgp
,
2250 struct bgpevpn
*vpn
)
2253 if (!bgp
->advertise_gw_macip
)
2256 bgp
->advertise_gw_macip
= 0;
2257 bgp_zebra_advertise_gw_macip(bgp
, bgp
->advertise_gw_macip
, 0);
2259 if (!vpn
->advertise_gw_macip
)
2262 vpn
->advertise_gw_macip
= 0;
2263 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
,
2270 * EVPN (VNI advertisement) enabled. Register with zebra.
2272 static void evpn_set_advertise_all_vni(struct bgp
*bgp
)
2274 bgp
->advertise_all_vni
= 1;
2275 bgp_zebra_advertise_all_vni(bgp
, bgp
->advertise_all_vni
);
2279 * EVPN (VNI advertisement) disabled. De-register with zebra. Cleanup VNI
2280 * cache, EVPN routes (delete and withdraw from peers).
2282 static void evpn_unset_advertise_all_vni(struct bgp
*bgp
)
2284 bgp
->advertise_all_vni
= 0;
2285 bgp_zebra_advertise_all_vni(bgp
, bgp
->advertise_all_vni
);
2286 bgp_evpn_cleanup_on_disable(bgp
);
2288 #endif /* HAVE_CUMULUS */
2290 static void write_vni_config(struct vty
*vty
, struct bgpevpn
*vpn
)
2292 char buf1
[RD_ADDRSTRLEN
];
2294 struct listnode
*node
, *nnode
;
2295 struct ecommunity
*ecom
;
2297 if (is_vni_configured(vpn
)) {
2298 vty_out(vty
, " vni %d\n", vpn
->vni
);
2299 if (is_rd_configured(vpn
))
2300 vty_out(vty
, " rd %s\n",
2301 prefix_rd2str(&vpn
->prd
, buf1
, sizeof(buf1
)));
2303 if (is_import_rt_configured(vpn
)) {
2304 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
,
2306 ecom_str
= ecommunity_ecom2str(
2307 ecom
, ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2308 vty_out(vty
, " route-target import %s\n",
2310 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
2314 if (is_export_rt_configured(vpn
)) {
2315 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
,
2317 ecom_str
= ecommunity_ecom2str(
2318 ecom
, ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
2319 vty_out(vty
, " route-target export %s\n",
2321 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
2325 if (vpn
->advertise_gw_macip
)
2326 vty_out(vty
, " advertise-default-gw\n");
2328 vty_out(vty
, " exit-vni\n");
2332 static void write_vni_config_for_entry(struct hash_backet
*backet
,
2335 struct bgpevpn
*vpn
= (struct bgpevpn
*)backet
->data
;
2336 write_vni_config(vty
, vpn
);
2339 #if defined(HAVE_CUMULUS)
2340 DEFUN (bgp_evpn_advertise_default_gw_vni
,
2341 bgp_evpn_advertise_default_gw_vni_cmd
,
2342 "advertise-default-gw",
2343 "Advertise default g/w mac-ip routes in EVPN for a VNI\n")
2345 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
2346 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
2354 evpn_set_advertise_default_gw(bgp
, vpn
);
2359 DEFUN (no_bgp_evpn_advertise_default_vni_gw
,
2360 no_bgp_evpn_advertise_default_gw_vni_cmd
,
2361 "no advertise-default-gw",
2363 "Withdraw default g/w mac-ip routes from EVPN for a VNI\n")
2365 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
2366 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
2374 evpn_unset_advertise_default_gw(bgp
, vpn
);
2380 DEFUN (bgp_evpn_advertise_default_gw
,
2381 bgp_evpn_advertise_default_gw_cmd
,
2382 "advertise-default-gw",
2383 "Advertise All default g/w mac-ip routes in EVPN\n")
2385 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
2390 evpn_set_advertise_default_gw(bgp
, NULL
);
2395 DEFUN (no_bgp_evpn_advertise_default_gw
,
2396 no_bgp_evpn_advertise_default_gw_cmd
,
2397 "no advertise-default-gw",
2399 "Withdraw All default g/w mac-ip routes from EVPN\n")
2401 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
2406 evpn_unset_advertise_default_gw(bgp
, NULL
);
2411 DEFUN (bgp_evpn_advertise_all_vni
,
2412 bgp_evpn_advertise_all_vni_cmd
,
2413 "advertise-all-vni",
2414 "Advertise All local VNIs\n")
2416 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
2420 evpn_set_advertise_all_vni(bgp
);
2424 DEFUN (no_bgp_evpn_advertise_all_vni
,
2425 no_bgp_evpn_advertise_all_vni_cmd
,
2426 "no advertise-all-vni",
2428 "Advertise All local VNIs\n")
2430 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
2434 evpn_unset_advertise_all_vni(bgp
);
2438 DEFUN (bgp_evpn_advertise_type5
,
2439 bgp_evpn_advertise_type5_cmd
,
2440 "advertise " BGP_AFI_CMD_STR
"" BGP_SAFI_CMD_STR
,
2441 "Advertise prefix routes\n"
2445 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
); /* bgp vrf instance */
2451 argv_find_and_parse_afi(argv
, argc
, &idx_afi
, &afi
);
2452 argv_find_and_parse_safi(argv
, argc
, &idx_safi
, &safi
);
2454 if (!(afi
== AFI_IP
) || (afi
== AFI_IP6
)) {
2456 "%%only ipv4 or ipv6 address families are supported");
2460 if (safi
!= SAFI_UNICAST
) {
2462 "%%only ipv4 unicast or ipv6 unicast are supported");
2466 if (afi
== AFI_IP
) {
2468 /* if we are already advertising ipv4 prefix as type-5
2470 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
,
2471 BGP_VRF_ADVERTISE_IPV4_IN_EVPN
)) {
2472 SET_FLAG(bgp_vrf
->vrf_flags
,
2473 BGP_VRF_ADVERTISE_IPV4_IN_EVPN
);
2474 bgp_evpn_advertise_type5_routes(bgp_vrf
, afi
, safi
);
2478 /* if we are already advertising ipv6 prefix as type-5
2480 if (!CHECK_FLAG(bgp_vrf
->vrf_flags
,
2481 BGP_VRF_ADVERTISE_IPV6_IN_EVPN
)) {
2482 SET_FLAG(bgp_vrf
->vrf_flags
,
2483 BGP_VRF_ADVERTISE_IPV6_IN_EVPN
);
2484 bgp_evpn_advertise_type5_routes(bgp_vrf
, afi
, safi
);
2490 DEFUN (no_bgp_evpn_advertise_type5
,
2491 no_bgp_evpn_advertise_type5_cmd
,
2492 "no advertise " BGP_AFI_CMD_STR
"" BGP_SAFI_CMD_STR
,
2494 "Advertise prefix routes\n"
2498 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
); /* bgp vrf instance */
2504 argv_find_and_parse_afi(argv
, argc
, &idx_afi
, &afi
);
2505 argv_find_and_parse_safi(argv
, argc
, &idx_safi
, &safi
);
2507 if (!(afi
== AFI_IP
) || (afi
== AFI_IP6
)) {
2509 "%%only ipv4 or ipv6 address families are supported");
2513 if (safi
!= SAFI_UNICAST
) {
2515 "%%only ipv4 unicast or ipv6 unicast are supported");
2519 if (afi
== AFI_IP
) {
2521 /* if we are already advertising ipv4 prefix as type-5
2523 if (CHECK_FLAG(bgp_vrf
->vrf_flags
,
2524 BGP_VRF_ADVERTISE_IPV4_IN_EVPN
)) {
2525 bgp_evpn_withdraw_type5_routes(bgp_vrf
, afi
, safi
);
2526 UNSET_FLAG(bgp_vrf
->vrf_flags
,
2527 BGP_VRF_ADVERTISE_IPV4_IN_EVPN
);
2531 /* if we are already advertising ipv6 prefix as type-5
2533 if (CHECK_FLAG(bgp_vrf
->vrf_flags
,
2534 BGP_VRF_ADVERTISE_IPV6_IN_EVPN
)) {
2535 bgp_evpn_withdraw_type5_routes(bgp_vrf
, afi
, safi
);
2536 UNSET_FLAG(bgp_vrf
->vrf_flags
,
2537 BGP_VRF_ADVERTISE_IPV6_IN_EVPN
);
2544 * Display VNI information - for all or a specific VNI
2546 DEFUN(show_bgp_l2vpn_evpn_vni
,
2547 show_bgp_l2vpn_evpn_vni_cmd
,
2548 "show bgp l2vpn evpn vni [(1-16777215)] [json]",
2561 json_object
*json
= NULL
;
2563 uj
= use_json(argc
, argv
);
2565 bgp
= bgp_get_default();
2569 if (!argv_find(argv
, argc
, "evpn", &idx
))
2573 json
= json_object_new_object();
2575 if ((uj
&& argc
== ((idx
+ 1) + 2)) || (!uj
&& argc
== (idx
+ 1) + 1)) {
2577 json_object_string_add(json
, "advertiseGatewayMacip",
2578 bgp
->advertise_gw_macip
2581 json_object_string_add(json
, "advertiseAllVnis",
2586 vty_out(vty
, "Advertise Gateway Macip: %s\n",
2587 bgp
->advertise_gw_macip
? "Enabled"
2590 /* Display all VNIs */
2591 vty_out(vty
, "Advertise All VNI flag: %s\n",
2592 is_evpn_enabled() ? "Enabled" : "Disabled");
2595 evpn_show_all_vnis(vty
, bgp
, json
);
2599 if (!argv_find(argv
, argc
, "vni", &vni_idx
))
2602 /* Display specific VNI */
2603 vni
= strtoul(argv
[vni_idx
+ 1]->arg
, NULL
, 10);
2604 evpn_show_vni(vty
, bgp
, vni
, json
);
2608 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2609 json
, JSON_C_TO_STRING_PRETTY
));
2610 json_object_free(json
);
2617 * Display EVPN neighbor summary.
2619 DEFUN(show_bgp_l2vpn_evpn_summary
,
2620 show_bgp_l2vpn_evpn_summary_cmd
,
2621 "show bgp l2vpn evpn summary [json]",
2626 "Summary of BGP neighbor status\n"
2629 u_char uj
= use_json(argc
, argv
);
2630 return bgp_show_summary_vty(vty
, NULL
, AFI_L2VPN
, SAFI_EVPN
, uj
);
2634 * Display global EVPN routing table.
2636 DEFUN(show_bgp_l2vpn_evpn_route
,
2637 show_bgp_l2vpn_evpn_route_cmd
,
2638 "show bgp l2vpn evpn route [type <macip|multicast>] [json]",
2643 "EVPN route information\n"
2644 "Specify Route type\n"
2645 "MAC-IP (Type-2) route\n"
2646 "Multicast (Type-3) route\n"
2653 json_object
*json
= NULL
;
2655 uj
= use_json(argc
, argv
);
2657 bgp
= bgp_get_default();
2662 json
= json_object_new_object();
2665 if (argv_find(argv
, argc
, "type", &type_idx
)) {
2666 /* Specific type is requested */
2667 if (strncmp(argv
[type_idx
+ 1]->arg
, "ma", 2) == 0)
2668 type
= BGP_EVPN_MAC_IP_ROUTE
;
2669 else if (strncmp(argv
[type_idx
+ 1]->arg
, "mu", 2) == 0)
2670 type
= BGP_EVPN_IMET_ROUTE
;
2675 evpn_show_all_routes(vty
, bgp
, type
, json
);
2678 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2679 json
, JSON_C_TO_STRING_PRETTY
));
2680 json_object_free(json
);
2687 * Display global EVPN routing table for specific RD.
2689 DEFUN(show_bgp_l2vpn_evpn_route_rd
,
2690 show_bgp_l2vpn_evpn_route_rd_cmd
,
2691 "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|multicast>] [json]",
2696 "EVPN route information\n"
2697 "Route Distinguisher\n"
2698 "ASN:XX or A.B.C.D:XX\n"
2699 "Specify Route type\n"
2700 "MAC-IP (Type-2) route\n"
2701 "Multicast (Type-3) route\n"
2706 struct prefix_rd prd
;
2711 json_object
*json
= NULL
;
2713 bgp
= bgp_get_default();
2717 /* check if we need json output */
2718 uj
= use_json(argc
, argv
);
2720 json
= json_object_new_object();
2723 if (argv_find(argv
, argc
, "rd", &rd_idx
)) {
2724 ret
= str2prefix_rd(argv
[rd_idx
+ 1]->arg
, &prd
);
2727 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2733 if (argv_find(argv
, argc
, "type", &type_idx
)) {
2734 /* Specific type is requested */
2735 if (strncmp(argv
[type_idx
+ 1]->arg
, "ma", 2) == 0)
2736 type
= BGP_EVPN_MAC_IP_ROUTE
;
2737 else if (strncmp(argv
[type_idx
+ 1]->arg
, "mu", 2) == 0)
2738 type
= BGP_EVPN_IMET_ROUTE
;
2743 evpn_show_route_rd(vty
, bgp
, &prd
, type
, json
);
2746 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2747 json
, JSON_C_TO_STRING_PRETTY
));
2748 json_object_free(json
);
2755 * Display global EVPN routing table for specific RD and MACIP.
2757 DEFUN(show_bgp_l2vpn_evpn_route_rd_macip
,
2758 show_bgp_l2vpn_evpn_route_rd_macip_cmd
,
2759 "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD] [json]",
2764 "EVPN route information\n"
2765 "Route Distinguisher\n"
2766 "ASN:XX or A.B.C.D:XX\n"
2768 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2770 "IP address (IPv4 or IPv6)\n"
2775 struct prefix_rd prd
;
2782 json_object
*json
= NULL
;
2784 memset(&mac
, 0, sizeof(struct ethaddr
));
2785 memset(&ip
, 0, sizeof(struct ipaddr
));
2787 bgp
= bgp_get_default();
2791 /* check if we need json output */
2792 uj
= use_json(argc
, argv
);
2794 json
= json_object_new_object();
2797 if (argv_find(argv
, argc
, "rd", &rd_idx
)) {
2798 ret
= str2prefix_rd(argv
[rd_idx
+ 1]->arg
, &prd
);
2800 vty_out(vty
, "%% Malformed Route Distinguisher\n");
2806 if (argv_find(argv
, argc
, "mac", &mac_idx
)) {
2807 if (!prefix_str2mac(argv
[mac_idx
+ 1]->arg
, &mac
)) {
2808 vty_out(vty
, "%% Malformed MAC address\n");
2813 /* get the ip if specified */
2814 if (argv_find(argv
, argc
, "ip", &ip_idx
)) {
2815 if (str2ipaddr(argv
[ip_idx
+ 1]->arg
, &ip
) != 0) {
2816 vty_out(vty
, "%% Malformed IP address\n");
2821 evpn_show_route_rd_macip(vty
, bgp
, &prd
, &mac
, &ip
, json
);
2824 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2825 json
, JSON_C_TO_STRING_PRETTY
));
2826 json_object_free(json
);
2833 * Display per-VRF EVPN routing table.
2835 DEFUN(show_bgp_l2vpn_evpn_route_vrf
, show_bgp_l2vpn_evpn_route_vrf_cmd
,
2836 "show bgp l2vpn evpn route vrf VRFNAME",
2841 "EVPN route information\n"
2846 char *vrf_name
= NULL
;
2847 struct bgp
*bgp_vrf
= NULL
;
2849 vrf_name
= argv
[vrf_idx
]->arg
;
2850 bgp_vrf
= bgp_lookup_by_name(vrf_name
);
2854 evpn_show_vrf_routes(vty
, bgp_vrf
);
2860 * Display per-VNI EVPN routing table.
2862 DEFUN(show_bgp_l2vpn_evpn_route_vni
, show_bgp_l2vpn_evpn_route_vni_cmd
,
2863 "show bgp l2vpn evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>] [json]",
2868 "EVPN route information\n"
2869 "VXLAN Network Identifier\n"
2871 "Specify Route type\n"
2872 "MAC-IP (Type-2) route\n"
2873 "Multicast (Type-3) route\n"
2875 "Remote VTEP IP address\n"
2880 struct in_addr vtep_ip
;
2884 json_object
*json
= NULL
;
2886 bgp
= bgp_get_default();
2890 /* check if we need json output */
2891 uj
= use_json(argc
, argv
);
2893 json
= json_object_new_object();
2895 if (!argv_find(argv
, argc
, "evpn", &idx
))
2900 vni
= strtoul(argv
[idx
+ 3]->arg
, NULL
, 10);
2902 if ((!uj
&& ((argc
== (idx
+ 1 + 5)) && argv
[idx
+ 4]->arg
))
2903 || (uj
&& ((argc
== (idx
+ 1 + 6)) && argv
[idx
+ 4]->arg
))) {
2904 if (strncmp(argv
[idx
+ 4]->arg
, "type", 4) == 0) {
2905 if (strncmp(argv
[idx
+ 5]->arg
, "ma", 2) == 0)
2906 type
= BGP_EVPN_MAC_IP_ROUTE
;
2907 else if (strncmp(argv
[idx
+ 5]->arg
, "mu", 2) == 0)
2908 type
= BGP_EVPN_IMET_ROUTE
;
2911 } else if (strncmp(argv
[idx
+ 4]->arg
, "vtep", 4) == 0) {
2912 if (!inet_aton(argv
[idx
+ 5]->arg
, &vtep_ip
)) {
2913 vty_out(vty
, "%% Malformed VTEP IP address\n");
2920 evpn_show_routes_vni(vty
, bgp
, vni
, type
, vtep_ip
, json
);
2923 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2924 json
, JSON_C_TO_STRING_PRETTY
));
2925 json_object_free(json
);
2932 * Display per-VNI EVPN routing table for specific MACIP.
2934 DEFUN(show_bgp_l2vpn_evpn_route_vni_macip
,
2935 show_bgp_l2vpn_evpn_route_vni_macip_cmd
,
2936 "show bgp l2vpn evpn route vni (1-16777215) mac WORD [ip WORD] [json]",
2941 "EVPN route information\n"
2942 "VXLAN Network Identifier\n"
2945 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2947 "IP address (IPv4 or IPv6)\n"
2956 json_object
*json
= NULL
;
2958 bgp
= bgp_get_default();
2962 /* check if we need json output */
2963 uj
= use_json(argc
, argv
);
2965 json
= json_object_new_object();
2967 if (!argv_find(argv
, argc
, "evpn", &idx
))
2971 vni
= strtoul(argv
[idx
+ 3]->arg
, NULL
, 10);
2974 if (!prefix_str2mac(argv
[idx
+ 5]->arg
, &mac
)) {
2975 vty_out(vty
, "%% Malformed MAC address\n");
2980 memset(&ip
, 0, sizeof(ip
));
2981 if ((!uj
&& ((argc
== (idx
+ 1 + 7)) && argv
[idx
+ 7]->arg
!= NULL
))
2983 && ((argc
== (idx
+ 1 + 8)) && argv
[idx
+ 7]->arg
!= NULL
))) {
2984 if (str2ipaddr(argv
[idx
+ 7]->arg
, &ip
) != 0) {
2985 vty_out(vty
, "%% Malformed IP address\n");
2990 evpn_show_route_vni_macip(vty
, bgp
, vni
, &mac
, &ip
, json
);
2993 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2994 json
, JSON_C_TO_STRING_PRETTY
));
2995 json_object_free(json
);
3002 * Display per-VNI EVPN routing table for specific multicast IP (remote VTEP).
3004 DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast
,
3005 show_bgp_l2vpn_evpn_route_vni_multicast_cmd
,
3006 "show bgp l2vpn evpn route vni (1-16777215) multicast A.B.C.D [json]",
3011 "EVPN route information\n"
3012 "VXLAN Network Identifier\n"
3014 "Multicast (Type-3) route\n"
3015 "Originating Router IP address\n"
3021 struct in_addr orig_ip
;
3024 json_object
*json
= NULL
;
3026 bgp
= bgp_get_default();
3030 /* check if we need json output */
3031 uj
= use_json(argc
, argv
);
3033 json
= json_object_new_object();
3035 if (!argv_find(argv
, argc
, "evpn", &idx
))
3039 vni
= strtoul(argv
[idx
+ 3]->arg
, NULL
, 10);
3042 ret
= inet_aton(argv
[idx
+ 5]->arg
, &orig_ip
);
3044 vty_out(vty
, "%% Malformed Originating Router IP address\n");
3048 evpn_show_route_vni_multicast(vty
, bgp
, vni
, orig_ip
, json
);
3051 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3052 json
, JSON_C_TO_STRING_PRETTY
));
3053 json_object_free(json
);
3060 * Display per-VNI EVPN routing table - for all VNIs.
3062 DEFUN(show_bgp_l2vpn_evpn_route_vni_all
,
3063 show_bgp_l2vpn_evpn_route_vni_all_cmd
,
3064 "show bgp l2vpn evpn route vni all [vtep A.B.C.D] [json]",
3069 "EVPN route information\n"
3070 "VXLAN Network Identifier\n"
3073 "Remote VTEP IP address\n"
3077 struct in_addr vtep_ip
;
3080 json_object
*json
= NULL
;
3082 bgp
= bgp_get_default();
3086 /* check if we need json output */
3087 uj
= use_json(argc
, argv
);
3089 json
= json_object_new_object();
3091 if (!argv_find(argv
, argc
, "evpn", &idx
))
3095 if ((!uj
&& (argc
== (idx
+ 1 + 5) && argv
[idx
+ 5]->arg
))
3096 || (uj
&& (argc
== (idx
+ 1 + 6) && argv
[idx
+ 5]->arg
))) {
3097 if (!inet_aton(argv
[idx
+ 5]->arg
, &vtep_ip
)) {
3098 vty_out(vty
, "%% Malformed VTEP IP address\n");
3103 evpn_show_routes_vni_all(vty
, bgp
, vtep_ip
, json
);
3106 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3107 json
, JSON_C_TO_STRING_PRETTY
));
3108 json_object_free(json
);
3115 * Display EVPN import route-target hash table
3117 DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt
,
3118 show_bgp_l2vpn_evpn_vrf_import_rt_cmd
,
3119 "show bgp l2vpn evpn vrf-import-rt [json]",
3124 "Show vrf import route target\n"
3128 struct bgp
*bgp_def
= NULL
;
3129 json_object
*json
= NULL
;
3131 bgp_def
= bgp_get_default();
3135 uj
= use_json(argc
, argv
);
3137 json
= json_object_new_object();
3139 evpn_show_vrf_import_rts(vty
, bgp_def
, json
);
3142 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3143 json
, JSON_C_TO_STRING_PRETTY
));
3144 json_object_free(json
);
3151 * Display EVPN import route-target hash table
3153 DEFUN(show_bgp_l2vpn_evpn_import_rt
,
3154 show_bgp_l2vpn_evpn_import_rt_cmd
,
3155 "show bgp l2vpn evpn import-rt [json]",
3160 "Show import route target\n"
3165 json_object
*json
= NULL
;
3167 bgp
= bgp_get_default();
3171 uj
= use_json(argc
, argv
);
3173 json
= json_object_new_object();
3175 evpn_show_import_rts(vty
, bgp
, json
);
3178 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3179 json
, JSON_C_TO_STRING_PRETTY
));
3180 json_object_free(json
);
3186 #if defined(HAVE_CUMULUS)
3187 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni
, show_bgp_evpn_vni_cmd
,
3188 "show bgp evpn vni [(1-16777215)]", SHOW_STR BGP_STR EVPN_HELP_STR
3192 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary
, show_bgp_evpn_summary_cmd
,
3193 "show bgp evpn summary [json]", SHOW_STR BGP_STR EVPN_HELP_STR
3194 "Summary of BGP neighbor status\n"
3197 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route
, show_bgp_evpn_route_cmd
,
3198 "show bgp evpn route [type <macip|multicast>]",
3199 SHOW_STR BGP_STR EVPN_HELP_STR
3200 "EVPN route information\n"
3201 "Specify Route type\n"
3202 "MAC-IP (Type-2) route\n"
3203 "Multicast (Type-3) route\n")
3206 show_bgp_l2vpn_evpn_route_rd
, show_bgp_evpn_route_rd_cmd
,
3207 "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|multicast>]",
3208 SHOW_STR BGP_STR EVPN_HELP_STR
3209 "EVPN route information\n"
3210 "Route Distinguisher\n"
3211 "ASN:XX or A.B.C.D:XX\n"
3212 "Specify Route type\n"
3213 "MAC-IP (Type-2) route\n"
3214 "Multicast (Type-3) route\n")
3217 show_bgp_l2vpn_evpn_route_rd_macip
, show_bgp_evpn_route_rd_macip_cmd
,
3218 "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD]",
3219 SHOW_STR BGP_STR EVPN_HELP_STR
3220 "EVPN route information\n"
3221 "Route Distinguisher\n"
3222 "ASN:XX or A.B.C.D:XX\n"
3224 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3226 "IP address (IPv4 or IPv6)\n")
3229 show_bgp_l2vpn_evpn_route_vni
, show_bgp_evpn_route_vni_cmd
,
3230 "show bgp evpn route vni (1-16777215) [<type <macip|multicast> | vtep A.B.C.D>]",
3231 SHOW_STR BGP_STR EVPN_HELP_STR
3232 "EVPN route information\n"
3233 "VXLAN Network Identifier\n"
3235 "Specify Route type\n"
3236 "MAC-IP (Type-2) route\n"
3237 "Multicast (Type-3) route\n"
3239 "Remote VTEP IP address\n")
3241 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip
,
3242 show_bgp_evpn_route_vni_macip_cmd
,
3243 "show bgp evpn route vni (1-16777215) mac WORD [ip WORD]",
3244 SHOW_STR BGP_STR EVPN_HELP_STR
3245 "EVPN route information\n"
3246 "VXLAN Network Identifier\n"
3249 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3251 "IP address (IPv4 or IPv6)\n")
3253 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast
,
3254 show_bgp_evpn_route_vni_multicast_cmd
,
3255 "show bgp evpn route vni (1-16777215) multicast A.B.C.D",
3256 SHOW_STR BGP_STR EVPN_HELP_STR
3257 "EVPN route information\n"
3258 "VXLAN Network Identifier\n"
3260 "Multicast (Type-3) route\n"
3261 "Originating Router IP address\n")
3263 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all
, show_bgp_evpn_route_vni_all_cmd
,
3264 "show bgp evpn route vni all [vtep A.B.C.D]",
3265 SHOW_STR BGP_STR EVPN_HELP_STR
3266 "EVPN route information\n"
3267 "VXLAN Network Identifier\n"
3270 "Remote VTEP IP address\n")
3272 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_import_rt
, show_bgp_evpn_import_rt_cmd
,
3273 "show bgp evpn import-rt",
3274 SHOW_STR BGP_STR EVPN_HELP_STR
"Show import route target\n")
3277 DEFUN_NOSH (bgp_evpn_vni
,
3280 "VXLAN Network Identifier\n"
3284 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3285 struct bgpevpn
*vpn
;
3290 vni
= strtoul(argv
[1]->arg
, NULL
, 10);
3292 /* Create VNI, or mark as configured. */
3293 vpn
= evpn_create_update_vni(bgp
, vni
);
3295 vty_out(vty
, "%% Failed to create VNI \n");
3299 VTY_PUSH_CONTEXT_SUB(BGP_EVPN_VNI_NODE
, vpn
);
3303 DEFUN (no_bgp_evpn_vni
,
3304 no_bgp_evpn_vni_cmd
,
3305 "no vni (1-16777215)",
3307 "VXLAN Network Identifier\n"
3311 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3312 struct bgpevpn
*vpn
;
3317 vni
= strtoul(argv
[2]->arg
, NULL
, 10);
3319 /* Check if we should disallow. */
3320 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
3322 vty_out(vty
, "%% Specified VNI does not exist\n");
3325 if (!is_vni_configured(vpn
)) {
3326 vty_out(vty
, "%% Specified VNI is not configured\n");
3330 evpn_delete_vni(bgp
, vpn
);
3334 DEFUN_NOSH (exit_vni
,
3337 "Exit from VNI mode\n")
3339 if (vty
->node
== BGP_EVPN_VNI_NODE
)
3340 vty
->node
= BGP_EVPN_NODE
;
3344 DEFUN (bgp_evpn_vrf_rd
,
3345 bgp_evpn_vrf_rd_cmd
,
3346 "rd ASN:NN_OR_IP-ADDRESS:NN",
3347 "Route Distinguisher\n"
3348 "ASN:XX or A.B.C.D:XX\n")
3351 struct prefix_rd prd
;
3352 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3357 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
3359 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3363 /* If same as existing value, there is nothing more to do. */
3364 if (bgp_evpn_vrf_rd_matches_existing(bgp_vrf
, &prd
))
3367 /* Configure or update the RD. */
3368 evpn_configure_vrf_rd(bgp_vrf
, &prd
);
3372 DEFUN (no_bgp_evpn_vrf_rd
,
3373 no_bgp_evpn_vrf_rd_cmd
,
3374 "no rd ASN:NN_OR_IP-ADDRESS:NN",
3376 "Route Distinguisher\n"
3377 "ASN:XX or A.B.C.D:XX\n")
3380 struct prefix_rd prd
;
3381 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3386 ret
= str2prefix_rd(argv
[2]->arg
, &prd
);
3388 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3392 /* Check if we should disallow. */
3393 if (!is_vrf_rd_configured(bgp_vrf
)) {
3394 vty_out(vty
, "%% RD is not configured for this VRF\n");
3398 if (!bgp_evpn_vrf_rd_matches_existing(bgp_vrf
, &prd
)) {
3400 "%% RD specified does not match configuration for this VRF\n");
3404 evpn_unconfigure_vrf_rd(bgp_vrf
);
3408 DEFUN (no_bgp_evpn_vrf_rd_without_val
,
3409 no_bgp_evpn_vrf_rd_without_val_cmd
,
3412 "Route Distinguisher\n")
3414 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3419 /* Check if we should disallow. */
3420 if (!is_vrf_rd_configured(bgp_vrf
)) {
3421 vty_out(vty
, "%% RD is not configured for this VRF\n");
3425 evpn_unconfigure_vrf_rd(bgp_vrf
);
3429 DEFUN (bgp_evpn_vni_rd
,
3430 bgp_evpn_vni_rd_cmd
,
3431 "rd ASN:NN_OR_IP-ADDRESS:NN",
3432 "Route Distinguisher\n"
3433 "ASN:XX or A.B.C.D:XX\n")
3435 struct prefix_rd prd
;
3436 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3437 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3443 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
3445 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3449 /* If same as existing value, there is nothing more to do. */
3450 if (bgp_evpn_rd_matches_existing(vpn
, &prd
))
3453 /* Configure or update the RD. */
3454 evpn_configure_rd(bgp
, vpn
, &prd
);
3458 DEFUN (no_bgp_evpn_vni_rd
,
3459 no_bgp_evpn_vni_rd_cmd
,
3460 "no rd ASN:NN_OR_IP-ADDRESS:NN",
3462 "Route Distinguisher\n"
3463 "ASN:XX or A.B.C.D:XX\n")
3465 struct prefix_rd prd
;
3466 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3467 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3473 ret
= str2prefix_rd(argv
[2]->arg
, &prd
);
3475 vty_out(vty
, "%% Malformed Route Distinguisher\n");
3479 /* Check if we should disallow. */
3480 if (!is_rd_configured(vpn
)) {
3481 vty_out(vty
, "%% RD is not configured for this VNI\n");
3485 if (!bgp_evpn_rd_matches_existing(vpn
, &prd
)) {
3487 "%% RD specified does not match configuration for this VNI\n");
3491 evpn_unconfigure_rd(bgp
, vpn
);
3495 DEFUN (no_bgp_evpn_vni_rd_without_val
,
3496 no_bgp_evpn_vni_rd_without_val_cmd
,
3499 "Route Distinguisher\n")
3501 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3502 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3507 /* Check if we should disallow. */
3508 if (!is_rd_configured(vpn
)) {
3509 vty_out(vty
, "%% RD is not configured for this VNI\n");
3513 evpn_unconfigure_rd(bgp
, vpn
);
3518 * Loop over all extended-communities in the route-target list rtl and
3519 * return 1 if we find ecomtarget
3521 static int bgp_evpn_rt_matches_existing(struct list
*rtl
,
3522 struct ecommunity
*ecomtarget
)
3524 struct listnode
*node
, *nnode
;
3525 struct ecommunity
*ecom
;
3527 for (ALL_LIST_ELEMENTS(rtl
, node
, nnode
, ecom
)) {
3528 if (ecommunity_match(ecom
, ecomtarget
))
3535 /* display L3VNI related info for a VRF instance */
3536 DEFUN (show_bgp_vrf_l3vni_info
,
3537 show_bgp_vrf_l3vni_info_cmd
,
3538 "show bgp vrf VRFNAME l3vni info [json]",
3547 char buf
[ETHER_ADDR_STRLEN
];
3548 char buf1
[INET6_ADDRSTRLEN
];
3550 const char *name
= NULL
;
3551 struct bgp
*bgp
= NULL
;
3552 struct listnode
*node
= NULL
;
3553 struct bgpevpn
*vpn
= NULL
;
3554 struct ecommunity
*ecom
= NULL
;
3555 json_object
*json
= NULL
;
3556 json_object
*json_vnis
= NULL
;
3557 json_object
*json_export_rts
= NULL
;
3558 json_object
*json_import_rts
= NULL
;
3559 u_char uj
= use_json(argc
, argv
);
3562 json
= json_object_new_object();
3563 json_vnis
= json_object_new_array();
3564 json_export_rts
= json_object_new_array();
3565 json_import_rts
= json_object_new_array();
3568 name
= argv
[idx_vrf
]->arg
;
3569 bgp
= bgp_lookup_by_name(name
);
3572 vty_out(vty
, "BGP instance for VRF %s not found",
3575 json_object_string_add(json
, "warning",
3576 "BGP instance not found");
3577 vty_out(vty
, "%s\n",
3578 json_object_to_json_string(json
));
3579 json_object_free(json
);
3585 vty_out(vty
, "BGP VRF: %s\n", name
);
3586 vty_out(vty
, " Local-Ip: %s\n",
3587 inet_ntoa(bgp
->originator_ip
));
3588 vty_out(vty
, " L3-VNI: %u\n", bgp
->l3vni
);
3589 vty_out(vty
, " Rmac: %s\n",
3590 prefix_mac2str(&bgp
->rmac
, buf
, sizeof(buf
)));
3591 vty_out(vty
, " L2-VNI List:\n");
3593 for (ALL_LIST_ELEMENTS_RO(bgp
->l2vnis
, node
, vpn
))
3594 vty_out(vty
, "%u ", vpn
->vni
);
3596 vty_out(vty
, " Export-RTs:\n");
3598 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_export_rtl
, node
, ecom
))
3599 vty_out(vty
, "%s ", ecommunity_str(ecom
));
3601 vty_out(vty
, " Import-RTs:\n");
3603 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_import_rtl
, node
, ecom
))
3604 vty_out(vty
, "%s ", ecommunity_str(ecom
));
3606 vty_out(vty
, " RD: %s\n",
3607 prefix_rd2str(&bgp
->vrf_prd
, buf1
, RD_ADDRSTRLEN
));
3609 json_object_string_add(json
, "vrf", name
);
3610 json_object_string_add(json
, "local-ip",
3611 inet_ntoa(bgp
->originator_ip
));
3612 json_object_int_add(json
, "l3vni", bgp
->l3vni
);
3613 json_object_string_add(json
, "rmac",
3614 prefix_mac2str(&bgp
->rmac
, buf
,
3616 /* list of l2vnis */
3617 for (ALL_LIST_ELEMENTS_RO(bgp
->l2vnis
, node
, vpn
))
3618 json_object_array_add(json_vnis
,
3619 json_object_new_int(vpn
->vni
));
3620 json_object_object_add(json
, "l2vnis", json_vnis
);
3623 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_export_rtl
, node
, ecom
))
3624 json_object_array_add(json_export_rts
,
3625 json_object_new_string(
3626 ecommunity_str(ecom
)));
3627 json_object_object_add(json
, "export-rts", json_export_rts
);
3630 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_import_rtl
, node
, ecom
))
3631 json_object_array_add(json_import_rts
,
3632 json_object_new_string(
3633 ecommunity_str(ecom
)));
3634 json_object_object_add(json
, "import-rts", json_import_rts
);
3635 json_object_string_add(
3637 prefix_rd2str(&bgp
->vrf_prd
, buf1
, RD_ADDRSTRLEN
));
3642 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
3643 json
, JSON_C_TO_STRING_PRETTY
));
3644 json_object_free(json
);
3649 /* import/export rt for l3vni-vrf */
3650 DEFUN (bgp_evpn_vrf_rt
,
3651 bgp_evpn_vrf_rt_cmd
,
3652 "route-target <both|import|export> RT",
3654 "import and export\n"
3657 "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3660 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3661 struct ecommunity
*ecomadd
= NULL
;
3666 if (!strcmp(argv
[1]->arg
, "import"))
3667 rt_type
= RT_TYPE_IMPORT
;
3668 else if (!strcmp(argv
[1]->arg
, "export"))
3669 rt_type
= RT_TYPE_EXPORT
;
3670 else if (!strcmp(argv
[1]->arg
, "both"))
3671 rt_type
= RT_TYPE_BOTH
;
3673 vty_out(vty
, "%% Invalid Route Target type\n");
3677 /* Add/update the import route-target */
3678 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_IMPORT
) {
3679 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
3680 ECOMMUNITY_ROUTE_TARGET
, 0);
3682 vty_out(vty
, "%% Malformed Route Target list\n");
3685 ecommunity_str(ecomadd
);
3687 /* Do nothing if we already have this import route-target */
3688 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_import_rtl
,
3690 bgp_evpn_configure_import_rt_for_vrf(bgp
, ecomadd
);
3693 /* Add/update the export route-target */
3694 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_EXPORT
) {
3695 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
3696 ECOMMUNITY_ROUTE_TARGET
, 0);
3698 vty_out(vty
, "%% Malformed Route Target list\n");
3701 ecommunity_str(ecomadd
);
3703 /* Do nothing if we already have this export route-target */
3704 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_export_rtl
,
3706 bgp_evpn_configure_export_rt_for_vrf(bgp
, ecomadd
);
3712 DEFUN (no_bgp_evpn_vrf_rt
,
3713 no_bgp_evpn_vrf_rt_cmd
,
3714 "no route-target <both|import|export> RT",
3717 "import and export\n"
3720 "ASN:XX or A.B.C.D:XX\n")
3722 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3723 int rt_type
, found_ecomdel
;
3724 struct ecommunity
*ecomdel
= NULL
;
3729 if (!strcmp(argv
[2]->arg
, "import"))
3730 rt_type
= RT_TYPE_IMPORT
;
3731 else if (!strcmp(argv
[2]->arg
, "export"))
3732 rt_type
= RT_TYPE_EXPORT
;
3733 else if (!strcmp(argv
[2]->arg
, "both"))
3734 rt_type
= RT_TYPE_BOTH
;
3736 vty_out(vty
, "%% Invalid Route Target type\n");
3740 if (rt_type
== RT_TYPE_IMPORT
) {
3741 if (!CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
)) {
3743 "%% Import RT is not configured for this VRF\n");
3746 } else if (rt_type
== RT_TYPE_EXPORT
) {
3747 if (!CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
)) {
3749 "%% Export RT is not configured for this VRF\n");
3752 } else if (rt_type
== RT_TYPE_BOTH
) {
3753 if (!CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
)
3754 && !CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
)) {
3756 "%% Import/Export RT is not configured for this VRF\n");
3761 ecomdel
= ecommunity_str2com(argv
[3]->arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
3763 vty_out(vty
, "%% Malformed Route Target list\n");
3766 ecommunity_str(ecomdel
);
3768 if (rt_type
== RT_TYPE_IMPORT
) {
3769 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_import_rtl
,
3772 "%% RT specified does not match configuration for this VRF\n");
3775 bgp_evpn_unconfigure_import_rt_for_vrf(bgp
, ecomdel
);
3776 } else if (rt_type
== RT_TYPE_EXPORT
) {
3777 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_export_rtl
,
3780 "%% RT specified does not match configuration for this VRF\n");
3783 bgp_evpn_unconfigure_export_rt_for_vrf(bgp
, ecomdel
);
3784 } else if (rt_type
== RT_TYPE_BOTH
) {
3787 if (bgp_evpn_rt_matches_existing(bgp
->vrf_import_rtl
,
3789 bgp_evpn_unconfigure_import_rt_for_vrf(bgp
, ecomdel
);
3793 if (bgp_evpn_rt_matches_existing(bgp
->vrf_export_rtl
,
3795 bgp_evpn_unconfigure_export_rt_for_vrf(bgp
, ecomdel
);
3799 if (!found_ecomdel
) {
3801 "%% RT specified does not match configuration for this VRF\n");
3809 DEFUN (bgp_evpn_vni_rt
,
3810 bgp_evpn_vni_rt_cmd
,
3811 "route-target <both|import|export> RT",
3813 "import and export\n"
3816 "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
3818 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3819 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3821 struct ecommunity
*ecomadd
= NULL
;
3826 if (!strcmp(argv
[1]->text
, "import"))
3827 rt_type
= RT_TYPE_IMPORT
;
3828 else if (!strcmp(argv
[1]->text
, "export"))
3829 rt_type
= RT_TYPE_EXPORT
;
3830 else if (!strcmp(argv
[1]->text
, "both"))
3831 rt_type
= RT_TYPE_BOTH
;
3833 vty_out(vty
, "%% Invalid Route Target type\n");
3837 /* Add/update the import route-target */
3838 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_IMPORT
) {
3839 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
3840 ECOMMUNITY_ROUTE_TARGET
, 0);
3842 vty_out(vty
, "%% Malformed Route Target list\n");
3845 ecommunity_str(ecomadd
);
3847 /* Do nothing if we already have this import route-target */
3848 if (!bgp_evpn_rt_matches_existing(vpn
->import_rtl
, ecomadd
))
3849 evpn_configure_import_rt(bgp
, vpn
, ecomadd
);
3852 /* Add/update the export route-target */
3853 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_EXPORT
) {
3854 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
3855 ECOMMUNITY_ROUTE_TARGET
, 0);
3857 vty_out(vty
, "%% Malformed Route Target list\n");
3860 ecommunity_str(ecomadd
);
3862 /* Do nothing if we already have this export route-target */
3863 if (!bgp_evpn_rt_matches_existing(vpn
->export_rtl
, ecomadd
))
3864 evpn_configure_export_rt(bgp
, vpn
, ecomadd
);
3870 DEFUN (no_bgp_evpn_vni_rt
,
3871 no_bgp_evpn_vni_rt_cmd
,
3872 "no route-target <both|import|export> RT",
3875 "import and export\n"
3878 "ASN:XX or A.B.C.D:XX\n")
3880 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3881 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3882 int rt_type
, found_ecomdel
;
3883 struct ecommunity
*ecomdel
= NULL
;
3888 if (!strcmp(argv
[2]->text
, "import"))
3889 rt_type
= RT_TYPE_IMPORT
;
3890 else if (!strcmp(argv
[2]->text
, "export"))
3891 rt_type
= RT_TYPE_EXPORT
;
3892 else if (!strcmp(argv
[2]->text
, "both"))
3893 rt_type
= RT_TYPE_BOTH
;
3895 vty_out(vty
, "%% Invalid Route Target type\n");
3899 /* The user did "no route-target import", check to see if there are any
3900 * import route-targets configured. */
3901 if (rt_type
== RT_TYPE_IMPORT
) {
3902 if (!is_import_rt_configured(vpn
)) {
3904 "%% Import RT is not configured for this VNI\n");
3907 } else if (rt_type
== RT_TYPE_EXPORT
) {
3908 if (!is_export_rt_configured(vpn
)) {
3910 "%% Export RT is not configured for this VNI\n");
3913 } else if (rt_type
== RT_TYPE_BOTH
) {
3914 if (!is_import_rt_configured(vpn
)
3915 && !is_export_rt_configured(vpn
)) {
3917 "%% Import/Export RT is not configured for this VNI\n");
3922 ecomdel
= ecommunity_str2com(argv
[3]->arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
3924 vty_out(vty
, "%% Malformed Route Target list\n");
3927 ecommunity_str(ecomdel
);
3929 if (rt_type
== RT_TYPE_IMPORT
) {
3930 if (!bgp_evpn_rt_matches_existing(vpn
->import_rtl
, ecomdel
)) {
3932 "%% RT specified does not match configuration for this VNI\n");
3935 evpn_unconfigure_import_rt(bgp
, vpn
, ecomdel
);
3936 } else if (rt_type
== RT_TYPE_EXPORT
) {
3937 if (!bgp_evpn_rt_matches_existing(vpn
->export_rtl
, ecomdel
)) {
3939 "%% RT specified does not match configuration for this VNI\n");
3942 evpn_unconfigure_export_rt(bgp
, vpn
, ecomdel
);
3943 } else if (rt_type
== RT_TYPE_BOTH
) {
3946 if (bgp_evpn_rt_matches_existing(vpn
->import_rtl
, ecomdel
)) {
3947 evpn_unconfigure_import_rt(bgp
, vpn
, ecomdel
);
3951 if (bgp_evpn_rt_matches_existing(vpn
->export_rtl
, ecomdel
)) {
3952 evpn_unconfigure_export_rt(bgp
, vpn
, ecomdel
);
3956 if (!found_ecomdel
) {
3958 "%% RT specified does not match configuration for this VNI\n");
3966 DEFUN (no_bgp_evpn_vni_rt_without_val
,
3967 no_bgp_evpn_vni_rt_without_val_cmd
,
3968 "no route-target <import|export>",
3974 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3975 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3981 if (!strcmp(argv
[2]->text
, "import")) {
3982 rt_type
= RT_TYPE_IMPORT
;
3983 } else if (!strcmp(argv
[2]->text
, "export")) {
3984 rt_type
= RT_TYPE_EXPORT
;
3986 vty_out(vty
, "%% Invalid Route Target type\n");
3990 /* Check if we should disallow. */
3991 if (rt_type
== RT_TYPE_IMPORT
) {
3992 if (!is_import_rt_configured(vpn
)) {
3994 "%% Import RT is not configured for this VNI\n");
3998 if (!is_export_rt_configured(vpn
)) {
4000 "%% Export RT is not configured for this VNI\n");
4005 /* Unconfigure the RT. */
4006 if (rt_type
== RT_TYPE_IMPORT
)
4007 evpn_unconfigure_import_rt(bgp
, vpn
, NULL
);
4009 evpn_unconfigure_export_rt(bgp
, vpn
, NULL
);
4014 * Output EVPN configuration information.
4016 void bgp_config_write_evpn_info(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
4020 hash_iterate(bgp
->vnihash
,
4021 (void (*)(struct hash_backet
*,
4022 void *))write_vni_config_for_entry
,
4025 if (bgp
->advertise_all_vni
)
4026 vty_out(vty
, " advertise-all-vni\n");
4028 if (bgp
->advertise_gw_macip
)
4029 vty_out(vty
, " advertise-default-gw\n");
4032 void bgp_ethernetvpn_init(void)
4034 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_cmd
);
4035 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_rd_cmd
);
4036 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_tags_cmd
);
4037 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd
);
4038 install_element(VIEW_NODE
,
4039 &show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd
);
4040 install_element(VIEW_NODE
,
4041 &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd
);
4044 &show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd
);
4047 &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd
);
4048 install_element(VIEW_NODE
, &show_ip_bgp_evpn_rd_overlay_cmd
);
4049 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_overlay_cmd
);
4050 install_element(BGP_EVPN_NODE
, &no_evpnrt5_network_cmd
);
4051 install_element(BGP_EVPN_NODE
, &evpnrt5_network_cmd
);
4052 #if defined(HAVE_CUMULUS)
4053 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_all_vni_cmd
);
4054 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_all_vni_cmd
);
4055 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_default_gw_cmd
);
4056 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_default_gw_cmd
);
4057 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_type5_cmd
);
4058 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_type5_cmd
);
4060 /* "show bgp l2vpn evpn" commands. */
4061 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_vni_cmd
);
4062 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_summary_cmd
);
4063 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_cmd
);
4064 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_rd_cmd
);
4065 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_rd_macip_cmd
);
4066 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vni_cmd
);
4067 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vrf_cmd
);
4068 install_element(VIEW_NODE
,
4069 &show_bgp_l2vpn_evpn_route_vni_multicast_cmd
);
4070 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vni_macip_cmd
);
4071 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vni_all_cmd
);
4072 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_import_rt_cmd
);
4073 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_vrf_import_rt_cmd
);
4075 /* "show bgp evpn" commands. */
4076 install_element(VIEW_NODE
, &show_bgp_evpn_vni_cmd
);
4077 install_element(VIEW_NODE
, &show_bgp_evpn_summary_cmd
);
4078 install_element(VIEW_NODE
, &show_bgp_evpn_route_cmd
);
4079 install_element(VIEW_NODE
, &show_bgp_evpn_route_rd_cmd
);
4080 install_element(VIEW_NODE
, &show_bgp_evpn_route_rd_macip_cmd
);
4081 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_cmd
);
4082 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_multicast_cmd
);
4083 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_macip_cmd
);
4084 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_all_cmd
);
4085 install_element(VIEW_NODE
, &show_bgp_evpn_import_rt_cmd
);
4086 install_element(VIEW_NODE
, &show_bgp_vrf_l3vni_info_cmd
);
4088 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
4089 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_vni_cmd
);
4090 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
4091 install_element(BGP_EVPN_VNI_NODE
, &bgp_evpn_vni_rd_cmd
);
4092 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rd_cmd
);
4093 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rd_without_val_cmd
);
4094 install_element(BGP_EVPN_VNI_NODE
, &bgp_evpn_vni_rt_cmd
);
4095 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rt_cmd
);
4096 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rt_without_val_cmd
);
4097 install_element(BGP_NODE
, &bgp_evpn_vrf_rd_cmd
);
4098 install_element(BGP_NODE
, &no_bgp_evpn_vrf_rd_cmd
);
4099 install_element(BGP_NODE
, &no_bgp_evpn_vrf_rd_without_val_cmd
);
4100 install_element(BGP_EVPN_NODE
, &bgp_evpn_vrf_rt_cmd
);
4101 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_vrf_rt_cmd
);
4102 install_element(BGP_EVPN_VNI_NODE
,
4103 &bgp_evpn_advertise_default_gw_vni_cmd
);
4104 install_element(BGP_EVPN_VNI_NODE
,
4105 &no_bgp_evpn_advertise_default_gw_vni_cmd
);