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
25 #include "lib/printfrr.h"
26 #include "lib/vxlan.h"
29 #include "bgpd/bgpd.h"
30 #include "bgpd/bgp_table.h"
31 #include "bgpd/bgp_attr.h"
32 #include "bgpd/bgp_route.h"
33 #include "bgpd/bgp_mplsvpn.h"
34 #include "bgpd/bgp_vpn.h"
35 #include "bgpd/bgp_evpn_vty.h"
36 #include "bgpd/bgp_evpn.h"
37 #include "bgpd/bgp_evpn_private.h"
38 #include "bgpd/bgp_evpn_mh.h"
39 #include "bgpd/bgp_zebra.h"
40 #include "bgpd/bgp_vty.h"
41 #include "bgpd/bgp_errors.h"
42 #include "bgpd/bgp_ecommunity.h"
43 #include "bgpd/bgp_lcommunity.h"
44 #include "bgpd/bgp_community.h"
46 #define SHOW_DISPLAY_STANDARD 0
47 #define SHOW_DISPLAY_TAGS 1
48 #define SHOW_DISPLAY_OVERLAY 2
49 #define VNI_STR_LEN 32
52 * Context for VNI hash walk - used by callbacks.
57 struct in_addr vtep_ip
;
62 static void display_vrf_import_rt(struct vty
*vty
, struct vrf_irt_node
*irt
,
66 uint8_t type
, sub_type
;
67 struct ecommunity_as eas
;
68 struct ecommunity_ip eip
;
69 struct listnode
*node
, *nnode
;
70 struct bgp
*tmp_bgp_vrf
= NULL
;
71 json_object
*json_rt
= NULL
;
72 json_object
*json_vrfs
= NULL
;
73 char rt_buf
[RT_ADDRSTRLEN
];
76 json_rt
= json_object_new_object();
77 json_vrfs
= json_object_new_array();
80 pnt
= (uint8_t *)&irt
->rt
.val
;
83 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
86 memset(&eas
, 0, sizeof(eas
));
88 case ECOMMUNITY_ENCODE_AS
:
89 eas
.as
= (*pnt
++ << 8);
91 ptr_get_be32(pnt
, &eas
.val
);
93 snprintf(rt_buf
, sizeof(rt_buf
), "%u:%u", eas
.as
, eas
.val
);
96 json_object_string_add(json_rt
, "rt", rt_buf
);
98 vty_out(vty
, "Route-target: %s", rt_buf
);
102 case ECOMMUNITY_ENCODE_IP
:
103 memcpy(&eip
.ip
, pnt
, 4);
105 eip
.val
= (*pnt
++ << 8);
108 snprintfrr(rt_buf
, sizeof(rt_buf
), "%pI4:%u", &eip
.ip
, eip
.val
);
111 json_object_string_add(json_rt
, "rt", rt_buf
);
113 vty_out(vty
, "Route-target: %s", rt_buf
);
117 case ECOMMUNITY_ENCODE_AS4
:
118 pnt
= ptr_get_be32(pnt
, &eas
.val
);
119 eas
.val
= (*pnt
++ << 8);
122 snprintf(rt_buf
, sizeof(rt_buf
), "%u:%u", eas
.as
, eas
.val
);
125 json_object_string_add(json_rt
, "rt", rt_buf
);
127 vty_out(vty
, "Route-target: %s", rt_buf
);
137 "\nList of VRFs importing routes with this route-target:\n");
140 for (ALL_LIST_ELEMENTS(irt
->vrfs
, node
, nnode
, tmp_bgp_vrf
)) {
142 json_object_array_add(
144 json_object_new_string(
145 vrf_id_to_name(tmp_bgp_vrf
->vrf_id
)));
147 vty_out(vty
, " %s\n",
148 vrf_id_to_name(tmp_bgp_vrf
->vrf_id
));
152 json_object_object_add(json_rt
, "vrfs", json_vrfs
);
153 json_object_object_add(json
, rt_buf
, json_rt
);
157 static void show_vrf_import_rt_entry(struct hash_bucket
*bucket
, void *args
[])
159 json_object
*json
= NULL
;
160 struct vty
*vty
= NULL
;
161 struct vrf_irt_node
*irt
= (struct vrf_irt_node
*)bucket
->data
;
163 vty
= (struct vty
*)args
[0];
164 json
= (struct json_object
*)args
[1];
166 display_vrf_import_rt(vty
, irt
, json
);
169 static void display_import_rt(struct vty
*vty
, struct irt_node
*irt
,
173 uint8_t type
, sub_type
;
174 struct ecommunity_as eas
;
175 struct ecommunity_ip eip
;
176 struct listnode
*node
, *nnode
;
177 struct bgpevpn
*tmp_vpn
;
178 json_object
*json_rt
= NULL
;
179 json_object
*json_vnis
= NULL
;
180 char rt_buf
[RT_ADDRSTRLEN
];
183 json_rt
= json_object_new_object();
184 json_vnis
= json_object_new_array();
187 /* TODO: This needs to go into a function */
189 pnt
= (uint8_t *)&irt
->rt
.val
;
192 if (sub_type
!= ECOMMUNITY_ROUTE_TARGET
)
195 memset(&eas
, 0, sizeof(eas
));
197 case ECOMMUNITY_ENCODE_AS
:
198 eas
.as
= (*pnt
++ << 8);
200 ptr_get_be32(pnt
, &eas
.val
);
202 snprintf(rt_buf
, sizeof(rt_buf
), "%u:%u", eas
.as
, eas
.val
);
205 json_object_string_add(json_rt
, "rt", rt_buf
);
207 vty_out(vty
, "Route-target: %s", rt_buf
);
211 case ECOMMUNITY_ENCODE_IP
:
212 memcpy(&eip
.ip
, pnt
, 4);
214 eip
.val
= (*pnt
++ << 8);
217 snprintfrr(rt_buf
, sizeof(rt_buf
), "%pI4:%u", &eip
.ip
, eip
.val
);
220 json_object_string_add(json_rt
, "rt", rt_buf
);
222 vty_out(vty
, "Route-target: %s", rt_buf
);
226 case ECOMMUNITY_ENCODE_AS4
:
227 pnt
= ptr_get_be32(pnt
, &eas
.val
);
228 eas
.val
= (*pnt
++ << 8);
231 snprintf(rt_buf
, sizeof(rt_buf
), "%u:%u", eas
.as
, eas
.val
);
234 json_object_string_add(json_rt
, "rt", rt_buf
);
236 vty_out(vty
, "Route-target: %s", rt_buf
);
246 "\nList of VNIs importing routes with this route-target:\n");
249 for (ALL_LIST_ELEMENTS(irt
->vnis
, node
, nnode
, tmp_vpn
)) {
251 json_object_array_add(
252 json_vnis
, json_object_new_int(tmp_vpn
->vni
));
254 vty_out(vty
, " %u\n", tmp_vpn
->vni
);
258 json_object_object_add(json_rt
, "vnis", json_vnis
);
259 json_object_object_add(json
, rt_buf
, json_rt
);
263 static void show_import_rt_entry(struct hash_bucket
*bucket
, void *args
[])
265 json_object
*json
= NULL
;
266 struct vty
*vty
= NULL
;
267 struct irt_node
*irt
= (struct irt_node
*)bucket
->data
;
272 display_import_rt(vty
, irt
, json
);
277 static void bgp_evpn_show_route_rd_header(struct vty
*vty
,
278 struct bgp_dest
*rd_dest
,
279 json_object
*json
, char *rd_str
,
286 const struct prefix
*p
= bgp_dest_get_prefix(rd_dest
);
290 /* Decode RD type. */
291 type
= decode_rd_type(pnt
);
294 vty_out(vty
, "Route Distinguisher: ");
298 decode_rd_as(pnt
+ 2, &rd_as
);
299 snprintf(rd_str
, len
, "%u:%d", rd_as
.as
, rd_as
.val
);
301 json_object_string_add(json
, "rd", rd_str
);
303 vty_out(vty
, "%s\n", rd_str
);
307 decode_rd_as4(pnt
+ 2, &rd_as
);
308 snprintf(rd_str
, len
, "%u:%d", rd_as
.as
, rd_as
.val
);
310 json_object_string_add(json
, "rd", rd_str
);
312 vty_out(vty
, "%s\n", rd_str
);
316 decode_rd_ip(pnt
+ 2, &rd_ip
);
317 snprintfrr(rd_str
, len
, "%pI4:%d", &rd_ip
.ip
, rd_ip
.val
);
319 json_object_string_add(json
, "rd", rd_str
);
321 vty_out(vty
, "%s\n", rd_str
);
326 snprintf(rd_str
, len
, "Unknown");
327 json_object_string_add(json
, "rd", rd_str
);
329 snprintf(rd_str
, len
, "Unknown RD type");
330 vty_out(vty
, "%s\n", rd_str
);
336 static void bgp_evpn_show_route_header(struct vty
*vty
, struct bgp
*bgp
,
337 uint64_t tbl_ver
, json_object
*json
)
340 " Network Next Hop Metric LocPrf Weight Path\n";
346 "BGP table version is %" PRIu64
", local router ID is %pI4\n",
347 tbl_ver
, &bgp
->router_id
);
349 "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
350 vty_out(vty
, "Origin codes: i - IGP, e - EGP, ? - incomplete\n");
352 "EVPN type-1 prefix: [1]:[ESI]:[EthTag]:[IPlen]:[VTEP-IP]\n");
354 "EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]\n");
355 vty_out(vty
, "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
356 vty_out(vty
, "EVPN type-4 prefix: [4]:[ESI]:[IPlen]:[OrigIP]\n");
357 vty_out(vty
, "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
358 vty_out(vty
, "%s", ri_header
);
361 static void display_l3vni(struct vty
*vty
, struct bgp
*bgp_vrf
,
364 char buf1
[INET6_ADDRSTRLEN
];
366 struct listnode
*node
, *nnode
;
367 struct ecommunity
*ecom
;
368 json_object
*json_import_rtl
= NULL
;
369 json_object
*json_export_rtl
= NULL
;
370 char buf2
[ETHER_ADDR_STRLEN
];
371 char originator_ip
[BUFSIZ
] = {0};
373 json_import_rtl
= json_export_rtl
= 0;
376 json_import_rtl
= json_object_new_array();
377 json_export_rtl
= json_object_new_array();
378 json_object_int_add(json
, "vni", bgp_vrf
->l3vni
);
379 json_object_string_add(json
, "type", "L3");
380 json_object_string_add(json
, "inKernel", "True");
381 json_object_string_add(
383 prefix_rd2str(&bgp_vrf
->vrf_prd
, buf1
, RD_ADDRSTRLEN
));
384 json_object_string_add(
385 json
, "originatorIp",
386 inet_ntop(AF_INET
, &bgp_vrf
->originator_ip
,
387 originator_ip
, sizeof(originator_ip
)));
388 json_object_string_add(json
, "advertiseGatewayMacip", "n/a");
389 json_object_string_add(json
, "advertiseSviMacIp", "n/a");
390 json_object_to_json_string_ext(json
,
391 JSON_C_TO_STRING_NOSLASHESCAPE
);
392 json_object_string_add(json
, "advertisePip",
393 bgp_vrf
->evpn_info
->advertise_pip
?
394 "Enabled" : "Disabled");
395 json_object_string_add(json
, "sysIP",
397 &bgp_vrf
->evpn_info
->pip_ip
,
398 buf1
, INET_ADDRSTRLEN
));
399 json_object_string_add(json
, "sysMac",
400 prefix_mac2str(&bgp_vrf
->evpn_info
->pip_rmac
,
401 buf2
, sizeof(buf2
)));
402 json_object_string_add(json
, "rmac",
403 prefix_mac2str(&bgp_vrf
->rmac
,
404 buf2
, sizeof(buf2
)));
406 vty_out(vty
, "VNI: %d", bgp_vrf
->l3vni
);
407 vty_out(vty
, " (known to the kernel)");
410 vty_out(vty
, " Type: %s\n", "L3");
411 vty_out(vty
, " Tenant VRF: %s\n",
412 vrf_id_to_name(bgp_vrf
->vrf_id
));
413 vty_out(vty
, " RD: %s\n",
414 prefix_rd2str(&bgp_vrf
->vrf_prd
, buf1
, RD_ADDRSTRLEN
));
415 vty_out(vty
, " Originator IP: %pI4\n",
416 &bgp_vrf
->originator_ip
);
417 vty_out(vty
, " Advertise-gw-macip : %s\n", "n/a");
418 vty_out(vty
, " Advertise-svi-macip : %s\n", "n/a");
419 vty_out(vty
, " Advertise-pip: %s\n",
420 bgp_vrf
->evpn_info
->advertise_pip
? "Yes" : "No");
421 vty_out(vty
, " System-IP: %s\n",
422 inet_ntop(AF_INET
, &bgp_vrf
->evpn_info
->pip_ip
,
423 buf1
, INET_ADDRSTRLEN
));
424 vty_out(vty
, " System-MAC: %s\n",
425 prefix_mac2str(&bgp_vrf
->evpn_info
->pip_rmac
,
426 buf2
, sizeof(buf2
)));
427 vty_out(vty
, " Router-MAC: %s\n",
428 prefix_mac2str(&bgp_vrf
->rmac
,
429 buf2
, sizeof(buf2
)));
433 vty_out(vty
, " Import Route Target:\n");
435 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_import_rtl
, node
, nnode
, ecom
)) {
436 ecom_str
= ecommunity_ecom2str(ecom
,
437 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
440 json_object_array_add(json_import_rtl
,
441 json_object_new_string(ecom_str
));
443 vty_out(vty
, " %s\n", ecom_str
);
445 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
449 json_object_object_add(json
, "importRts", json_import_rtl
);
451 vty_out(vty
, " Export Route Target:\n");
453 for (ALL_LIST_ELEMENTS(bgp_vrf
->vrf_export_rtl
, node
, nnode
, ecom
)) {
454 ecom_str
= ecommunity_ecom2str(ecom
,
455 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
458 json_object_array_add(json_export_rtl
,
459 json_object_new_string(ecom_str
));
461 vty_out(vty
, " %s\n", ecom_str
);
463 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
467 json_object_object_add(json
, "exportRts", json_export_rtl
);
470 static void display_vni(struct vty
*vty
, struct bgpevpn
*vpn
, json_object
*json
)
472 char buf1
[RD_ADDRSTRLEN
];
474 struct listnode
*node
, *nnode
;
475 struct ecommunity
*ecom
;
476 json_object
*json_import_rtl
= NULL
;
477 json_object
*json_export_rtl
= NULL
;
478 struct bgp
*bgp_evpn
;
479 char buf
[BUFSIZ
] = {0};
481 bgp_evpn
= bgp_get_evpn();
484 json_import_rtl
= json_object_new_array();
485 json_export_rtl
= json_object_new_array();
486 json_object_int_add(json
, "vni", vpn
->vni
);
487 json_object_string_add(json
, "type", "L2");
488 json_object_string_add(json
, "inKernel",
489 is_vni_live(vpn
) ? "True" : "False");
490 json_object_string_add(
492 prefix_rd2str(&vpn
->prd
, buf1
, sizeof(buf1
)));
493 json_object_string_add(json
, "originatorIp",
494 inet_ntop(AF_INET
, &vpn
->originator_ip
,
496 json_object_string_add(
498 inet_ntop(AF_INET
, &vpn
->mcast_grp
, buf
, sizeof(buf
)));
499 /* per vni knob is enabled -- Enabled
500 * Global knob is enabled -- Active
501 * default -- Disabled
503 if (!vpn
->advertise_gw_macip
&&
504 bgp_evpn
&& bgp_evpn
->advertise_gw_macip
)
505 json_object_string_add(json
, "advertiseGatewayMacip",
507 else if (vpn
->advertise_gw_macip
)
508 json_object_string_add(json
, "advertiseGatewayMacip",
511 json_object_string_add(json
, "advertiseGatewayMacip",
513 if (!vpn
->advertise_svi_macip
&& bgp_evpn
&&
514 bgp_evpn
->evpn_info
->advertise_svi_macip
)
515 json_object_string_add(json
, "advertiseSviMacIp",
517 else if (vpn
->advertise_svi_macip
)
518 json_object_string_add(json
, "advertiseSviMacIp",
521 json_object_string_add(json
, "advertiseSviMacIp",
524 vty_out(vty
, "VNI: %d", vpn
->vni
);
525 if (is_vni_live(vpn
))
526 vty_out(vty
, " (known to the kernel)");
529 vty_out(vty
, " Type: %s\n", "L2");
530 vty_out(vty
, " Tenant-Vrf: %s\n",
531 vrf_id_to_name(vpn
->tenant_vrf_id
));
532 vty_out(vty
, " RD: %s\n",
533 prefix_rd2str(&vpn
->prd
, buf1
, sizeof(buf1
)));
534 vty_out(vty
, " Originator IP: %pI4\n", &vpn
->originator_ip
);
535 vty_out(vty
, " Mcast group: %pI4\n", &vpn
->mcast_grp
);
536 if (!vpn
->advertise_gw_macip
&&
537 bgp_evpn
&& bgp_evpn
->advertise_gw_macip
)
538 vty_out(vty
, " Advertise-gw-macip : %s\n",
540 else if (vpn
->advertise_gw_macip
)
541 vty_out(vty
, " Advertise-gw-macip : %s\n",
544 vty_out(vty
, " Advertise-gw-macip : %s\n",
546 if (!vpn
->advertise_svi_macip
&& bgp_evpn
&&
547 bgp_evpn
->evpn_info
->advertise_svi_macip
)
548 vty_out(vty
, " Advertise-svi-macip : %s\n",
550 else if (vpn
->advertise_svi_macip
)
551 vty_out(vty
, " Advertise-svi-macip : %s\n",
554 vty_out(vty
, " Advertise-svi-macip : %s\n",
559 vty_out(vty
, " Import Route Target:\n");
561 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
562 ecom_str
= ecommunity_ecom2str(ecom
,
563 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
566 json_object_array_add(json_import_rtl
,
567 json_object_new_string(ecom_str
));
569 vty_out(vty
, " %s\n", ecom_str
);
571 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
575 json_object_object_add(json
, "importRts", json_import_rtl
);
577 vty_out(vty
, " Export Route Target:\n");
579 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
580 ecom_str
= ecommunity_ecom2str(ecom
,
581 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
584 json_object_array_add(json_export_rtl
,
585 json_object_new_string(ecom_str
));
587 vty_out(vty
, " %s\n", ecom_str
);
589 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
593 json_object_object_add(json
, "exportRts", json_export_rtl
);
596 static void show_esi_routes(struct bgp
*bgp
,
597 struct bgp_evpn_es
*es
,
602 struct bgp_dest
*dest
;
603 struct bgp_path_info
*pi
;
604 uint32_t prefix_cnt
, path_cnt
;
607 prefix_cnt
= path_cnt
= 0;
609 tbl_ver
= es
->route_table
->version
;
610 for (dest
= bgp_table_top(es
->route_table
); dest
;
611 dest
= bgp_route_next(dest
)) {
612 int add_prefix_to_json
= 0;
613 char prefix_str
[BUFSIZ
];
614 json_object
*json_paths
= NULL
;
615 json_object
*json_prefix
= NULL
;
616 const struct prefix
*p
= bgp_dest_get_prefix(dest
);
618 prefix2str((struct prefix_evpn
*)p
, prefix_str
,
622 json_prefix
= json_object_new_object();
624 pi
= bgp_dest_get_bgp_path_info(dest
);
626 /* Overall header/legend displayed once. */
628 bgp_evpn_show_route_header(vty
, bgp
,
637 json_paths
= json_object_new_array();
639 /* For EVPN, the prefix is displayed for each path (to fit in
640 * with code that already exists).
642 for (; pi
; pi
= pi
->next
) {
643 json_object
*json_path
= NULL
;
646 json_path
= json_object_new_array();
648 route_vty_out(vty
, p
, pi
, 0, SAFI_EVPN
, json_path
,
652 json_object_array_add(json_paths
, json_path
);
655 add_prefix_to_json
= 1;
659 if (add_prefix_to_json
) {
660 json_object_string_add(json_prefix
, "prefix",
662 json_object_int_add(json_prefix
, "prefixLen",
664 json_object_object_add(json_prefix
, "paths",
666 json_object_object_add(json
, prefix_str
,
669 json_object_free(json_paths
);
670 json_object_free(json_prefix
);
678 json_object_int_add(json
, "numPrefix", prefix_cnt
);
679 json_object_int_add(json
, "numPaths", path_cnt
);
682 vty_out(vty
, "No EVPN prefixes exist for this ESI\n");
684 vty_out(vty
, "\nDisplayed %u prefixes (%u paths)\n",
685 prefix_cnt
, path_cnt
);
689 /* Display all MAC-IP VNI routes linked to an ES */
690 static void bgp_evpn_show_routes_mac_ip_es(struct vty
*vty
, esi_t
*esi
,
691 json_object
*json
, int detail
,
695 struct bgp_path_info
*pi
;
696 int header
= detail
? 0 : 1;
698 struct listnode
*node
;
699 struct bgp_evpn_es
*es
;
700 struct bgp_path_es_info
*es_info
;
701 struct bgp
*bgp
= bgp_get_evpn();
702 json_object
*json_paths
= NULL
;
710 json_paths
= json_object_new_array();
712 RB_FOREACH (es
, bgp_es_rb_head
, &bgp_mh_info
->es_rb_tree
) {
713 struct list
*es_list
;
715 if (esi
&& memcmp(esi
, &es
->esi
, sizeof(*esi
)))
719 es_list
= es
->macip_global_path_list
;
721 es_list
= es
->macip_evi_path_list
;
723 for (ALL_LIST_ELEMENTS_RO(es_list
, node
, es_info
)) {
724 json_object
*json_path
= NULL
;
729 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
732 /* Overall header/legend displayed once. */
734 bgp_evpn_show_route_header(vty
, bgp
, 0, json
);
741 json_path
= json_object_new_array();
744 route_vty_out_detail(
745 vty
, bgp
, rn
, pi
, AFI_L2VPN
, SAFI_EVPN
,
746 RPKI_NOT_BEING_USED
, json_path
);
748 route_vty_out(vty
, &rn
->p
, pi
, 0, SAFI_EVPN
,
752 json_object_array_add(json_paths
, json_path
);
757 json_object_object_add(json
, "paths", json_paths
);
758 json_object_int_add(json
, "numPaths", path_cnt
);
761 vty_out(vty
, "There are no MAC-IP ES paths");
763 vty_out(vty
, "\nDisplayed %u paths\n", path_cnt
);
768 static void bgp_evpn_show_routes_mac_ip_evi_es(struct vty
*vty
, esi_t
*esi
,
769 json_object
*json
, int detail
)
771 return bgp_evpn_show_routes_mac_ip_es(vty
, esi
, json
, detail
, false);
774 static void bgp_evpn_show_routes_mac_ip_global_es(struct vty
*vty
, esi_t
*esi
,
775 json_object
*json
, int detail
)
777 return bgp_evpn_show_routes_mac_ip_es(vty
, esi
, json
, detail
, true);
780 static void show_vni_routes(struct bgp
*bgp
, struct bgpevpn
*vpn
, int type
,
781 struct vty
*vty
, struct in_addr vtep_ip
,
782 json_object
*json
, int detail
)
784 struct bgp_dest
*dest
;
785 struct bgp_path_info
*pi
;
786 struct bgp_table
*table
;
787 int header
= detail
? 0 : 1;
789 uint32_t prefix_cnt
, path_cnt
;
791 prefix_cnt
= path_cnt
= 0;
793 table
= vpn
->route_table
;
794 tbl_ver
= table
->version
;
795 for (dest
= bgp_table_top(table
); dest
; dest
= bgp_route_next(dest
)) {
796 const struct prefix_evpn
*evp
=
797 (const struct prefix_evpn
*)bgp_dest_get_prefix(dest
);
798 int add_prefix_to_json
= 0;
799 char prefix_str
[BUFSIZ
];
800 json_object
*json_paths
= NULL
;
801 json_object
*json_prefix
= NULL
;
802 const struct prefix
*p
= bgp_dest_get_prefix(dest
);
804 prefix2str((struct prefix_evpn
*)bgp_dest_get_prefix(dest
),
805 prefix_str
, sizeof(prefix_str
));
807 if (type
&& evp
->prefix
.route_type
!= type
)
811 json_prefix
= json_object_new_object();
813 pi
= bgp_dest_get_bgp_path_info(dest
);
815 /* Overall header/legend displayed once. */
817 bgp_evpn_show_route_header(vty
, bgp
,
826 json_paths
= json_object_new_array();
828 /* For EVPN, the prefix is displayed for each path (to fit in
829 * with code that already exists).
831 for (; pi
; pi
= pi
->next
) {
832 json_object
*json_path
= NULL
;
834 if (vtep_ip
.s_addr
!= INADDR_ANY
835 && !IPV4_ADDR_SAME(&(vtep_ip
),
836 &(pi
->attr
->nexthop
)))
840 json_path
= json_object_new_array();
843 route_vty_out_detail(vty
, bgp
, dest
, pi
,
844 AFI_L2VPN
, SAFI_EVPN
,
848 route_vty_out(vty
, p
, pi
, 0, SAFI_EVPN
,
852 json_object_array_add(json_paths
, json_path
);
855 add_prefix_to_json
= 1;
859 if (add_prefix_to_json
) {
860 json_object_string_add(json_prefix
, "prefix",
862 json_object_int_add(json_prefix
, "prefixLen",
864 json_object_object_add(json_prefix
, "paths",
866 json_object_object_add(json
, prefix_str
,
869 json_object_free(json_paths
);
870 json_object_free(json_prefix
);
878 json_object_int_add(json
, "numPrefix", prefix_cnt
);
879 json_object_int_add(json
, "numPaths", path_cnt
);
882 vty_out(vty
, "No EVPN prefixes %sexist for this VNI",
883 type
? "(of requested type) " : "");
885 vty_out(vty
, "\nDisplayed %u prefixes (%u paths)%s\n",
886 prefix_cnt
, path_cnt
,
887 type
? " (of requested type)" : "");
892 static void show_vni_routes_hash(struct hash_bucket
*bucket
, void *arg
)
894 struct bgpevpn
*vpn
= (struct bgpevpn
*)bucket
->data
;
895 struct vni_walk_ctx
*wctx
= arg
;
896 struct vty
*vty
= wctx
->vty
;
897 json_object
*json
= wctx
->json
;
898 json_object
*json_vni
= NULL
;
899 char vni_str
[VNI_STR_LEN
];
901 snprintf(vni_str
, sizeof(vni_str
), "%d", vpn
->vni
);
903 json_vni
= json_object_new_object();
904 json_object_int_add(json_vni
, "vni", vpn
->vni
);
906 vty_out(vty
, "\nVNI: %d\n\n", vpn
->vni
);
909 show_vni_routes(wctx
->bgp
, vpn
, 0, wctx
->vty
, wctx
->vtep_ip
, json_vni
,
913 json_object_object_add(json
, vni_str
, json_vni
);
916 static void show_l3vni_entry(struct vty
*vty
, struct bgp
*bgp
,
919 json_object
*json_vni
= NULL
;
920 json_object
*json_import_rtl
= NULL
;
921 json_object
*json_export_rtl
= NULL
;
923 char buf2
[INET6_ADDRSTRLEN
];
924 char buf3
[BUFSIZ
] = {0};
927 struct listnode
*node
, *nnode
;
928 struct ecommunity
*ecom
;
934 json_vni
= json_object_new_object();
935 json_import_rtl
= json_object_new_array();
936 json_export_rtl
= json_object_new_array();
939 /* if an l3vni is present in bgp it is live */
941 snprintf(buf1
, sizeof(buf1
), "*");
944 json_object_int_add(json_vni
, "vni", bgp
->l3vni
);
945 json_object_string_add(json_vni
, "type", "L3");
946 json_object_string_add(json_vni
, "inKernel", "True");
947 json_object_string_add(json_vni
, "originatorIp",
948 inet_ntop(AF_INET
, &bgp
->originator_ip
,
949 buf3
, sizeof(buf3
)));
950 json_object_string_add(
952 prefix_rd2str(&bgp
->vrf_prd
, buf2
, RD_ADDRSTRLEN
));
953 json_object_string_add(json_vni
, "advertiseGatewayMacip",
955 json_object_string_add(json_vni
, "advertiseSviMacIp", "n/a");
956 json_object_to_json_string_ext(json_vni
,
957 JSON_C_TO_STRING_NOSLASHESCAPE
);
958 json_object_string_add(
959 json_vni
, "advertisePip",
960 bgp
->evpn_info
->advertise_pip
? "Enabled" : "Disabled");
961 json_object_string_add(json_vni
, "sysIP",
963 &bgp
->evpn_info
->pip_ip
, buf3
,
965 json_object_string_add(json_vni
, "sysMAC",
966 prefix_mac2str(&bgp
->evpn_info
->pip_rmac
,
967 buf2
, sizeof(buf2
)));
968 json_object_string_add(
970 prefix_mac2str(&bgp
->rmac
, buf2
, sizeof(buf2
)));
972 vty_out(vty
, "%-1s %-10u %-4s %-21s", buf1
, bgp
->l3vni
, "L3",
973 prefix_rd2str(&bgp
->vrf_prd
, buf2
, RD_ADDRSTRLEN
));
976 for (ALL_LIST_ELEMENTS(bgp
->vrf_import_rtl
, node
, nnode
, ecom
)) {
977 ecom_str
= ecommunity_ecom2str(ecom
,
978 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
981 json_object_array_add(json_import_rtl
,
982 json_object_new_string(ecom_str
));
984 if (listcount(bgp
->vrf_import_rtl
) > 1)
985 snprintf(rt_buf
, sizeof(rt_buf
), "%s, ...",
988 snprintf(rt_buf
, sizeof(rt_buf
), "%s",
990 vty_out(vty
, " %-25s", rt_buf
);
993 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
995 /* If there are multiple import RTs we break here and show only
1002 json_object_object_add(json_vni
, "importRTs", json_import_rtl
);
1004 for (ALL_LIST_ELEMENTS(bgp
->vrf_export_rtl
, node
, nnode
, ecom
)) {
1005 ecom_str
= ecommunity_ecom2str(ecom
,
1006 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1009 json_object_array_add(json_export_rtl
,
1010 json_object_new_string(ecom_str
));
1012 if (listcount(bgp
->vrf_export_rtl
) > 1)
1013 snprintf(rt_buf
, sizeof(rt_buf
), "%s, ...",
1016 snprintf(rt_buf
, sizeof(rt_buf
), "%s",
1018 vty_out(vty
, " %-25s", rt_buf
);
1021 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
1023 /* If there are multiple export RTs we break here and show only
1030 vty_out(vty
, "%-37s", vrf_id_to_name(bgp
->vrf_id
));
1033 char vni_str
[VNI_STR_LEN
];
1035 json_object_object_add(json_vni
, "exportRTs", json_export_rtl
);
1036 snprintf(vni_str
, sizeof(vni_str
), "%u", bgp
->l3vni
);
1037 json_object_object_add(json
, vni_str
, json_vni
);
1043 static void show_vni_entry(struct hash_bucket
*bucket
, void *args
[])
1047 json_object
*json_vni
= NULL
;
1048 json_object
*json_import_rtl
= NULL
;
1049 json_object
*json_export_rtl
= NULL
;
1050 struct bgpevpn
*vpn
= (struct bgpevpn
*)bucket
->data
;
1052 char buf2
[RD_ADDRSTRLEN
];
1053 char buf3
[BUFSIZ
] = {0};
1056 struct listnode
*node
, *nnode
;
1057 struct ecommunity
*ecom
;
1058 struct bgp
*bgp_evpn
;
1063 bgp_evpn
= bgp_get_evpn();
1066 json_vni
= json_object_new_object();
1067 json_import_rtl
= json_object_new_array();
1068 json_export_rtl
= json_object_new_array();
1072 if (is_vni_live(vpn
))
1073 snprintf(buf1
, sizeof(buf1
), "*");
1076 json_object_int_add(json_vni
, "vni", vpn
->vni
);
1077 json_object_string_add(json_vni
, "type", "L2");
1078 json_object_string_add(json_vni
, "inKernel",
1079 is_vni_live(vpn
) ? "True" : "False");
1080 json_object_string_add(
1082 prefix_rd2str(&vpn
->prd
, buf2
, sizeof(buf2
)));
1083 json_object_string_add(json_vni
, "originatorIp",
1084 inet_ntop(AF_INET
, &vpn
->originator_ip
,
1085 buf3
, sizeof(buf3
)));
1086 json_object_string_add(json_vni
, "mcastGroup",
1087 inet_ntop(AF_INET
, &vpn
->mcast_grp
, buf3
,
1089 /* per vni knob is enabled -- Enabled
1090 * Global knob is enabled -- Active
1091 * default -- Disabled
1093 if (!vpn
->advertise_gw_macip
&& bgp_evpn
1094 && bgp_evpn
->advertise_gw_macip
)
1095 json_object_string_add(
1096 json_vni
, "advertiseGatewayMacip", "Active");
1097 else if (vpn
->advertise_gw_macip
)
1098 json_object_string_add(
1099 json_vni
, "advertiseGatewayMacip", "Enabled");
1101 json_object_string_add(
1102 json_vni
, "advertiseGatewayMacip", "Disabled");
1103 if (!vpn
->advertise_svi_macip
&& bgp_evpn
1104 && bgp_evpn
->evpn_info
->advertise_svi_macip
)
1105 json_object_string_add(json_vni
, "advertiseSviMacIp",
1107 else if (vpn
->advertise_svi_macip
)
1108 json_object_string_add(json_vni
, "advertiseSviMacIp",
1111 json_object_string_add(json_vni
, "advertiseSviMacIp",
1114 vty_out(vty
, "%-1s %-10u %-4s %-21s", buf1
, vpn
->vni
, "L2",
1115 prefix_rd2str(&vpn
->prd
, buf2
, RD_ADDRSTRLEN
));
1118 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
1119 ecom_str
= ecommunity_ecom2str(ecom
,
1120 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1123 json_object_array_add(json_import_rtl
,
1124 json_object_new_string(ecom_str
));
1126 if (listcount(vpn
->import_rtl
) > 1)
1127 snprintf(rt_buf
, sizeof(rt_buf
), "%s, ...",
1130 snprintf(rt_buf
, sizeof(rt_buf
), "%s",
1132 vty_out(vty
, " %-25s", rt_buf
);
1135 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
1137 /* If there are multiple import RTs we break here and show only
1144 json_object_object_add(json_vni
, "importRTs", json_import_rtl
);
1146 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
1147 ecom_str
= ecommunity_ecom2str(ecom
,
1148 ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
1151 json_object_array_add(json_export_rtl
,
1152 json_object_new_string(ecom_str
));
1154 if (listcount(vpn
->export_rtl
) > 1)
1155 snprintf(rt_buf
, sizeof(rt_buf
), "%s, ...",
1158 snprintf(rt_buf
, sizeof(rt_buf
), "%s",
1160 vty_out(vty
, " %-25s", rt_buf
);
1163 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
1165 /* If there are multiple export RTs we break here and show only
1172 vty_out(vty
, "%-37s", vrf_id_to_name(vpn
->tenant_vrf_id
));
1175 char vni_str
[VNI_STR_LEN
];
1177 json_object_object_add(json_vni
, "exportRTs", json_export_rtl
);
1178 snprintf(vni_str
, sizeof(vni_str
), "%u", vpn
->vni
);
1179 json_object_object_add(json
, vni_str
, json_vni
);
1185 static int bgp_show_ethernet_vpn(struct vty
*vty
, struct prefix_rd
*prd
,
1186 enum bgp_show_type type
, void *output_arg
,
1187 int option
, bool use_json
)
1189 afi_t afi
= AFI_L2VPN
;
1191 struct bgp_table
*table
;
1192 struct bgp_dest
*dest
;
1193 struct bgp_dest
*rm
;
1194 struct bgp_path_info
*pi
;
1197 char rd_str
[RD_ADDRSTRLEN
];
1200 char router_id
[BUFSIZ
] = {0};
1202 unsigned long output_count
= 0;
1203 unsigned long total_count
= 0;
1204 json_object
*json
= NULL
;
1205 json_object
*json_array
= NULL
;
1206 json_object
*json_prefix_info
= NULL
;
1208 memset(rd_str
, 0, RD_ADDRSTRLEN
);
1210 bgp
= bgp_get_evpn();
1213 vty_out(vty
, "No BGP process is configured\n");
1215 vty_out(vty
, "{}\n");
1220 json
= json_object_new_object();
1222 for (dest
= bgp_table_top(bgp
->rib
[afi
][SAFI_EVPN
]); dest
;
1223 dest
= bgp_route_next(dest
)) {
1225 json_object
*json_nroute
= NULL
;
1226 const struct prefix
*p
= bgp_dest_get_prefix(dest
);
1228 if (prd
&& memcmp(p
->u
.val
, prd
->val
, 8) != 0)
1231 table
= bgp_dest_get_bgp_table_info(dest
);
1236 tbl_ver
= table
->version
;
1238 for (rm
= bgp_table_top(table
); rm
; rm
= bgp_route_next(rm
)) {
1239 pi
= bgp_dest_get_bgp_path_info(rm
);
1244 for (; pi
; pi
= pi
->next
) {
1246 if (type
== bgp_show_type_neighbor
) {
1247 struct peer
*peer
= output_arg
;
1249 if (peer_cmp(peer
, pi
->peer
) != 0)
1252 if (type
== bgp_show_type_lcommunity_exact
) {
1253 struct lcommunity
*lcom
= output_arg
;
1255 if (!pi
->attr
->lcommunity
||
1257 pi
->attr
->lcommunity
, lcom
))
1260 if (type
== bgp_show_type_lcommunity
) {
1261 struct lcommunity
*lcom
= output_arg
;
1263 if (!pi
->attr
->lcommunity
||
1265 pi
->attr
->lcommunity
, lcom
))
1268 if (type
== bgp_show_type_community
) {
1269 struct community
*com
= output_arg
;
1271 if (!pi
->attr
->community
||
1273 pi
->attr
->community
, com
))
1276 if (type
== bgp_show_type_community_exact
) {
1277 struct community
*com
= output_arg
;
1279 if (!pi
->attr
->community
||
1281 pi
->attr
->community
, com
))
1286 json_object_int_add(
1287 json
, "bgpTableVersion",
1289 json_object_string_add(
1296 sizeof(router_id
)));
1297 json_object_int_add(
1300 bgp
->default_local_pref
);
1301 json_object_int_add(
1305 if (option
== SHOW_DISPLAY_TAGS
)
1310 == SHOW_DISPLAY_OVERLAY
)
1314 bgp_evpn_show_route_header(vty
, bgp
, tbl_ver
, NULL
);
1322 json_object_new_object();
1323 bgp_evpn_show_route_rd_header(
1324 vty
, dest
, json_nroute
, rd_str
,
1328 if (use_json
&& !json_array
)
1329 json_array
= json_object_new_array();
1331 if (option
== SHOW_DISPLAY_TAGS
)
1333 vty
, bgp_dest_get_prefix(rm
),
1334 pi
, no_display
, SAFI_EVPN
,
1336 else if (option
== SHOW_DISPLAY_OVERLAY
)
1337 route_vty_out_overlay(
1338 vty
, bgp_dest_get_prefix(rm
),
1339 pi
, no_display
, json_array
);
1342 bgp_dest_get_prefix(rm
),
1343 pi
, no_display
, SAFI_EVPN
,
1351 if (use_json
&& json_array
) {
1352 const struct prefix
*p
=
1353 bgp_dest_get_prefix(rm
);
1355 json_prefix_info
= json_object_new_object();
1357 json_object_string_add(
1358 json_prefix_info
, "prefix",
1359 prefix2str((struct prefix_evpn
*)p
, buf
,
1362 json_object_int_add(json_prefix_info
,
1363 "prefixLen", p
->prefixlen
);
1365 json_object_object_add(json_prefix_info
,
1366 "paths", json_array
);
1367 json_object_object_add(json_nroute
, buf
,
1373 if (use_json
&& json_nroute
)
1374 json_object_object_add(json
, rd_str
, json_nroute
);
1378 json_object_int_add(json
, "numPrefix", output_count
);
1379 json_object_int_add(json
, "totalPrefix", total_count
);
1380 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1381 json
, JSON_C_TO_STRING_PRETTY
));
1382 json_object_free(json
);
1384 if (output_count
== 0)
1385 vty_out(vty
, "No prefixes displayed, %ld exist\n",
1389 "\nDisplayed %ld out of %ld total prefixes\n",
1390 output_count
, total_count
);
1395 DEFUN(show_ip_bgp_l2vpn_evpn
,
1396 show_ip_bgp_l2vpn_evpn_cmd
,
1397 "show [ip] bgp l2vpn evpn [json]",
1398 SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR JSON_STR
)
1400 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_normal
, NULL
, 0,
1401 use_json(argc
, argv
));
1404 DEFUN(show_ip_bgp_l2vpn_evpn_rd
,
1405 show_ip_bgp_l2vpn_evpn_rd_cmd
,
1406 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
1412 "Display information for a route distinguisher\n"
1413 "VPN Route Distinguisher\n" JSON_STR
)
1415 int idx_ext_community
= 0;
1417 struct prefix_rd prd
;
1419 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1421 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1423 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1426 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_normal
, NULL
, 0,
1427 use_json(argc
, argv
));
1430 DEFUN(show_ip_bgp_l2vpn_evpn_all_tags
,
1431 show_ip_bgp_l2vpn_evpn_all_tags_cmd
,
1432 "show [ip] bgp l2vpn evpn all tags",
1438 "Display information about all EVPN NLRIs\n"
1439 "Display BGP tags for prefixes\n")
1441 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_normal
, NULL
, 1,
1445 DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags
,
1446 show_ip_bgp_l2vpn_evpn_rd_tags_cmd
,
1447 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN tags",
1453 "Display information for a route distinguisher\n"
1454 "VPN Route Distinguisher\n" "Display BGP tags for prefixes\n")
1456 int idx_ext_community
= 0;
1458 struct prefix_rd prd
;
1460 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1462 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1464 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1467 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_normal
, NULL
, 1,
1471 DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_routes
,
1472 show_ip_bgp_l2vpn_evpn_neighbor_routes_cmd
,
1473 "show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]",
1479 "Detailed information on TCP and BGP neighbor connections\n"
1480 "IPv4 Neighbor to display information about\n"
1481 "IPv6 Neighbor to display information about\n"
1482 "Neighbor on BGP configured interface\n"
1483 "Display routes learned from neighbor\n" JSON_STR
)
1487 char *peerstr
= NULL
;
1488 bool uj
= use_json(argc
, argv
);
1489 afi_t afi
= AFI_L2VPN
;
1490 safi_t safi
= SAFI_EVPN
;
1491 struct bgp
*bgp
= NULL
;
1493 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
1496 vty_out(vty
, "No index\n");
1500 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1501 argv_find(argv
, argc
, "neighbors", &idx
);
1502 peerstr
= argv
[++idx
]->arg
;
1504 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
1507 json_object
*json_no
= NULL
;
1508 json_no
= json_object_new_object();
1509 json_object_string_add(json_no
, "warning",
1510 "Malformed address");
1511 vty_out(vty
, "%s\n",
1512 json_object_to_json_string(json_no
));
1513 json_object_free(json_no
);
1515 vty_out(vty
, "Malformed address: %s\n",
1519 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1521 json_object
*json_no
= NULL
;
1522 json_no
= json_object_new_object();
1523 json_object_string_add(
1525 "No such neighbor or address family");
1526 vty_out(vty
, "%s\n",
1527 json_object_to_json_string(json_no
));
1528 json_object_free(json_no
);
1530 vty_out(vty
, "%% No such neighbor or address family\n");
1534 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_neighbor
, peer
, 0,
1538 DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes
,
1539 show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd
,
1540 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]",
1546 "Display information for a route distinguisher\n"
1547 "VPN Route Distinguisher\n"
1548 "Detailed information on TCP and BGP neighbor connections\n"
1549 "IPv4 Neighbor to display information about\n"
1550 "IPv6 Neighbor to display information about\n"
1551 "Neighbor on BGP configured interface\n"
1552 "Display routes learned from neighbor\n" JSON_STR
)
1554 int idx_ext_community
= 0;
1558 char *peerstr
= NULL
;
1559 struct prefix_rd prd
;
1560 bool uj
= use_json(argc
, argv
);
1561 afi_t afi
= AFI_L2VPN
;
1562 safi_t safi
= SAFI_EVPN
;
1563 struct bgp
*bgp
= NULL
;
1565 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
1568 vty_out(vty
, "No index\n");
1572 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1573 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1576 json_object
*json_no
= NULL
;
1577 json_no
= json_object_new_object();
1578 json_object_string_add(json_no
, "warning",
1579 "Malformed Route Distinguisher");
1580 vty_out(vty
, "%s\n",
1581 json_object_to_json_string(json_no
));
1582 json_object_free(json_no
);
1584 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1588 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1589 argv_find(argv
, argc
, "neighbors", &idx
);
1590 peerstr
= argv
[++idx
]->arg
;
1592 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
1595 json_object
*json_no
= NULL
;
1596 json_no
= json_object_new_object();
1597 json_object_string_add(json_no
, "warning",
1598 "Malformed address");
1599 vty_out(vty
, "%s\n",
1600 json_object_to_json_string(json_no
));
1601 json_object_free(json_no
);
1603 vty_out(vty
, "Malformed address: %s\n",
1607 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1609 json_object
*json_no
= NULL
;
1610 json_no
= json_object_new_object();
1611 json_object_string_add(
1613 "No such neighbor or address family");
1614 vty_out(vty
, "%s\n",
1615 json_object_to_json_string(json_no
));
1616 json_object_free(json_no
);
1618 vty_out(vty
, "%% No such neighbor or address family\n");
1622 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_neighbor
, peer
, 0,
1626 DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes
,
1627 show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes_cmd
,
1628 "show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]",
1634 "Detailed information on TCP and BGP neighbor connections\n"
1635 "IPv4 Neighbor to display information about\n"
1636 "IPv6 Neighbor to display information about\n"
1637 "Neighbor on BGP configured interface\n"
1638 "Display the routes advertised to a BGP neighbor\n" JSON_STR
)
1642 bool uj
= use_json(argc
, argv
);
1643 struct bgp
*bgp
= NULL
;
1644 afi_t afi
= AFI_L2VPN
;
1645 safi_t safi
= SAFI_EVPN
;
1646 char *peerstr
= NULL
;
1651 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
1654 vty_out(vty
, "No index\n");
1658 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1659 argv_find(argv
, argc
, "neighbors", &idx
);
1660 peerstr
= argv
[++idx
]->arg
;
1662 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
1665 json_object
*json_no
= NULL
;
1666 json_no
= json_object_new_object();
1667 json_object_string_add(json_no
, "warning",
1668 "Malformed address");
1669 vty_out(vty
, "%s\n",
1670 json_object_to_json_string(json_no
));
1671 json_object_free(json_no
);
1673 vty_out(vty
, "Malformed address: %s\n",
1677 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1679 json_object
*json_no
= NULL
;
1680 json_no
= json_object_new_object();
1681 json_object_string_add(
1683 "No such neighbor or address family");
1684 vty_out(vty
, "%s\n",
1685 json_object_to_json_string(json_no
));
1686 json_object_free(json_no
);
1688 vty_out(vty
, "%% No such neighbor or address family\n");
1692 return show_adj_route_vpn(vty
, peer
, NULL
, AFI_L2VPN
, SAFI_EVPN
, uj
);
1695 DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes
,
1696 show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd
,
1697 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]",
1703 "Display information for a route distinguisher\n"
1704 "VPN Route Distinguisher\n"
1705 "Detailed information on TCP and BGP neighbor connections\n"
1706 "IPv4 Neighbor to display information about\n"
1707 "IPv6 Neighbor to display information about\n"
1708 "Neighbor on BGP configured interface\n"
1709 "Display the routes advertised to a BGP neighbor\n" JSON_STR
)
1711 int idx_ext_community
= 0;
1715 struct prefix_rd prd
;
1716 struct bgp
*bgp
= NULL
;
1717 bool uj
= use_json(argc
, argv
);
1718 char *peerstr
= NULL
;
1719 afi_t afi
= AFI_L2VPN
;
1720 safi_t safi
= SAFI_EVPN
;
1728 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
1731 vty_out(vty
, "No index\n");
1735 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1737 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1738 argv_find(argv
, argc
, "neighbors", &idx
);
1739 peerstr
= argv
[++idx
]->arg
;
1741 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
1744 json_object
*json_no
= NULL
;
1745 json_no
= json_object_new_object();
1746 json_object_string_add(json_no
, "warning",
1747 "Malformed address");
1748 vty_out(vty
, "%s\n",
1749 json_object_to_json_string(json_no
));
1750 json_object_free(json_no
);
1752 vty_out(vty
, "Malformed address: %s\n",
1756 if (!peer
|| !peer
->afc
[AFI_L2VPN
][SAFI_EVPN
]) {
1758 json_object
*json_no
= NULL
;
1759 json_no
= json_object_new_object();
1760 json_object_string_add(
1762 "No such neighbor or address family");
1763 vty_out(vty
, "%s\n",
1764 json_object_to_json_string(json_no
));
1765 json_object_free(json_no
);
1767 vty_out(vty
, "%% No such neighbor or address family\n");
1771 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1774 json_object
*json_no
= NULL
;
1775 json_no
= json_object_new_object();
1776 json_object_string_add(json_no
, "warning",
1777 "Malformed Route Distinguisher");
1778 vty_out(vty
, "%s\n",
1779 json_object_to_json_string(json_no
));
1780 json_object_free(json_no
);
1782 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1786 return show_adj_route_vpn(vty
, peer
, &prd
, AFI_L2VPN
, SAFI_EVPN
, uj
);
1789 DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay
,
1790 show_ip_bgp_l2vpn_evpn_all_overlay_cmd
,
1791 "show [ip] bgp l2vpn evpn all overlay [json]",
1797 "Display information about all EVPN NLRIs\n"
1798 "Display BGP Overlay Information for prefixes\n"
1801 return bgp_show_ethernet_vpn(vty
, NULL
, bgp_show_type_normal
, NULL
,
1802 SHOW_DISPLAY_OVERLAY
,
1803 use_json(argc
, argv
));
1806 DEFUN(show_ip_bgp_evpn_rd_overlay
,
1807 show_ip_bgp_evpn_rd_overlay_cmd
,
1808 "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN overlay",
1814 "Display information for a route distinguisher\n"
1815 "VPN Route Distinguisher\n"
1816 "Display BGP Overlay Information for prefixes\n")
1818 int idx_ext_community
= 0;
1820 struct prefix_rd prd
;
1822 argv_find(argv
, argc
, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community
);
1824 ret
= str2prefix_rd(argv
[idx_ext_community
]->arg
, &prd
);
1826 vty_out(vty
, "%% Malformed Route Distinguisher\n");
1829 return bgp_show_ethernet_vpn(vty
, &prd
, bgp_show_type_normal
, NULL
,
1830 SHOW_DISPLAY_OVERLAY
,
1831 use_json(argc
, argv
));
1834 DEFUN(show_bgp_l2vpn_evpn_com
,
1835 show_bgp_l2vpn_evpn_com_cmd
,
1836 "show bgp l2vpn evpn \
1837 <community AA:NN|large-community AA:BB:CC> \
1838 [exact-match] [json]",
1843 "Display routes matching the community\n"
1844 "Community number where AA and NN are (0-65535)\n"
1845 "Display routes matching the large-community\n"
1846 "List of large-community numbers\n"
1847 "Exact match of the communities\n"
1852 const char *clist_number_or_name
;
1853 int show_type
= bgp_show_type_normal
;
1854 struct community
*com
;
1855 struct lcommunity
*lcom
;
1857 if (argv_find(argv
, argc
, "large-community", &idx
)) {
1858 clist_number_or_name
= argv
[++idx
]->arg
;
1859 show_type
= bgp_show_type_lcommunity
;
1861 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
1862 show_type
= bgp_show_type_lcommunity_exact
;
1864 lcom
= lcommunity_str2com(clist_number_or_name
);
1866 vty_out(vty
, "%% Large-community malformed\n");
1870 ret
= bgp_show_ethernet_vpn(vty
, NULL
, show_type
, lcom
,
1871 SHOW_DISPLAY_STANDARD
,
1872 use_json(argc
, argv
));
1874 lcommunity_free(&lcom
);
1875 } else if (argv_find(argv
, argc
, "community", &idx
)) {
1876 clist_number_or_name
= argv
[++idx
]->arg
;
1877 show_type
= bgp_show_type_community
;
1879 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
1880 show_type
= bgp_show_type_community_exact
;
1882 com
= community_str2com(clist_number_or_name
);
1885 vty_out(vty
, "%% Community malformed: %s\n",
1886 clist_number_or_name
);
1890 ret
= bgp_show_ethernet_vpn(vty
, NULL
, show_type
, com
,
1891 SHOW_DISPLAY_STANDARD
,
1892 use_json(argc
, argv
));
1893 community_free(&com
);
1899 /* For testing purpose, static route of EVPN RT-5. */
1900 DEFUN(evpnrt5_network
,
1901 evpnrt5_network_cmd
,
1902 "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]",
1903 "Specify a network to announce via BGP\n"
1906 "Specify Route Distinguisher\n"
1907 "VPN Route Distinguisher\n"
1909 "Ethernet Tag Value\n"
1912 "Ethernet Segment Identifier\n"
1913 "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
1915 "Gateway IP ( A.B.C.D )\n"
1916 "Gateway IPv6 ( X:X::X:X )\n"
1917 "Router Mac Ext Comm\n"
1918 "Router Mac address Value ( aa:bb:cc:dd:ee:ff format)\n"
1919 "Route-map to modify the attributes\n"
1920 "Name of the route map\n")
1922 int idx_ipv4_prefixlen
= 1;
1923 int idx_route_distinguisher
= 3;
1928 int idx_routermac
= 13;
1930 return bgp_static_set_safi(
1931 AFI_L2VPN
, SAFI_EVPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1932 argv
[idx_route_distinguisher
]->arg
, argv
[idx_label
]->arg
, NULL
,
1933 BGP_EVPN_IP_PREFIX_ROUTE
, argv
[idx_esi
]->arg
,
1934 argv
[idx_gwip
]->arg
, argv
[idx_ethtag
]->arg
,
1935 argv
[idx_routermac
]->arg
);
1938 /* For testing purpose, static route of EVPN RT-5. */
1939 DEFUN(no_evpnrt5_network
,
1940 no_evpnrt5_network_cmd
,
1941 "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>",
1943 "Specify a network to announce via BGP\n"
1946 "Specify Route Distinguisher\n"
1947 "VPN Route Distinguisher\n"
1949 "Ethernet Tag Value\n"
1952 "Ethernet Segment Identifier\n"
1953 "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
1954 "Gateway IP\n" "Gateway IP ( A.B.C.D )\n" "Gateway IPv6 ( X:X::X:X )\n")
1956 int idx_ipv4_prefixlen
= 2;
1957 int idx_ext_community
= 4;
1962 return bgp_static_unset_safi(
1963 AFI_L2VPN
, SAFI_EVPN
, vty
, argv
[idx_ipv4_prefixlen
]->arg
,
1964 argv
[idx_ext_community
]->arg
, argv
[idx_label
]->arg
,
1965 BGP_EVPN_IP_PREFIX_ROUTE
, argv
[idx_esi
]->arg
,
1966 argv
[idx_gwip
]->arg
, argv
[idx_ethtag
]->arg
);
1969 static void evpn_import_rt_delete_auto(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1971 evpn_rt_delete_auto(bgp
, vpn
->vni
, vpn
->import_rtl
);
1974 static void evpn_export_rt_delete_auto(struct bgp
*bgp
, struct bgpevpn
*vpn
)
1976 evpn_rt_delete_auto(bgp
, vpn
->vni
, vpn
->export_rtl
);
1980 * Configure the Import RTs for a VNI (vty handler). Caller expected to
1981 * check that this is a change.
1983 static void evpn_configure_import_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
1984 struct ecommunity
*ecomadd
)
1986 /* If the VNI is "live", we need to uninstall routes using the current
1987 * import RT(s) first before we update the import RT, and subsequently
1990 if (is_vni_live(vpn
))
1991 bgp_evpn_uninstall_routes(bgp
, vpn
);
1993 /* Cleanup the RT to VNI mapping and get rid of existing import RT. */
1994 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
1996 /* If the auto route-target is in use we must remove it */
1997 evpn_import_rt_delete_auto(bgp
, vpn
);
1999 /* Add new RT and rebuild the RT to VNI mapping */
2000 listnode_add_sort(vpn
->import_rtl
, ecomadd
);
2002 SET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
2003 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
2005 /* Install routes that match new import RT */
2006 if (is_vni_live(vpn
))
2007 bgp_evpn_install_routes(bgp
, vpn
);
2011 * Unconfigure Import RT(s) for a VNI (vty handler).
2013 static void evpn_unconfigure_import_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2014 struct ecommunity
*ecomdel
)
2016 struct listnode
*node
, *nnode
, *node_to_del
;
2017 struct ecommunity
*ecom
;
2019 /* Along the lines of "configure" except we have to reset to the
2022 if (is_vni_live(vpn
))
2023 bgp_evpn_uninstall_routes(bgp
, vpn
);
2025 /* Cleanup the RT to VNI mapping and get rid of existing import RT. */
2026 bgp_evpn_unmap_vni_from_its_rts(bgp
, vpn
);
2028 /* Delete all import RTs */
2029 if (ecomdel
== NULL
) {
2030 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
2031 ecommunity_free(&ecom
);
2032 list_delete_node(vpn
->import_rtl
, node
);
2036 /* Delete a specific import RT */
2040 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
, ecom
)) {
2041 if (ecommunity_match(ecom
, ecomdel
)) {
2042 ecommunity_free(&ecom
);
2049 list_delete_node(vpn
->import_rtl
, node_to_del
);
2052 assert(vpn
->import_rtl
);
2053 /* Reset to auto RT - this also rebuilds the RT to VNI mapping */
2054 if (list_isempty(vpn
->import_rtl
)) {
2055 UNSET_FLAG(vpn
->flags
, VNI_FLAG_IMPRT_CFGD
);
2056 bgp_evpn_derive_auto_rt_import(bgp
, vpn
);
2058 /* Rebuild the RT to VNI mapping */
2060 bgp_evpn_map_vni_to_its_rts(bgp
, vpn
);
2062 /* Install routes that match new import RT */
2063 if (is_vni_live(vpn
))
2064 bgp_evpn_install_routes(bgp
, vpn
);
2068 * Configure the Export RT for a VNI (vty handler). Caller expected to
2069 * check that this is a change. Note that only a single export RT is
2070 * allowed for a VNI and any change to configuration is implemented as
2071 * a "replace" (similar to other configuration).
2073 static void evpn_configure_export_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2074 struct ecommunity
*ecomadd
)
2076 /* If the auto route-target is in use we must remove it */
2077 evpn_export_rt_delete_auto(bgp
, vpn
);
2079 listnode_add_sort(vpn
->export_rtl
, ecomadd
);
2080 SET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
2082 if (is_vni_live(vpn
))
2083 bgp_evpn_handle_export_rt_change(bgp
, vpn
);
2087 * Unconfigure the Export RT for a VNI (vty handler)
2089 static void evpn_unconfigure_export_rt(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2090 struct ecommunity
*ecomdel
)
2092 struct listnode
*node
, *nnode
, *node_to_del
;
2093 struct ecommunity
*ecom
;
2095 /* Delete all export RTs */
2096 if (ecomdel
== NULL
) {
2097 /* Reset to default and process all routes. */
2098 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
2099 ecommunity_free(&ecom
);
2100 list_delete_node(vpn
->export_rtl
, node
);
2104 /* Delete a specific export RT */
2108 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
, ecom
)) {
2109 if (ecommunity_match(ecom
, ecomdel
)) {
2110 ecommunity_free(&ecom
);
2117 list_delete_node(vpn
->export_rtl
, node_to_del
);
2120 assert(vpn
->export_rtl
);
2121 if (list_isempty(vpn
->export_rtl
)) {
2122 UNSET_FLAG(vpn
->flags
, VNI_FLAG_EXPRT_CFGD
);
2123 bgp_evpn_derive_auto_rt_export(bgp
, vpn
);
2126 if (is_vni_live(vpn
))
2127 bgp_evpn_handle_export_rt_change(bgp
, vpn
);
2131 * Configure RD for VRF
2133 static void evpn_configure_vrf_rd(struct bgp
*bgp_vrf
, struct prefix_rd
*rd
)
2135 /* If we have already advertise type-5 routes with a diffrent RD, we
2136 * have to delete and withdraw them firs
2138 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 1);
2141 memcpy(&bgp_vrf
->vrf_prd
, rd
, sizeof(struct prefix_rd
));
2142 SET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_RD_CFGD
);
2144 /* We have a new RD for VRF.
2145 * Advertise all type-5 routes again with the new RD
2147 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 0);
2151 * Unconfigure RD for VRF
2153 static void evpn_unconfigure_vrf_rd(struct bgp
*bgp_vrf
)
2155 /* If we have already advertise type-5 routes with a diffrent RD, we
2156 * have to delete and withdraw them firs
2158 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 1);
2160 /* fall back to default RD */
2161 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf
);
2162 UNSET_FLAG(bgp_vrf
->vrf_flags
, BGP_VRF_RD_CFGD
);
2164 /* We have a new RD for VRF.
2165 * Advertise all type-5 routes again with the new RD
2167 bgp_evpn_handle_vrf_rd_change(bgp_vrf
, 0);
2171 * Configure RD for a VNI (vty handler)
2173 static void evpn_configure_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2174 struct prefix_rd
*rd
)
2176 /* If the VNI is "live", we need to delete and withdraw this VNI's
2177 * local routes with the prior RD first. Then, after updating RD,
2178 * need to re-advertise.
2180 if (is_vni_live(vpn
))
2181 bgp_evpn_handle_rd_change(bgp
, vpn
, 1);
2184 memcpy(&vpn
->prd
, rd
, sizeof(struct prefix_rd
));
2185 SET_FLAG(vpn
->flags
, VNI_FLAG_RD_CFGD
);
2187 if (is_vni_live(vpn
))
2188 bgp_evpn_handle_rd_change(bgp
, vpn
, 0);
2192 * Unconfigure RD for a VNI (vty handler)
2194 static void evpn_unconfigure_rd(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2196 /* If the VNI is "live", we need to delete and withdraw this VNI's
2197 * local routes with the prior RD first. Then, after resetting RD
2198 * to automatic value, need to re-advertise.
2200 if (is_vni_live(vpn
))
2201 bgp_evpn_handle_rd_change(bgp
, vpn
, 1);
2203 /* reset RD to default */
2204 bgp_evpn_derive_auto_rd(bgp
, vpn
);
2206 if (is_vni_live(vpn
))
2207 bgp_evpn_handle_rd_change(bgp
, vpn
, 0);
2211 * Create VNI, if not already present (VTY handler). Mark as configured.
2213 static struct bgpevpn
*evpn_create_update_vni(struct bgp
*bgp
, vni_t vni
)
2215 struct bgpevpn
*vpn
;
2216 struct in_addr mcast_grp
= {INADDR_ANY
};
2221 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2223 /* Check if this L2VNI is already configured as L3VNI */
2224 if (bgp_evpn_lookup_l3vni_l2vni_table(vni
)) {
2227 "%u: Failed to create L2VNI %u, it is configured as L3VNI",
2232 /* tenant vrf will be updated when we get local_vni_add from
2235 vpn
= bgp_evpn_new(bgp
, vni
, bgp
->router_id
, 0, mcast_grp
);
2239 "%u: Failed to allocate VNI entry for VNI %u - at Config",
2245 /* Mark as configured. */
2246 SET_FLAG(vpn
->flags
, VNI_FLAG_CFGD
);
2251 * Delete VNI. If VNI does not exist in the system (i.e., just
2252 * configuration), all that is needed is to free it. Otherwise,
2253 * any parameters configured for the VNI need to be reset (with
2254 * appropriate action) and the VNI marked as unconfigured; the
2255 * VNI will continue to exist, purely as a "learnt" entity.
2257 static void evpn_delete_vni(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2259 assert(bgp
->vnihash
);
2261 if (!is_vni_live(vpn
)) {
2262 bgp_evpn_free(bgp
, vpn
);
2266 /* We need to take the unconfigure action for each parameter of this VNI
2267 * that is configured. Some optimization is possible, but not worth the
2268 * additional code for an operation that should be pretty rare.
2270 UNSET_FLAG(vpn
->flags
, VNI_FLAG_CFGD
);
2272 /* First, deal with the export side - RD and export RT changes. */
2273 if (is_rd_configured(vpn
))
2274 evpn_unconfigure_rd(bgp
, vpn
);
2275 if (is_export_rt_configured(vpn
))
2276 evpn_unconfigure_export_rt(bgp
, vpn
, NULL
);
2278 /* Next, deal with the import side. */
2279 if (is_import_rt_configured(vpn
))
2280 evpn_unconfigure_import_rt(bgp
, vpn
, NULL
);
2284 * Display import RT mapping to VRFs (vty handler)
2285 * bgp_evpn: evpn bgp instance
2287 static void evpn_show_vrf_import_rts(struct vty
*vty
, struct bgp
*bgp_evpn
,
2295 hash_iterate(bgp_evpn
->vrf_import_rt_hash
,
2296 (void (*)(struct hash_bucket
*,
2297 void *))show_vrf_import_rt_entry
,
2302 * Display import RT mapping to VNIs (vty handler)
2304 static void evpn_show_import_rts(struct vty
*vty
, struct bgp
*bgp
,
2313 bgp
->import_rt_hash
,
2314 (void (*)(struct hash_bucket
*, void *))show_import_rt_entry
,
2319 * Display EVPN routes for all VNIs - vty handler.
2321 static void evpn_show_routes_vni_all(struct vty
*vty
, struct bgp
*bgp
,
2322 struct in_addr vtep_ip
, json_object
*json
,
2326 struct vni_walk_ctx wctx
;
2328 num_vnis
= hashcount(bgp
->vnihash
);
2331 memset(&wctx
, 0, sizeof(struct vni_walk_ctx
));
2334 wctx
.vtep_ip
= vtep_ip
;
2336 wctx
.detail
= detail
;
2337 hash_iterate(bgp
->vnihash
, (void (*)(struct hash_bucket
*,
2338 void *))show_vni_routes_hash
,
2343 * Display EVPN routes for a VNI -- for specific type-3 route (vty handler).
2345 static void evpn_show_route_vni_multicast(struct vty
*vty
, struct bgp
*bgp
,
2346 vni_t vni
, struct in_addr orig_ip
,
2349 struct bgpevpn
*vpn
;
2350 struct prefix_evpn p
;
2351 struct bgp_dest
*dest
;
2352 struct bgp_path_info
*pi
;
2353 uint32_t path_cnt
= 0;
2356 json_object
*json_paths
= NULL
;
2362 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2364 vty_out(vty
, "VNI not found\n");
2368 /* See if route exists. */
2369 build_evpn_type3_prefix(&p
, orig_ip
);
2370 dest
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
2371 if (!dest
|| !bgp_dest_has_bgp_path_info_data(dest
)) {
2373 vty_out(vty
, "%% Network not in table\n");
2378 json_paths
= json_object_new_array();
2380 /* Prefix and num paths displayed once per prefix. */
2381 route_vty_out_detail_header(vty
, bgp
, dest
, NULL
, afi
, safi
, json
);
2383 /* Display each path for this prefix. */
2384 for (pi
= bgp_dest_get_bgp_path_info(dest
); pi
; pi
= pi
->next
) {
2385 json_object
*json_path
= NULL
;
2388 json_path
= json_object_new_array();
2390 route_vty_out_detail(vty
, bgp
, dest
, pi
, afi
, safi
,
2391 RPKI_NOT_BEING_USED
, json_path
);
2394 json_object_array_add(json_paths
, json_path
);
2401 json_object_object_add(json
, "paths", json_paths
);
2403 json_object_int_add(json
, "numPaths", path_cnt
);
2405 vty_out(vty
, "\nDisplayed %u paths for requested prefix\n",
2411 * Display EVPN routes for a VNI -- for specific MAC and/or IP (vty handler).
2412 * By definition, only matching type-2 route will be displayed.
2414 static void evpn_show_route_vni_macip(struct vty
*vty
, struct bgp
*bgp
,
2415 vni_t vni
, struct ethaddr
*mac
,
2416 struct ipaddr
*ip
, json_object
*json
)
2418 struct bgpevpn
*vpn
;
2419 struct prefix_evpn p
;
2420 struct bgp_dest
*dest
;
2421 struct bgp_path_info
*pi
;
2422 uint32_t path_cnt
= 0;
2425 json_object
*json_paths
= NULL
;
2431 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2434 vty_out(vty
, "VNI not found\n");
2438 /* See if route exists. Look for both non-sticky and sticky. */
2439 build_evpn_type2_prefix(&p
, mac
, ip
);
2440 dest
= bgp_node_lookup(vpn
->route_table
, (struct prefix
*)&p
);
2441 if (!dest
|| !bgp_dest_has_bgp_path_info_data(dest
)) {
2443 vty_out(vty
, "%% Network not in table\n");
2448 json_paths
= json_object_new_array();
2450 /* Prefix and num paths displayed once per prefix. */
2451 route_vty_out_detail_header(vty
, bgp
, dest
, NULL
, afi
, safi
, json
);
2453 /* Display each path for this prefix. */
2454 for (pi
= bgp_dest_get_bgp_path_info(dest
); pi
; pi
= pi
->next
) {
2455 json_object
*json_path
= NULL
;
2458 json_path
= json_object_new_array();
2460 route_vty_out_detail(vty
, bgp
, dest
, pi
, afi
, safi
,
2461 RPKI_NOT_BEING_USED
, json_path
);
2464 json_object_array_add(json_paths
, json_path
);
2471 json_object_object_add(json
, "paths", json_paths
);
2473 json_object_int_add(json
, "numPaths", path_cnt
);
2475 vty_out(vty
, "\nDisplayed %u paths for requested prefix\n",
2480 /* Disaplay EVPN routes for a ESI - VTY handler */
2481 static void evpn_show_routes_esi(struct vty
*vty
, struct bgp
*bgp
,
2482 esi_t
*esi
, json_object
*json
)
2484 struct bgp_evpn_es
*es
= NULL
;
2487 es
= bgp_evpn_es_find(esi
);
2490 vty_out(vty
, "ESI not found\n");
2494 show_esi_routes(bgp
, es
, vty
, json
);
2498 * Display EVPN routes for a VNI - vty handler.
2499 * If 'type' is non-zero, only routes matching that type are shown.
2500 * If the vtep_ip is non zero, only routes behind that vtep are shown
2502 static void evpn_show_routes_vni(struct vty
*vty
, struct bgp
*bgp
, vni_t vni
,
2503 int type
, struct in_addr vtep_ip
,
2506 struct bgpevpn
*vpn
;
2509 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2512 vty_out(vty
, "VNI not found\n");
2516 /* Walk this VNI's route table and display appropriate routes. */
2517 show_vni_routes(bgp
, vpn
, type
, vty
, vtep_ip
, json
, 0);
2521 * Display BGP EVPN routing table -- for specific RD and MAC and/or
2522 * IP (vty handler). By definition, only matching type-2 route will be
2525 static void evpn_show_route_rd_macip(struct vty
*vty
, struct bgp
*bgp
,
2526 struct prefix_rd
*prd
, struct ethaddr
*mac
,
2527 struct ipaddr
*ip
, json_object
*json
)
2529 struct prefix_evpn p
;
2530 struct bgp_dest
*dest
;
2531 struct bgp_path_info
*pi
;
2534 uint32_t path_cnt
= 0;
2535 json_object
*json_paths
= NULL
;
2536 char prefix_str
[BUFSIZ
];
2541 /* See if route exists. Look for both non-sticky and sticky. */
2542 build_evpn_type2_prefix(&p
, mac
, ip
);
2543 dest
= bgp_afi_node_lookup(bgp
->rib
[afi
][safi
], afi
, safi
,
2544 (struct prefix
*)&p
, prd
);
2545 if (!dest
|| !bgp_dest_has_bgp_path_info_data(dest
)) {
2547 vty_out(vty
, "%% Network not in table\n");
2551 prefix2str(&p
, prefix_str
, sizeof(prefix_str
));
2553 /* Prefix and num paths displayed once per prefix. */
2554 route_vty_out_detail_header(vty
, bgp
, dest
, prd
, afi
, safi
, json
);
2557 json_paths
= json_object_new_array();
2559 /* Display each path for this prefix. */
2560 for (pi
= bgp_dest_get_bgp_path_info(dest
); pi
; pi
= pi
->next
) {
2561 json_object
*json_path
= NULL
;
2564 json_path
= json_object_new_array();
2566 route_vty_out_detail(vty
, bgp
, dest
, pi
, afi
, safi
,
2567 RPKI_NOT_BEING_USED
, json_path
);
2570 json_object_array_add(json_paths
, json_path
);
2575 if (json
&& path_cnt
) {
2577 json_object_object_add(json
, prefix_str
, json_paths
);
2578 json_object_int_add(json
, "numPaths", path_cnt
);
2580 vty_out(vty
, "\nDisplayed %u paths for requested prefix\n",
2586 * Display BGP EVPN routing table -- for specific RD (vty handler)
2587 * If 'type' is non-zero, only routes matching that type are shown.
2589 static void evpn_show_route_rd(struct vty
*vty
, struct bgp
*bgp
,
2590 struct prefix_rd
*prd
, int type
,
2593 struct bgp_dest
*rd_dest
;
2594 struct bgp_table
*table
;
2595 struct bgp_dest
*dest
;
2596 struct bgp_path_info
*pi
;
2600 uint32_t prefix_cnt
, path_cnt
;
2601 char rd_str
[RD_ADDRSTRLEN
];
2602 json_object
*json_rd
= NULL
;
2603 int add_rd_to_json
= 0;
2607 prefix_cnt
= path_cnt
= 0;
2609 prefix_rd2str(prd
, rd_str
, sizeof(rd_str
));
2611 rd_dest
= bgp_node_lookup(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
2615 table
= bgp_dest_get_bgp_table_info(rd_dest
);
2620 json_rd
= json_object_new_object();
2621 json_object_string_add(json_rd
, "rd", rd_str
);
2624 /* Display all prefixes with this RD. */
2625 for (dest
= bgp_table_top(table
); dest
; dest
= bgp_route_next(dest
)) {
2626 const struct prefix_evpn
*evp
=
2627 (const struct prefix_evpn
*)bgp_dest_get_prefix(dest
);
2628 json_object
*json_prefix
= NULL
;
2629 json_object
*json_paths
= NULL
;
2630 char prefix_str
[BUFSIZ
];
2631 int add_prefix_to_json
= 0;
2633 prefix2str((struct prefix_evpn
*)evp
, prefix_str
,
2634 sizeof(prefix_str
));
2636 if (type
&& evp
->prefix
.route_type
!= type
)
2640 json_prefix
= json_object_new_object();
2642 pi
= bgp_dest_get_bgp_path_info(dest
);
2644 /* RD header and legend - once overall. */
2645 if (rd_header
&& !json
) {
2647 "EVPN type-1 prefix: [1]:[ESI]:[EthTag]:[IPlen]:[VTEP-IP]\n");
2649 "EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]\n");
2651 "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
2653 "EVPN type-4 prefix: [4]:[ESI]:[IPlen]:[OrigIP]\n");
2655 "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
2659 /* Prefix and num paths displayed once per prefix. */
2660 route_vty_out_detail_header(vty
, bgp
, dest
, prd
, afi
,
2667 json_paths
= json_object_new_array();
2669 /* Display each path for this prefix. */
2670 for (; pi
; pi
= pi
->next
) {
2671 json_object
*json_path
= NULL
;
2674 json_path
= json_object_new_array();
2676 route_vty_out_detail(vty
, bgp
, dest
, pi
, afi
, safi
,
2677 RPKI_NOT_BEING_USED
, json_path
);
2680 json_object_array_add(json_paths
, json_path
);
2683 add_prefix_to_json
= 1;
2688 if (add_prefix_to_json
) {
2689 json_object_object_add(json_prefix
, "paths",
2691 json_object_object_add(json_rd
, prefix_str
,
2694 json_object_free(json_paths
);
2695 json_object_free(json_prefix
);
2704 json_object_object_add(json
, rd_str
, json_rd
);
2706 json_object_free(json_rd
);
2710 json_object_int_add(json
, "numPrefix", prefix_cnt
);
2711 json_object_int_add(json
, "numPaths", path_cnt
);
2713 if (prefix_cnt
== 0)
2714 vty_out(vty
, "No prefixes exist with this RD%s\n",
2715 type
? " (of requested type)" : "");
2718 "\nDisplayed %u prefixes (%u paths) with this RD%s\n",
2719 prefix_cnt
, path_cnt
,
2720 type
? " (of requested type)" : "");
2725 * Display BGP EVPN routing table - all routes (vty handler).
2726 * If 'type' is non-zero, only routes matching that type are shown.
2728 static void evpn_show_all_routes(struct vty
*vty
, struct bgp
*bgp
, int type
,
2729 json_object
*json
, int detail
)
2731 struct bgp_dest
*rd_dest
;
2732 struct bgp_table
*table
;
2733 struct bgp_dest
*dest
;
2734 struct bgp_path_info
*pi
;
2735 int header
= detail
? 0 : 1;
2739 uint32_t prefix_cnt
, path_cnt
;
2743 prefix_cnt
= path_cnt
= 0;
2745 /* EVPN routing table is a 2-level table with the first level being
2748 for (rd_dest
= bgp_table_top(bgp
->rib
[afi
][safi
]); rd_dest
;
2749 rd_dest
= bgp_route_next(rd_dest
)) {
2750 char rd_str
[RD_ADDRSTRLEN
];
2751 json_object
*json_rd
= NULL
; /* contains routes for an RD */
2752 int add_rd_to_json
= 0;
2754 const struct prefix
*rd_destp
= bgp_dest_get_prefix(rd_dest
);
2756 table
= bgp_dest_get_bgp_table_info(rd_dest
);
2760 tbl_ver
= table
->version
;
2761 prefix_rd2str((struct prefix_rd
*)rd_destp
, rd_str
,
2765 json_rd
= json_object_new_object();
2769 /* Display all prefixes for an RD */
2770 for (dest
= bgp_table_top(table
); dest
;
2771 dest
= bgp_route_next(dest
)) {
2772 json_object
*json_prefix
=
2773 NULL
; /* contains prefix under a RD */
2774 json_object
*json_paths
=
2775 NULL
; /* array of paths under a prefix*/
2776 const struct prefix_evpn
*evp
=
2777 (const struct prefix_evpn
*)bgp_dest_get_prefix(
2779 char prefix_str
[BUFSIZ
];
2780 int add_prefix_to_json
= 0;
2781 const struct prefix
*p
= bgp_dest_get_prefix(dest
);
2783 prefix2str((struct prefix_evpn
*)p
, prefix_str
,
2784 sizeof(prefix_str
));
2786 if (type
&& evp
->prefix
.route_type
!= type
)
2789 pi
= bgp_dest_get_bgp_path_info(dest
);
2791 /* Overall header/legend displayed once. */
2793 bgp_evpn_show_route_header(vty
, bgp
,
2798 "%19s Extended Community\n"
2803 /* RD header - per RD. */
2805 bgp_evpn_show_route_rd_header(
2806 vty
, rd_dest
, json_rd
, rd_str
,
2815 json_prefix
= json_object_new_object();
2816 json_paths
= json_object_new_array();
2817 json_object_string_add(json_prefix
, "prefix",
2819 json_object_int_add(json_prefix
, "prefixLen",
2823 /* Prefix and num paths displayed once per prefix. */
2825 route_vty_out_detail_header(
2827 (struct prefix_rd
*)rd_destp
, AFI_L2VPN
,
2828 SAFI_EVPN
, json_prefix
);
2830 /* For EVPN, the prefix is displayed for each path (to
2832 * with code that already exists).
2834 for (; pi
; pi
= pi
->next
) {
2835 json_object
*json_path
= NULL
;
2837 add_prefix_to_json
= 1;
2841 json_path
= json_object_new_array();
2844 route_vty_out_detail(
2845 vty
, bgp
, dest
, pi
, AFI_L2VPN
,
2846 SAFI_EVPN
, RPKI_NOT_BEING_USED
,
2849 route_vty_out(vty
, p
, pi
, 0, SAFI_EVPN
,
2853 json_object_array_add(json_paths
,
2858 if (add_prefix_to_json
) {
2859 json_object_object_add(json_prefix
,
2862 json_object_object_add(json_rd
,
2866 json_object_free(json_prefix
);
2867 json_object_free(json_paths
);
2876 json_object_object_add(json
, rd_str
, json_rd
);
2878 json_object_free(json_rd
);
2885 json_object_int_add(json
, "numPrefix", prefix_cnt
);
2886 json_object_int_add(json
, "numPaths", path_cnt
);
2888 if (prefix_cnt
== 0) {
2889 vty_out(vty
, "No EVPN prefixes %sexist\n",
2890 type
? "(of requested type) " : "");
2892 vty_out(vty
, "\nDisplayed %u prefixes (%u paths)%s\n",
2893 prefix_cnt
, path_cnt
,
2894 type
? " (of requested type)" : "");
2900 * Display specified VNI (vty handler)
2902 static void evpn_show_vni(struct vty
*vty
, struct bgp
*bgp
, vni_t vni
,
2906 struct bgpevpn
*vpn
;
2908 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
2911 display_vni(vty
, vpn
, json
);
2913 struct bgp
*bgp_temp
;
2914 struct listnode
*node
= NULL
;
2916 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp_temp
)) {
2917 if (bgp_temp
->l3vni
== vni
) {
2919 display_l3vni(vty
, bgp_temp
, json
);
2926 vty_out(vty
, "{}\n");
2928 vty_out(vty
, "VNI not found\n");
2935 * Display a VNI (upon user query).
2937 static void evpn_show_all_vnis(struct vty
*vty
, struct bgp
*bgp
,
2941 struct bgp
*bgp_temp
= NULL
;
2942 struct listnode
*node
;
2946 vty_out(vty
, "Flags: * - Kernel\n");
2947 vty_out(vty
, " %-10s %-4s %-21s %-25s %-25s %-37s\n", "VNI",
2948 "Type", "RD", "Import RT", "Export RT", "Tenant VRF");
2951 /* print all L2 VNIS */
2954 hash_iterate(bgp
->vnihash
,
2955 (void (*)(struct hash_bucket
*, void *))show_vni_entry
,
2958 /* print all L3 VNIs */
2959 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp_temp
))
2960 show_l3vni_entry(vty
, bgp_temp
, json
);
2964 * evpn - enable advertisement of svi MAC-IP
2966 static void evpn_set_advertise_svi_macip(struct bgp
*bgp
, struct bgpevpn
*vpn
,
2970 if (set
&& bgp
->evpn_info
->advertise_svi_macip
)
2972 else if (!set
&& !bgp
->evpn_info
->advertise_svi_macip
)
2975 bgp
->evpn_info
->advertise_svi_macip
= set
;
2976 bgp_zebra_advertise_svi_macip(bgp
,
2977 bgp
->evpn_info
->advertise_svi_macip
, 0);
2979 if (set
&& vpn
->advertise_svi_macip
)
2981 else if (!set
&& !vpn
->advertise_svi_macip
)
2984 vpn
->advertise_svi_macip
= set
;
2985 bgp_zebra_advertise_svi_macip(bgp
, vpn
->advertise_svi_macip
,
2991 * evpn - enable advertisement of default g/w
2993 static void evpn_set_advertise_default_gw(struct bgp
*bgp
, struct bgpevpn
*vpn
)
2996 if (bgp
->advertise_gw_macip
)
2999 bgp
->advertise_gw_macip
= 1;
3000 bgp_zebra_advertise_gw_macip(bgp
, bgp
->advertise_gw_macip
, 0);
3002 if (vpn
->advertise_gw_macip
)
3005 vpn
->advertise_gw_macip
= 1;
3006 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
,
3013 * evpn - disable advertisement of default g/w
3015 static void evpn_unset_advertise_default_gw(struct bgp
*bgp
,
3016 struct bgpevpn
*vpn
)
3019 if (!bgp
->advertise_gw_macip
)
3022 bgp
->advertise_gw_macip
= 0;
3023 bgp_zebra_advertise_gw_macip(bgp
, bgp
->advertise_gw_macip
, 0);
3025 if (!vpn
->advertise_gw_macip
)
3028 vpn
->advertise_gw_macip
= 0;
3029 bgp_zebra_advertise_gw_macip(bgp
, vpn
->advertise_gw_macip
,
3036 * evpn - enable advertisement of default g/w
3038 static void evpn_process_default_originate_cmd(struct bgp
*bgp_vrf
,
3039 afi_t afi
, bool add
)
3041 safi_t safi
= SAFI_UNICAST
; /* ipv4/ipv6 unicast */
3044 /* bail if we are already advertising default route */
3045 if (evpn_default_originate_set(bgp_vrf
, afi
, safi
))
3049 SET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3050 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4
);
3051 else if (afi
== AFI_IP6
)
3052 SET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3053 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6
);
3055 /* bail out if we havent advertised the default route */
3056 if (!evpn_default_originate_set(bgp_vrf
, afi
, safi
))
3059 UNSET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3060 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4
);
3061 else if (afi
== AFI_IP6
)
3062 UNSET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3063 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6
);
3066 bgp_evpn_install_uninstall_default_route(bgp_vrf
, afi
, safi
, add
);
3070 * evpn - enable advertisement of default g/w
3072 static void evpn_set_advertise_subnet(struct bgp
*bgp
,
3073 struct bgpevpn
*vpn
)
3075 if (vpn
->advertise_subnet
)
3078 vpn
->advertise_subnet
= 1;
3079 bgp_zebra_advertise_subnet(bgp
, vpn
->advertise_subnet
, vpn
->vni
);
3083 * evpn - disable advertisement of default g/w
3085 static void evpn_unset_advertise_subnet(struct bgp
*bgp
, struct bgpevpn
*vpn
)
3087 if (!vpn
->advertise_subnet
)
3090 vpn
->advertise_subnet
= 0;
3091 bgp_zebra_advertise_subnet(bgp
, vpn
->advertise_subnet
, vpn
->vni
);
3095 * EVPN (VNI advertisement) enabled. Register with zebra.
3097 static void evpn_set_advertise_all_vni(struct bgp
*bgp
)
3099 bgp
->advertise_all_vni
= 1;
3101 bgp_zebra_advertise_all_vni(bgp
, bgp
->advertise_all_vni
);
3105 * EVPN (VNI advertisement) disabled. De-register with zebra. Cleanup VNI
3106 * cache, EVPN routes (delete and withdraw from peers).
3108 static void evpn_unset_advertise_all_vni(struct bgp
*bgp
)
3110 bgp
->advertise_all_vni
= 0;
3111 bgp_set_evpn(bgp_get_default());
3112 bgp_zebra_advertise_all_vni(bgp
, bgp
->advertise_all_vni
);
3113 bgp_evpn_cleanup_on_disable(bgp
);
3117 * EVPN - use RFC8365 to auto-derive RT
3119 static void evpn_set_advertise_autort_rfc8365(struct bgp
*bgp
)
3121 bgp
->advertise_autort_rfc8365
= 1;
3122 bgp_evpn_handle_autort_change(bgp
);
3126 * EVPN - don't use RFC8365 to auto-derive RT
3128 static void evpn_unset_advertise_autort_rfc8365(struct bgp
*bgp
)
3130 bgp
->advertise_autort_rfc8365
= 0;
3131 bgp_evpn_handle_autort_change(bgp
);
3134 static void write_vni_config(struct vty
*vty
, struct bgpevpn
*vpn
)
3136 char buf1
[RD_ADDRSTRLEN
];
3138 struct listnode
*node
, *nnode
;
3139 struct ecommunity
*ecom
;
3141 if (is_vni_configured(vpn
)) {
3142 vty_out(vty
, " vni %d\n", vpn
->vni
);
3143 if (is_rd_configured(vpn
))
3144 vty_out(vty
, " rd %s\n",
3145 prefix_rd2str(&vpn
->prd
, buf1
, sizeof(buf1
)));
3147 if (is_import_rt_configured(vpn
)) {
3148 for (ALL_LIST_ELEMENTS(vpn
->import_rtl
, node
, nnode
,
3150 ecom_str
= ecommunity_ecom2str(
3151 ecom
, ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
3152 vty_out(vty
, " route-target import %s\n",
3154 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
3158 if (is_export_rt_configured(vpn
)) {
3159 for (ALL_LIST_ELEMENTS(vpn
->export_rtl
, node
, nnode
,
3161 ecom_str
= ecommunity_ecom2str(
3162 ecom
, ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
3163 vty_out(vty
, " route-target export %s\n",
3165 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
3169 if (vpn
->advertise_gw_macip
)
3170 vty_out(vty
, " advertise-default-gw\n");
3172 if (vpn
->advertise_svi_macip
)
3173 vty_out(vty
, " advertise-svi-ip\n");
3175 if (vpn
->advertise_subnet
)
3176 vty_out(vty
, " advertise-subnet\n");
3178 vty_out(vty
, " exit-vni\n");
3182 #ifndef VTYSH_EXTRACT_PL
3183 #include "bgpd/bgp_evpn_vty_clippy.c"
3186 DEFPY(bgp_evpn_flood_control
,
3187 bgp_evpn_flood_control_cmd
,
3188 "[no$no] flooding <disable$disable|head-end-replication$her>",
3190 "Specify handling for BUM packets\n"
3191 "Do not flood any BUM packets\n"
3192 "Flood BUM packets using head-end replication\n")
3194 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3195 enum vxlan_flood_control flood_ctrl
;
3201 flood_ctrl
= VXLAN_FLOOD_DISABLED
;
3203 flood_ctrl
= VXLAN_FLOOD_HEAD_END_REPL
;
3207 if (bgp
->vxlan_flood_ctrl
== flood_ctrl
)
3210 bgp
->vxlan_flood_ctrl
= flood_ctrl
;
3211 bgp_evpn_flood_control_change(bgp
);
3216 DEFUN (bgp_evpn_advertise_default_gw_vni
,
3217 bgp_evpn_advertise_default_gw_vni_cmd
,
3218 "advertise-default-gw",
3219 "Advertise default g/w mac-ip routes in EVPN for a VNI\n")
3221 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3222 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3227 evpn_set_advertise_default_gw(bgp
, vpn
);
3232 DEFUN (no_bgp_evpn_advertise_default_vni_gw
,
3233 no_bgp_evpn_advertise_default_gw_vni_cmd
,
3234 "no advertise-default-gw",
3236 "Withdraw default g/w mac-ip routes from EVPN for a VNI\n")
3238 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3239 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3244 evpn_unset_advertise_default_gw(bgp
, vpn
);
3250 DEFUN (bgp_evpn_advertise_default_gw
,
3251 bgp_evpn_advertise_default_gw_cmd
,
3252 "advertise-default-gw",
3253 "Advertise All default g/w mac-ip routes in EVPN\n")
3255 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3260 if (!EVPN_ENABLED(bgp
)) {
3262 "This command is only supported under the EVPN VRF\n");
3266 evpn_set_advertise_default_gw(bgp
, NULL
);
3271 DEFUN (no_bgp_evpn_advertise_default_gw
,
3272 no_bgp_evpn_advertise_default_gw_cmd
,
3273 "no advertise-default-gw",
3275 "Withdraw All default g/w mac-ip routes from EVPN\n")
3277 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3282 if (!EVPN_ENABLED(bgp
)) {
3284 "This command is only supported under the EVPN VRF\n");
3288 evpn_unset_advertise_default_gw(bgp
, NULL
);
3293 DEFUN (bgp_evpn_advertise_all_vni
,
3294 bgp_evpn_advertise_all_vni_cmd
,
3295 "advertise-all-vni",
3296 "Advertise All local VNIs\n")
3298 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3299 struct bgp
*bgp_evpn
= NULL
;
3304 bgp_evpn
= bgp_get_evpn();
3305 if (bgp_evpn
&& bgp_evpn
!= bgp
) {
3306 vty_out(vty
, "%% Please unconfigure EVPN in VRF %s\n",
3308 return CMD_WARNING_CONFIG_FAILED
;
3311 evpn_set_advertise_all_vni(bgp
);
3315 DEFUN (no_bgp_evpn_advertise_all_vni
,
3316 no_bgp_evpn_advertise_all_vni_cmd
,
3317 "no advertise-all-vni",
3319 "Advertise All local VNIs\n")
3321 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3325 evpn_unset_advertise_all_vni(bgp
);
3329 DEFUN (bgp_evpn_advertise_autort_rfc8365
,
3330 bgp_evpn_advertise_autort_rfc8365_cmd
,
3331 "autort rfc8365-compatible",
3332 "Auto-derivation of RT\n"
3333 "Auto-derivation of RT using RFC8365\n")
3335 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3339 evpn_set_advertise_autort_rfc8365(bgp
);
3343 DEFUN (no_bgp_evpn_advertise_autort_rfc8365
,
3344 no_bgp_evpn_advertise_autort_rfc8365_cmd
,
3345 "no autort rfc8365-compatible",
3347 "Auto-derivation of RT\n"
3348 "Auto-derivation of RT using RFC8365\n")
3350 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3354 evpn_unset_advertise_autort_rfc8365(bgp
);
3358 DEFUN (bgp_evpn_default_originate
,
3359 bgp_evpn_default_originate_cmd
,
3360 "default-originate <ipv4 | ipv6>",
3361 "originate a default route\n"
3362 "ipv4 address family\n"
3363 "ipv6 address family\n")
3367 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3371 argv_find_and_parse_afi(argv
, argc
, &idx_afi
, &afi
);
3372 evpn_process_default_originate_cmd(bgp_vrf
, afi
, true);
3376 DEFUN (no_bgp_evpn_default_originate
,
3377 no_bgp_evpn_default_originate_cmd
,
3378 "no default-originate <ipv4 | ipv6>",
3380 "withdraw a default route\n"
3381 "ipv4 address family\n"
3382 "ipv6 address family\n")
3386 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3390 argv_find_and_parse_afi(argv
, argc
, &idx_afi
, &afi
);
3391 evpn_process_default_originate_cmd(bgp_vrf
, afi
, false);
3395 DEFPY (dup_addr_detection
,
3396 dup_addr_detection_cmd
,
3397 "dup-addr-detection [max-moves (2-1000)$max_moves_val time (2-1800)$time_val]",
3398 "Duplicate address detection\n"
3399 "Max allowed moves before address detected as duplicate\n"
3400 "Num of max allowed moves (2-1000) default 5\n"
3401 "Duplicate address detection time\n"
3402 "Time in seconds (2-1800) default 180\n")
3404 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3409 if (!EVPN_ENABLED(bgp_vrf
)) {
3411 "This command is only supported under the EVPN VRF\n");
3415 bgp_vrf
->evpn_info
->dup_addr_detect
= true;
3418 bgp_vrf
->evpn_info
->dad_time
= time_val
;
3420 bgp_vrf
->evpn_info
->dad_max_moves
= max_moves_val
;
3422 bgp_zebra_dup_addr_detection(bgp_vrf
);
3427 DEFPY (dup_addr_detection_auto_recovery
,
3428 dup_addr_detection_auto_recovery_cmd
,
3429 "dup-addr-detection freeze <permanent |(30-3600)$freeze_time_val>",
3430 "Duplicate address detection\n"
3431 "Duplicate address detection freeze\n"
3432 "Duplicate address detection permanent freeze\n"
3433 "Duplicate address detection freeze time (30-3600)\n")
3435 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3436 uint32_t freeze_time
= freeze_time_val
;
3441 if (!EVPN_ENABLED(bgp_vrf
)) {
3443 "This command is only supported under the EVPN VRF\n");
3447 bgp_vrf
->evpn_info
->dup_addr_detect
= true;
3448 bgp_vrf
->evpn_info
->dad_freeze
= true;
3449 bgp_vrf
->evpn_info
->dad_freeze_time
= freeze_time
;
3451 bgp_zebra_dup_addr_detection(bgp_vrf
);
3456 DEFPY (no_dup_addr_detection
,
3457 no_dup_addr_detection_cmd
,
3458 "no dup-addr-detection [max-moves (2-1000)$max_moves_val time (2-1800)$time_val | freeze <permanent$permanent_val | (30-3600)$freeze_time_val>]",
3460 "Duplicate address detection\n"
3461 "Max allowed moves before address detected as duplicate\n"
3462 "Num of max allowed moves (2-1000) default 5\n"
3463 "Duplicate address detection time\n"
3464 "Time in seconds (2-1800) default 180\n"
3465 "Duplicate address detection freeze\n"
3466 "Duplicate address detection permanent freeze\n"
3467 "Duplicate address detection freeze time (30-3600)\n")
3469 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
3470 uint32_t max_moves
= (uint32_t)max_moves_val
;
3471 uint32_t freeze_time
= (uint32_t)freeze_time_val
;
3476 if (!EVPN_ENABLED(bgp_vrf
)) {
3478 "This command is only supported under the EVPN VRF\n");
3483 if (!bgp_vrf
->evpn_info
->dup_addr_detect
)
3485 /* Reset all parameters to default. */
3486 bgp_vrf
->evpn_info
->dup_addr_detect
= false;
3487 bgp_vrf
->evpn_info
->dad_time
= EVPN_DAD_DEFAULT_TIME
;
3488 bgp_vrf
->evpn_info
->dad_max_moves
= EVPN_DAD_DEFAULT_MAX_MOVES
;
3489 bgp_vrf
->evpn_info
->dad_freeze
= false;
3490 bgp_vrf
->evpn_info
->dad_freeze_time
= 0;
3493 if (bgp_vrf
->evpn_info
->dad_max_moves
!= max_moves
) {
3495 "%% Value does not match with config\n");
3498 bgp_vrf
->evpn_info
->dad_max_moves
=
3499 EVPN_DAD_DEFAULT_MAX_MOVES
;
3503 if (bgp_vrf
->evpn_info
->dad_time
!= time_val
) {
3505 "%% Value does not match with config\n");
3508 bgp_vrf
->evpn_info
->dad_time
= EVPN_DAD_DEFAULT_TIME
;
3512 if (bgp_vrf
->evpn_info
->dad_freeze_time
3515 "%% Value does not match with config\n");
3518 bgp_vrf
->evpn_info
->dad_freeze_time
= 0;
3519 bgp_vrf
->evpn_info
->dad_freeze
= false;
3522 if (permanent_val
) {
3523 if (bgp_vrf
->evpn_info
->dad_freeze_time
) {
3525 "%% Value does not match with config\n");
3528 bgp_vrf
->evpn_info
->dad_freeze
= false;
3532 bgp_zebra_dup_addr_detection(bgp_vrf
);
3537 DEFPY(bgp_evpn_advertise_svi_ip
,
3538 bgp_evpn_advertise_svi_ip_cmd
,
3539 "[no$no] advertise-svi-ip",
3541 "Advertise svi mac-ip routes in EVPN\n")
3543 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3548 if (!EVPN_ENABLED(bgp
)) {
3550 "This command is only supported under EVPN VRF\n");
3555 evpn_set_advertise_svi_macip(bgp
, NULL
, 0);
3557 evpn_set_advertise_svi_macip(bgp
, NULL
, 1);
3562 DEFPY(bgp_evpn_advertise_svi_ip_vni
,
3563 bgp_evpn_advertise_svi_ip_vni_cmd
,
3564 "[no$no] advertise-svi-ip",
3566 "Advertise svi mac-ip routes in EVPN for a VNI\n")
3568 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3569 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3575 evpn_set_advertise_svi_macip(bgp
, vpn
, 0);
3577 evpn_set_advertise_svi_macip(bgp
, vpn
, 1);
3582 DEFUN_HIDDEN (bgp_evpn_advertise_vni_subnet
,
3583 bgp_evpn_advertise_vni_subnet_cmd
,
3585 "Advertise the subnet corresponding to VNI\n")
3587 struct bgp
*bgp_vrf
= NULL
;
3588 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3589 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3594 bgp_vrf
= bgp_lookup_by_vrf_id(vpn
->tenant_vrf_id
);
3598 evpn_set_advertise_subnet(bgp
, vpn
);
3602 DEFUN_HIDDEN (no_bgp_evpn_advertise_vni_subnet
,
3603 no_bgp_evpn_advertise_vni_subnet_cmd
,
3604 "no advertise-subnet",
3606 "Advertise All local VNIs\n")
3608 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
3609 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
3614 evpn_unset_advertise_subnet(bgp
, vpn
);
3618 DEFUN (bgp_evpn_advertise_type5
,
3619 bgp_evpn_advertise_type5_cmd
,
3620 "advertise " BGP_AFI_CMD_STR
"" BGP_SAFI_CMD_STR
" [route-map WORD]",
3621 "Advertise prefix routes\n"
3624 "route-map for filtering specific routes\n"
3625 "Name of the route map\n")
3627 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
); /* bgp vrf instance */
3634 int rmap_changed
= 0;
3636 argv_find_and_parse_afi(argv
, argc
, &idx_afi
, &afi
);
3637 argv_find_and_parse_safi(argv
, argc
, &idx_safi
, &safi
);
3638 ret
= argv_find(argv
, argc
, "route-map", &idx_rmap
);
3640 if (!bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
)
3642 else if (strcmp(argv
[idx_rmap
+ 1]->arg
,
3643 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
)
3646 } else if (bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
) {
3650 if (!(afi
== AFI_IP
|| afi
== AFI_IP6
)) {
3652 "%%only ipv4 or ipv6 address families are supported");
3656 if (safi
!= SAFI_UNICAST
) {
3658 "%%only ipv4 unicast or ipv6 unicast are supported");
3662 if (afi
== AFI_IP
) {
3664 /* if we are already advertising ipv4 prefix as type-5
3667 if (!rmap_changed
&&
3668 CHECK_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3669 BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST
))
3671 SET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3672 BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST
);
3675 /* if we are already advertising ipv6 prefix as type-5
3678 if (!rmap_changed
&&
3679 CHECK_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3680 BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST
))
3682 SET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3683 BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST
);
3687 bgp_evpn_withdraw_type5_routes(bgp_vrf
, afi
, safi
);
3688 if (bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
) {
3689 XFREE(MTYPE_ROUTE_MAP_NAME
,
3690 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
);
3691 route_map_counter_decrement(
3692 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
);
3693 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
= NULL
;
3694 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
= NULL
;
3698 /* set the route-map for advertise command */
3699 if (ret
&& argv
[idx_rmap
+ 1]->arg
) {
3700 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
=
3701 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[idx_rmap
+ 1]->arg
);
3702 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
=
3703 route_map_lookup_by_name(argv
[idx_rmap
+ 1]->arg
);
3704 route_map_counter_increment(
3705 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
);
3708 /* advertise type-5 routes */
3709 if (advertise_type5_routes(bgp_vrf
, afi
))
3710 bgp_evpn_advertise_type5_routes(bgp_vrf
, afi
, safi
);
3714 DEFUN (no_bgp_evpn_advertise_type5
,
3715 no_bgp_evpn_advertise_type5_cmd
,
3716 "no advertise " BGP_AFI_CMD_STR
"" BGP_SAFI_CMD_STR
,
3718 "Advertise prefix routes\n"
3722 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
); /* bgp vrf instance */
3728 argv_find_and_parse_afi(argv
, argc
, &idx_afi
, &afi
);
3729 argv_find_and_parse_safi(argv
, argc
, &idx_safi
, &safi
);
3731 if (!(afi
== AFI_IP
|| afi
== AFI_IP6
)) {
3733 "%%only ipv4 or ipv6 address families are supported");
3737 if (safi
!= SAFI_UNICAST
) {
3739 "%%only ipv4 unicast or ipv6 unicast are supported");
3743 if (afi
== AFI_IP
) {
3745 /* if we are not advertising ipv4 prefix as type-5
3748 if (CHECK_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3749 BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST
)) {
3750 bgp_evpn_withdraw_type5_routes(bgp_vrf
, afi
, safi
);
3751 UNSET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3752 BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST
);
3756 /* if we are not advertising ipv6 prefix as type-5
3759 if (CHECK_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3760 BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST
)) {
3761 bgp_evpn_withdraw_type5_routes(bgp_vrf
, afi
, safi
);
3762 UNSET_FLAG(bgp_vrf
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
3763 BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST
);
3767 /* clear the route-map information for advertise ipv4/ipv6 unicast */
3768 if (bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
) {
3769 XFREE(MTYPE_ROUTE_MAP_NAME
,
3770 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
);
3771 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].name
= NULL
;
3772 bgp_vrf
->adv_cmd_rmap
[afi
][safi
].map
= NULL
;
3778 DEFPY (bgp_evpn_use_es_l3nhg
,
3779 bgp_evpn_use_es_l3nhg_cmd
,
3780 "[no$no] use-es-l3nhg",
3782 "use L3 nexthop group for host routes with ES destination\n")
3784 bgp_mh_info
->host_routes_use_l3nhg
= no
? false :true;
3788 DEFPY (bgp_evpn_ead_evi_rx_disable
,
3789 bgp_evpn_ead_evi_rx_disable_cmd
,
3790 "[no$no] disable-ead-evi-rx",
3792 "Activate PE on EAD-ES even if EAD-EVI is not received\n")
3794 bool ead_evi_rx
= no
? true :false;
3796 if (ead_evi_rx
!= bgp_mh_info
->ead_evi_rx
) {
3797 bgp_mh_info
->ead_evi_rx
= ead_evi_rx
;
3798 bgp_evpn_switch_ead_evi_rx();
3803 DEFPY (bgp_evpn_ead_evi_tx_disable
,
3804 bgp_evpn_ead_evi_tx_disable_cmd
,
3805 "[no$no] disable-ead-evi-tx",
3807 "Don't advertise EAD-EVI for local ESs\n")
3809 bgp_mh_info
->ead_evi_tx
= no
? true :false;
3813 DEFPY (bgp_evpn_advertise_pip_ip_mac
,
3814 bgp_evpn_advertise_pip_ip_mac_cmd
,
3815 "[no$no] advertise-pip [ip <A.B.C.D> [mac <X:X:X:X:X:X|X:X:X:X:X:X/M>]]",
3817 "evpn system primary IP\n"
3820 MAC_STR MAC_STR MAC_STR
)
3822 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
); /* bgp vrf instance */
3823 struct bgp
*bgp_evpn
= NULL
;
3825 if (EVPN_ENABLED(bgp_vrf
)) {
3827 "This command is supported under L3VNI BGP EVPN VRF\n");
3828 return CMD_WARNING_CONFIG_FAILED
;
3830 bgp_evpn
= bgp_get_evpn();
3833 /* pip is already enabled */
3834 if (argc
== 1 && bgp_vrf
->evpn_info
->advertise_pip
)
3837 bgp_vrf
->evpn_info
->advertise_pip
= true;
3838 if (ip
.s_addr
!= INADDR_ANY
) {
3839 /* Already configured with same IP */
3840 if (IPV4_ADDR_SAME(&ip
,
3841 &bgp_vrf
->evpn_info
->pip_ip_static
))
3844 bgp_vrf
->evpn_info
->pip_ip_static
= ip
;
3845 bgp_vrf
->evpn_info
->pip_ip
= ip
;
3847 bgp_vrf
->evpn_info
->pip_ip_static
.s_addr
3849 /* default instance router-id assignemt */
3851 bgp_vrf
->evpn_info
->pip_ip
=
3852 bgp_evpn
->router_id
;
3855 if (!is_zero_mac(&mac
->eth_addr
)) {
3856 /* Already configured with same MAC */
3857 if (memcmp(&bgp_vrf
->evpn_info
->pip_rmac_static
,
3858 &mac
->eth_addr
, ETH_ALEN
) == 0)
3861 memcpy(&bgp_vrf
->evpn_info
->pip_rmac_static
,
3862 &mac
->eth_addr
, ETH_ALEN
);
3863 memcpy(&bgp_vrf
->evpn_info
->pip_rmac
,
3864 &bgp_vrf
->evpn_info
->pip_rmac_static
,
3867 /* Copy zebra sys mac */
3868 if (!is_zero_mac(&bgp_vrf
->evpn_info
->pip_rmac_zebra
))
3869 memcpy(&bgp_vrf
->evpn_info
->pip_rmac
,
3870 &bgp_vrf
->evpn_info
->pip_rmac_zebra
,
3875 if (!bgp_vrf
->evpn_info
->advertise_pip
)
3877 /* Disable PIP feature */
3878 bgp_vrf
->evpn_info
->advertise_pip
= false;
3879 /* copy anycast mac */
3880 memcpy(&bgp_vrf
->evpn_info
->pip_rmac
,
3881 &bgp_vrf
->rmac
, ETH_ALEN
);
3883 /* remove MAC-IP option retain PIP knob. */
3884 if ((ip
.s_addr
!= INADDR_ANY
) &&
3885 !IPV4_ADDR_SAME(&ip
,
3886 &bgp_vrf
->evpn_info
->pip_ip_static
)) {
3888 "%% BGP EVPN PIP IP does not match\n");
3889 return CMD_WARNING_CONFIG_FAILED
;
3892 if (!is_zero_mac(&mac
->eth_addr
) &&
3893 memcmp(&bgp_vrf
->evpn_info
->pip_rmac_static
,
3894 &mac
->eth_addr
, ETH_ALEN
) != 0) {
3896 "%% BGP EVPN PIP MAC does not match\n");
3897 return CMD_WARNING_CONFIG_FAILED
;
3899 /* pip_rmac can carry vrr_rmac reset only if it matches
3900 * with static value.
3902 if (memcmp(&bgp_vrf
->evpn_info
->pip_rmac
,
3903 &bgp_vrf
->evpn_info
->pip_rmac_static
,
3905 /* Copy zebra sys mac */
3907 &bgp_vrf
->evpn_info
->pip_rmac_zebra
))
3908 memcpy(&bgp_vrf
->evpn_info
->pip_rmac
,
3909 &bgp_vrf
->evpn_info
->pip_rmac_zebra
,
3912 /* copy anycast mac */
3913 memcpy(&bgp_vrf
->evpn_info
->pip_rmac
,
3914 &bgp_vrf
->rmac
, ETH_ALEN
);
3918 /* reset user configured sys MAC */
3919 memset(&bgp_vrf
->evpn_info
->pip_rmac_static
, 0, ETH_ALEN
);
3920 /* reset user configured sys IP */
3921 bgp_vrf
->evpn_info
->pip_ip_static
.s_addr
= INADDR_ANY
;
3922 /* Assign default PIP IP (bgp instance router-id) */
3924 bgp_vrf
->evpn_info
->pip_ip
= bgp_evpn
->router_id
;
3926 bgp_vrf
->evpn_info
->pip_ip
.s_addr
= INADDR_ANY
;
3929 if (is_evpn_enabled()) {
3930 struct listnode
*node
= NULL
;
3931 struct bgpevpn
*vpn
= NULL
;
3934 * At this point if bgp_evpn is NULL and evpn is enabled
3935 * something stupid has gone wrong
3939 update_advertise_vrf_routes(bgp_vrf
);
3941 /* Update (svi) type-2 routes */
3942 for (ALL_LIST_ELEMENTS_RO(bgp_vrf
->l2vnis
, node
, vpn
)) {
3943 if (!bgp_evpn_is_svi_macip_enabled(vpn
))
3945 update_routes_for_vni(bgp_evpn
, vpn
);
3953 * Display VNI information - for all or a specific VNI
3955 DEFUN(show_bgp_l2vpn_evpn_vni
,
3956 show_bgp_l2vpn_evpn_vni_cmd
,
3957 "show bgp l2vpn evpn vni [" CMD_VNI_RANGE
"] [json]",
3966 struct bgp
*bgp_evpn
;
3970 json_object
*json
= NULL
;
3971 uint32_t num_l2vnis
= 0;
3972 uint32_t num_l3vnis
= 0;
3973 uint32_t num_vnis
= 0;
3974 struct listnode
*node
= NULL
;
3975 struct bgp
*bgp_temp
= NULL
;
3977 uj
= use_json(argc
, argv
);
3979 bgp_evpn
= bgp_get_evpn();
3983 if (!argv_find(argv
, argc
, "evpn", &idx
))
3987 json
= json_object_new_object();
3989 if ((uj
&& argc
== ((idx
+ 1) + 2)) || (!uj
&& argc
== (idx
+ 1) + 1)) {
3991 num_l2vnis
= hashcount(bgp_evpn
->vnihash
);
3993 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp_temp
)) {
3994 if (bgp_temp
->l3vni
)
3997 num_vnis
= num_l2vnis
+ num_l3vnis
;
3999 json_object_string_add(json
, "advertiseGatewayMacip",
4000 bgp_evpn
->advertise_gw_macip
4003 json_object_string_add(json
, "advertiseSviMacIp",
4004 bgp_evpn
->evpn_info
->advertise_svi_macip
4005 ? "Enabled" : "Disabled");
4006 json_object_string_add(json
, "advertiseAllVnis",
4007 is_evpn_enabled() ? "Enabled"
4009 json_object_string_add(
4011 bgp_evpn
->vxlan_flood_ctrl
4012 == VXLAN_FLOOD_HEAD_END_REPL
4013 ? "Head-end replication"
4015 json_object_int_add(json
, "numVnis", num_vnis
);
4016 json_object_int_add(json
, "numL2Vnis", num_l2vnis
);
4017 json_object_int_add(json
, "numL3Vnis", num_l3vnis
);
4019 vty_out(vty
, "Advertise Gateway Macip: %s\n",
4020 bgp_evpn
->advertise_gw_macip
? "Enabled"
4022 vty_out(vty
, "Advertise SVI Macip: %s\n",
4023 bgp_evpn
->evpn_info
->advertise_svi_macip
? "Enabled"
4025 vty_out(vty
, "Advertise All VNI flag: %s\n",
4026 is_evpn_enabled() ? "Enabled" : "Disabled");
4027 vty_out(vty
, "BUM flooding: %s\n",
4028 bgp_evpn
->vxlan_flood_ctrl
4029 == VXLAN_FLOOD_HEAD_END_REPL
4030 ? "Head-end replication"
4032 vty_out(vty
, "Number of L2 VNIs: %u\n", num_l2vnis
);
4033 vty_out(vty
, "Number of L3 VNIs: %u\n", num_l3vnis
);
4035 evpn_show_all_vnis(vty
, bgp_evpn
, json
);
4039 if (!argv_find(argv
, argc
, "vni", &vni_idx
))
4042 /* Display specific VNI */
4043 vni
= strtoul(argv
[vni_idx
+ 1]->arg
, NULL
, 10);
4044 evpn_show_vni(vty
, bgp_evpn
, vni
, json
);
4048 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4049 json
, JSON_C_TO_STRING_PRETTY
));
4050 json_object_free(json
);
4056 DEFPY(show_bgp_l2vpn_evpn_es_evi
,
4057 show_bgp_l2vpn_evpn_es_evi_cmd
,
4058 "show bgp l2vpn evpn es-evi [vni (1-16777215)$vni] [json$uj] [detail$detail]",
4064 "VxLAN Network Identifier\n"
4067 "Detailed information\n")
4070 bgp_evpn_es_evi_show_vni(vty
, vni
, !!uj
, !!detail
);
4072 bgp_evpn_es_evi_show(vty
, !!uj
, !!detail
);
4077 DEFPY(show_bgp_l2vpn_evpn_es
,
4078 show_bgp_l2vpn_evpn_es_cmd
,
4079 "show bgp l2vpn evpn es [NAME$esi_str|detail$detail] [json$uj]",
4084 "Ethernet Segment\n"
4086 "Detailed information\n"
4092 if (!str_to_esi(esi_str
, &esi
)) {
4093 vty_out(vty
, "%%Malformed ESI\n");
4096 bgp_evpn_es_show_esi(vty
, &esi
, uj
);
4099 bgp_evpn_es_show(vty
, uj
, !!detail
);
4105 DEFPY(show_bgp_l2vpn_evpn_es_vrf
, show_bgp_l2vpn_evpn_es_vrf_cmd
,
4106 "show bgp l2vpn evpn es-vrf [NAME$esi_str] [json$uj]",
4107 SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR
4108 "Ethernet Segment\n"
4114 if (!str_to_esi(esi_str
, &esi
)) {
4115 vty_out(vty
, "%%Malformed ESI\n");
4118 bgp_evpn_es_vrf_show_esi(vty
, &esi
, uj
);
4121 bgp_evpn_es_vrf_show(vty
, uj
, NULL
);
4127 DEFPY(show_bgp_l2vpn_evpn_nh
,
4128 show_bgp_l2vpn_evpn_nh_cmd
,
4129 "show bgp l2vpn evpn next-hops [json$uj]",
4137 bgp_evpn_nh_show(vty
, uj
);
4143 * Display EVPN neighbor summary.
4145 DEFUN(show_bgp_l2vpn_evpn_summary
,
4146 show_bgp_l2vpn_evpn_summary_cmd
,
4147 "show bgp [vrf VRFNAME] l2vpn evpn summary [established|failed] [wide] [json]",
4154 "Summary of BGP neighbor status\n"
4155 "Show only sessions in Established state\n"
4156 "Show only sessions not in Established state\n"
4157 "Increase table width for longer output\n"
4163 uint8_t show_flags
= 0;
4165 if (argv_find(argv
, argc
, "vrf", &idx_vrf
))
4166 vrf
= argv
[++idx_vrf
]->arg
;
4168 if (argv_find(argv
, argc
, "failed", &idx
))
4169 SET_FLAG(show_flags
, BGP_SHOW_OPT_FAILED
);
4171 if (argv_find(argv
, argc
, "established", &idx
))
4172 SET_FLAG(show_flags
, BGP_SHOW_OPT_ESTABLISHED
);
4174 if (argv_find(argv
, argc
, "wide", &idx
))
4175 SET_FLAG(show_flags
, BGP_SHOW_OPT_WIDE
);
4177 if (use_json(argc
, argv
))
4178 SET_FLAG(show_flags
, BGP_SHOW_OPT_JSON
);
4180 return bgp_show_summary_vty(vty
, vrf
, AFI_L2VPN
, SAFI_EVPN
, show_flags
);
4183 int bgp_evpn_cli_parse_type(int *type
, struct cmd_token
**argv
, int argc
)
4187 if (argv_find(argv
, argc
, "type", &type_idx
)) {
4188 /* Specific type is requested */
4189 if ((strncmp(argv
[type_idx
+ 1]->arg
, "ma", 2) == 0)
4190 || (strmatch(argv
[type_idx
+ 1]->arg
, "2")))
4191 *type
= BGP_EVPN_MAC_IP_ROUTE
;
4192 else if ((strncmp(argv
[type_idx
+ 1]->arg
, "mu", 2) == 0)
4193 || (strmatch(argv
[type_idx
+ 1]->arg
, "3")))
4194 *type
= BGP_EVPN_IMET_ROUTE
;
4195 else if ((strncmp(argv
[type_idx
+ 1]->arg
, "es", 2) == 0)
4196 || (strmatch(argv
[type_idx
+ 1]->arg
, "4")))
4197 *type
= BGP_EVPN_ES_ROUTE
;
4198 else if ((strncmp(argv
[type_idx
+ 1]->arg
, "ea", 2) == 0)
4199 || (strmatch(argv
[type_idx
+ 1]->arg
, "1")))
4200 *type
= BGP_EVPN_AD_ROUTE
;
4201 else if ((strncmp(argv
[type_idx
+ 1]->arg
, "p", 1) == 0)
4202 || (strmatch(argv
[type_idx
+ 1]->arg
, "5")))
4203 *type
= BGP_EVPN_IP_PREFIX_ROUTE
;
4212 * Display global EVPN routing table.
4214 DEFUN(show_bgp_l2vpn_evpn_route
,
4215 show_bgp_l2vpn_evpn_route_cmd
,
4216 "show bgp l2vpn evpn route [detail] [type "EVPN_TYPE_ALL_LIST
"] [json]",
4222 "Display Detailed Information\n"
4224 EVPN_TYPE_ALL_LIST_HELP_STR
4231 json_object
*json
= NULL
;
4233 uj
= use_json(argc
, argv
);
4235 bgp
= bgp_get_evpn();
4240 json
= json_object_new_object();
4242 if (bgp_evpn_cli_parse_type(&type
, argv
, argc
) < 0)
4245 if (argv_find(argv
, argc
, "detail", &detail
))
4248 evpn_show_all_routes(vty
, bgp
, type
, json
, detail
);
4251 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4252 json
, JSON_C_TO_STRING_PRETTY
));
4253 json_object_free(json
);
4259 * Display global EVPN routing table for specific RD.
4261 DEFUN(show_bgp_l2vpn_evpn_route_rd
,
4262 show_bgp_l2vpn_evpn_route_rd_cmd
,
4263 "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type "EVPN_TYPE_ALL_LIST
"] [json]",
4269 EVPN_RT_DIST_HELP_STR
4270 EVPN_ASN_IP_HELP_STR
4272 EVPN_TYPE_ALL_LIST_HELP_STR
4277 struct prefix_rd prd
;
4281 json_object
*json
= NULL
;
4283 bgp
= bgp_get_evpn();
4287 /* check if we need json output */
4288 uj
= use_json(argc
, argv
);
4290 json
= json_object_new_object();
4293 if (argv_find(argv
, argc
, "rd", &rd_idx
)) {
4294 ret
= str2prefix_rd(argv
[rd_idx
+ 1]->arg
, &prd
);
4297 vty_out(vty
, "%% Malformed Route Distinguisher\n");
4302 if (bgp_evpn_cli_parse_type(&type
, argv
, argc
) < 0)
4305 evpn_show_route_rd(vty
, bgp
, &prd
, type
, json
);
4308 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4309 json
, JSON_C_TO_STRING_PRETTY
));
4310 json_object_free(json
);
4317 * Display global EVPN routing table for specific RD and MACIP.
4319 DEFUN(show_bgp_l2vpn_evpn_route_rd_macip
,
4320 show_bgp_l2vpn_evpn_route_rd_macip_cmd
,
4321 "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD] [json]",
4327 EVPN_RT_DIST_HELP_STR
4328 EVPN_ASN_IP_HELP_STR
4330 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
4332 "IP address (IPv4 or IPv6)\n"
4337 struct prefix_rd prd
;
4344 json_object
*json
= NULL
;
4346 memset(&mac
, 0, sizeof(struct ethaddr
));
4347 memset(&ip
, 0, sizeof(struct ipaddr
));
4349 bgp
= bgp_get_evpn();
4353 /* check if we need json output */
4354 uj
= use_json(argc
, argv
);
4356 json
= json_object_new_object();
4359 if (argv_find(argv
, argc
, "rd", &rd_idx
)) {
4360 ret
= str2prefix_rd(argv
[rd_idx
+ 1]->arg
, &prd
);
4362 vty_out(vty
, "%% Malformed Route Distinguisher\n");
4368 if (argv_find(argv
, argc
, "mac", &mac_idx
)) {
4369 if (!prefix_str2mac(argv
[mac_idx
+ 1]->arg
, &mac
)) {
4370 vty_out(vty
, "%% Malformed MAC address\n");
4375 /* get the ip if specified */
4376 if (argv_find(argv
, argc
, "ip", &ip_idx
)) {
4377 if (str2ipaddr(argv
[ip_idx
+ 1]->arg
, &ip
) != 0) {
4378 vty_out(vty
, "%% Malformed IP address\n");
4383 evpn_show_route_rd_macip(vty
, bgp
, &prd
, &mac
, &ip
, json
);
4386 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4387 json
, JSON_C_TO_STRING_PRETTY
));
4388 json_object_free(json
);
4394 /* Display per ESI routing table */
4395 DEFUN(show_bgp_l2vpn_evpn_route_esi
,
4396 show_bgp_l2vpn_evpn_route_esi_cmd
,
4397 "show bgp l2vpn evpn route esi ESI [json]",
4403 "Ethernet Segment Identifier\n"
4409 struct bgp
*bgp
= NULL
;
4410 json_object
*json
= NULL
;
4412 memset(&esi
, 0, sizeof(esi
));
4413 bgp
= bgp_get_evpn();
4417 uj
= use_json(argc
, argv
);
4419 json
= json_object_new_object();
4421 /* get the ESI - ESI-ID is at argv[6] */
4422 if (!str_to_esi(argv
[6]->arg
, &esi
)) {
4423 vty_out(vty
, "%% Malformed ESI\n");
4427 evpn_show_routes_esi(vty
, bgp
, &esi
, json
);
4430 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4431 json
, JSON_C_TO_STRING_PRETTY
));
4432 json_object_free(json
);
4440 * Display per-VNI EVPN routing table.
4442 DEFUN(show_bgp_l2vpn_evpn_route_vni
, show_bgp_l2vpn_evpn_route_vni_cmd
,
4443 "show bgp l2vpn evpn route vni " CMD_VNI_RANGE
" [<type <ead|1|macip|2|multicast|3> | vtep A.B.C.D>] [json]",
4449 "VXLAN Network Identifier\n"
4452 EVPN_TYPE_1_HELP_STR
4453 EVPN_TYPE_1_HELP_STR
4454 EVPN_TYPE_2_HELP_STR
4455 EVPN_TYPE_2_HELP_STR
4456 EVPN_TYPE_3_HELP_STR
4457 EVPN_TYPE_3_HELP_STR
4459 "Remote VTEP IP address\n"
4464 struct in_addr vtep_ip
;
4469 json_object
*json
= NULL
;
4471 bgp
= bgp_get_evpn();
4475 /* check if we need json output */
4476 uj
= use_json(argc
, argv
);
4478 json
= json_object_new_object();
4480 if (!argv_find(argv
, argc
, "evpn", &idx
))
4485 vni
= strtoul(argv
[idx
+ 3]->arg
, NULL
, 10);
4487 if (bgp_evpn_cli_parse_type(&type
, argv
, argc
) < 0)
4490 if (argv_find(argv
, argc
, "vtep", &vtep_idx
)) {
4491 if (!inet_aton(argv
[vtep_idx
+ 1]->arg
, &vtep_ip
)) {
4492 vty_out(vty
, "%% Malformed VTEP IP address\n");
4497 evpn_show_routes_vni(vty
, bgp
, vni
, type
, vtep_ip
, json
);
4500 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4501 json
, JSON_C_TO_STRING_PRETTY
));
4502 json_object_free(json
);
4509 * Display per-VNI EVPN routing table for specific MACIP.
4511 DEFUN(show_bgp_l2vpn_evpn_route_vni_macip
,
4512 show_bgp_l2vpn_evpn_route_vni_macip_cmd
,
4513 "show bgp l2vpn evpn route vni " CMD_VNI_RANGE
" mac WORD [ip WORD] [json]",
4519 "VXLAN Network Identifier\n"
4522 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
4524 "IP address (IPv4 or IPv6)\n"
4533 json_object
*json
= NULL
;
4535 bgp
= bgp_get_evpn();
4539 /* check if we need json output */
4540 uj
= use_json(argc
, argv
);
4542 json
= json_object_new_object();
4544 if (!argv_find(argv
, argc
, "evpn", &idx
))
4548 vni
= strtoul(argv
[idx
+ 3]->arg
, NULL
, 10);
4551 if (!prefix_str2mac(argv
[idx
+ 5]->arg
, &mac
)) {
4552 vty_out(vty
, "%% Malformed MAC address\n");
4557 memset(&ip
, 0, sizeof(ip
));
4558 if ((!uj
&& ((argc
== (idx
+ 1 + 7)) && argv
[idx
+ 7]->arg
!= NULL
))
4560 && ((argc
== (idx
+ 1 + 8)) && argv
[idx
+ 7]->arg
!= NULL
))) {
4561 if (str2ipaddr(argv
[idx
+ 7]->arg
, &ip
) != 0) {
4562 vty_out(vty
, "%% Malformed IP address\n");
4567 evpn_show_route_vni_macip(vty
, bgp
, vni
, &mac
, &ip
, json
);
4570 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4571 json
, JSON_C_TO_STRING_PRETTY
));
4572 json_object_free(json
);
4579 * Display per-VNI EVPN routing table for specific multicast IP (remote VTEP).
4581 DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast
,
4582 show_bgp_l2vpn_evpn_route_vni_multicast_cmd
,
4583 "show bgp l2vpn evpn route vni " CMD_VNI_RANGE
" multicast A.B.C.D [json]",
4589 "VXLAN Network Identifier\n"
4591 EVPN_TYPE_3_HELP_STR
4592 "Originating Router IP address\n"
4598 struct in_addr orig_ip
;
4601 json_object
*json
= NULL
;
4603 bgp
= bgp_get_evpn();
4607 /* check if we need json output */
4608 uj
= use_json(argc
, argv
);
4610 json
= json_object_new_object();
4612 if (!argv_find(argv
, argc
, "evpn", &idx
))
4616 vni
= strtoul(argv
[idx
+ 3]->arg
, NULL
, 10);
4619 ret
= inet_aton(argv
[idx
+ 5]->arg
, &orig_ip
);
4621 vty_out(vty
, "%% Malformed Originating Router IP address\n");
4625 evpn_show_route_vni_multicast(vty
, bgp
, vni
, orig_ip
, json
);
4628 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4629 json
, JSON_C_TO_STRING_PRETTY
));
4630 json_object_free(json
);
4637 * Display per-VNI EVPN routing table - for all VNIs.
4639 DEFUN(show_bgp_l2vpn_evpn_route_vni_all
,
4640 show_bgp_l2vpn_evpn_route_vni_all_cmd
,
4641 "show bgp l2vpn evpn route vni all [detail] [vtep A.B.C.D] [json]",
4647 "VXLAN Network Identifier\n"
4649 "Print Detailed Output\n"
4651 "Remote VTEP IP address\n"
4655 struct in_addr vtep_ip
;
4658 json_object
*json
= NULL
;
4659 /* Detail Adjust. Adjust indexes according to detail option */
4662 bgp
= bgp_get_evpn();
4666 /* check if we need json output */
4667 uj
= use_json(argc
, argv
);
4669 json
= json_object_new_object();
4671 if (!argv_find(argv
, argc
, "evpn", &idx
))
4674 if (argv_find(argv
, argc
, "detail", &da
))
4677 /* vtep-ip position depends on detail option */
4679 if ((!uj
&& (argc
== (idx
+ 1 + 5 + da
) && argv
[idx
+ 5 + da
]->arg
))
4681 && (argc
== (idx
+ 1 + 6 + da
) && argv
[idx
+ 5 + da
]->arg
))) {
4682 if (!inet_aton(argv
[idx
+ 5 + da
]->arg
, &vtep_ip
)) {
4683 vty_out(vty
, "%% Malformed VTEP IP address\n");
4688 evpn_show_routes_vni_all(vty
, bgp
, vtep_ip
, json
, da
);
4691 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4692 json
, JSON_C_TO_STRING_PRETTY
));
4693 json_object_free(json
);
4700 show_bgp_l2vpn_evpn_route_mac_ip_evi_es
,
4701 show_bgp_l2vpn_evpn_route_mac_ip_evi_es_cmd
,
4702 "show bgp l2vpn evpn route mac-ip-evi-es [NAME$esi_str|detail$detail] [json$uj]",
4703 SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR
4704 "EVPN route information\n"
4705 "MAC IP routes in the EVI tables linked to the ES\n"
4707 "Detailed information\n" JSON_STR
)
4711 json_object
*json
= NULL
;
4714 if (!str_to_esi(esi_str
, &esi
)) {
4715 vty_out(vty
, "%%Malformed ESI\n");
4724 json
= json_object_new_object();
4725 bgp_evpn_show_routes_mac_ip_evi_es(vty
, esi_p
, json
, !!detail
);
4727 vty_out(vty
, "%s\n",
4728 json_object_to_json_string_ext(
4729 json
, JSON_C_TO_STRING_PRETTY
));
4730 json_object_free(json
);
4737 show_bgp_l2vpn_evpn_route_mac_ip_global_es
,
4738 show_bgp_l2vpn_evpn_route_mac_ip_global_es_cmd
,
4739 "show bgp l2vpn evpn route mac-ip-global-es [NAME$esi_str|detail$detail] [json$uj]",
4740 SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR
4741 "EVPN route information\n"
4742 "MAC IP routes in the global table linked to the ES\n"
4744 "Detailed information\n" JSON_STR
)
4748 json_object
*json
= NULL
;
4751 if (!str_to_esi(esi_str
, &esi
)) {
4752 vty_out(vty
, "%%Malformed ESI\n");
4761 json
= json_object_new_object();
4762 bgp_evpn_show_routes_mac_ip_global_es(vty
, esi_p
, json
, !!detail
);
4764 vty_out(vty
, "%s\n",
4765 json_object_to_json_string_ext(
4766 json
, JSON_C_TO_STRING_PRETTY
));
4767 json_object_free(json
);
4774 * Display EVPN import route-target hash table
4776 DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt
,
4777 show_bgp_l2vpn_evpn_vrf_import_rt_cmd
,
4778 "show bgp l2vpn evpn vrf-import-rt [json]",
4783 "Show vrf import route target\n"
4787 struct bgp
*bgp_evpn
= NULL
;
4788 json_object
*json
= NULL
;
4790 bgp_evpn
= bgp_get_evpn();
4794 uj
= use_json(argc
, argv
);
4796 json
= json_object_new_object();
4798 evpn_show_vrf_import_rts(vty
, bgp_evpn
, json
);
4801 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4802 json
, JSON_C_TO_STRING_PRETTY
));
4803 json_object_free(json
);
4810 * Display EVPN import route-target hash table
4812 DEFUN(show_bgp_l2vpn_evpn_import_rt
,
4813 show_bgp_l2vpn_evpn_import_rt_cmd
,
4814 "show bgp l2vpn evpn import-rt [json]",
4819 "Show import route target\n"
4824 json_object
*json
= NULL
;
4826 bgp
= bgp_get_evpn();
4830 uj
= use_json(argc
, argv
);
4832 json
= json_object_new_object();
4834 evpn_show_import_rts(vty
, bgp
, json
);
4837 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
4838 json
, JSON_C_TO_STRING_PRETTY
));
4839 json_object_free(json
);
4845 DEFPY_HIDDEN(test_es_add
,
4847 "[no$no] test es NAME$esi_str [state NAME$state_str]",
4850 "Ethernet-segment\n"
4851 "Ethernet-Segment Identifier\n"
4859 struct in_addr vtep_ip
;
4862 bgp
= bgp_get_evpn();
4864 vty_out(vty
, "%%EVPN BGP instance not yet created\n");
4868 if (!str_to_esi(esi_str
, &esi
)) {
4869 vty_out(vty
, "%%Malformed ESI\n");
4874 ret
= bgp_evpn_local_es_del(bgp
, &esi
);
4876 vty_out(vty
, "%%Failed to delete ES\n");
4880 if (state_str
&& !strcmp(state_str
, "up"))
4884 vtep_ip
= bgp
->router_id
;
4886 ret
= bgp_evpn_local_es_add(bgp
, &esi
, vtep_ip
, oper_up
,
4887 EVPN_MH_DF_PREF_MIN
, false);
4889 vty_out(vty
, "%%Failed to add ES\n");
4896 DEFPY_HIDDEN(test_es_vni_add
,
4897 test_es_vni_add_cmd
,
4898 "[no$no] test es NAME$esi_str vni (1-16777215)$vni",
4901 "Ethernet-segment\n"
4902 "Ethernet-Segment Identifier\n"
4911 bgp
= bgp_get_evpn();
4913 vty_out(vty
, "%%EVPN BGP instance not yet created\n");
4917 if (!str_to_esi(esi_str
, &esi
)) {
4918 vty_out(vty
, "%%Malformed ESI\n");
4923 ret
= bgp_evpn_local_es_evi_del(bgp
, &esi
, vni
);
4925 vty_out(vty
, "%%Failed to deref ES VNI\n");
4929 ret
= bgp_evpn_local_es_evi_add(bgp
, &esi
, vni
);
4931 vty_out(vty
, "%%Failed to ref ES VNI\n");
4938 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni
, show_bgp_evpn_vni_cmd
,
4939 "show bgp evpn vni [" CMD_VNI_RANGE
"]", SHOW_STR BGP_STR EVPN_HELP_STR
4943 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary
, show_bgp_evpn_summary_cmd
,
4944 "show bgp evpn summary [json]", SHOW_STR BGP_STR EVPN_HELP_STR
4945 "Summary of BGP neighbor status\n" JSON_STR
)
4947 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route
, show_bgp_evpn_route_cmd
,
4948 "show bgp evpn route [detail] [type <macip|2|multicast|3>]",
4949 SHOW_STR BGP_STR EVPN_HELP_STR
4951 "Display Detailed Information\n"
4953 EVPN_TYPE_2_HELP_STR
4954 EVPN_TYPE_2_HELP_STR
4955 EVPN_TYPE_3_HELP_STR
4956 EVPN_TYPE_3_HELP_STR
)
4959 show_bgp_l2vpn_evpn_route_rd
, show_bgp_evpn_route_rd_cmd
,
4960 "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|2|multicast|3>]",
4961 SHOW_STR BGP_STR EVPN_HELP_STR
4963 EVPN_RT_DIST_HELP_STR
4964 EVPN_ASN_IP_HELP_STR
4966 EVPN_TYPE_2_HELP_STR
4967 EVPN_TYPE_2_HELP_STR
4968 EVPN_TYPE_3_HELP_STR
4969 EVPN_TYPE_3_HELP_STR
)
4972 show_bgp_l2vpn_evpn_route_rd_macip
, show_bgp_evpn_route_rd_macip_cmd
,
4973 "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD]",
4974 SHOW_STR BGP_STR EVPN_HELP_STR
4976 EVPN_RT_DIST_HELP_STR
4977 EVPN_ASN_IP_HELP_STR
4979 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
4981 "IP address (IPv4 or IPv6)\n")
4984 show_bgp_l2vpn_evpn_route_vni
, show_bgp_evpn_route_vni_cmd
,
4985 "show bgp evpn route vni " CMD_VNI_RANGE
" [<type <macip|2|multicast|3> | vtep A.B.C.D>]",
4986 SHOW_STR BGP_STR EVPN_HELP_STR
4988 "VXLAN Network Identifier\n"
4991 EVPN_TYPE_2_HELP_STR
4992 EVPN_TYPE_2_HELP_STR
4993 EVPN_TYPE_3_HELP_STR
4994 EVPN_TYPE_3_HELP_STR
4996 "Remote VTEP IP address\n")
4998 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip
,
4999 show_bgp_evpn_route_vni_macip_cmd
,
5000 "show bgp evpn route vni " CMD_VNI_RANGE
" mac WORD [ip WORD]",
5001 SHOW_STR BGP_STR EVPN_HELP_STR
5003 "VXLAN Network Identifier\n"
5006 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
5008 "IP address (IPv4 or IPv6)\n")
5010 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast
,
5011 show_bgp_evpn_route_vni_multicast_cmd
,
5012 "show bgp evpn route vni " CMD_VNI_RANGE
" multicast A.B.C.D",
5013 SHOW_STR BGP_STR EVPN_HELP_STR
5015 "VXLAN Network Identifier\n"
5017 EVPN_TYPE_3_HELP_STR
5018 "Originating Router IP address\n")
5020 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all
, show_bgp_evpn_route_vni_all_cmd
,
5021 "show bgp evpn route vni all [detail] [vtep A.B.C.D]",
5022 SHOW_STR BGP_STR EVPN_HELP_STR
5024 "VXLAN Network Identifier\n"
5026 "Print Detailed Output\n"
5028 "Remote VTEP IP address\n")
5030 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_import_rt
, show_bgp_evpn_import_rt_cmd
,
5031 "show bgp evpn import-rt",
5032 SHOW_STR BGP_STR EVPN_HELP_STR
"Show import route target\n")
5034 DEFUN_NOSH (bgp_evpn_vni
,
5036 "vni " CMD_VNI_RANGE
,
5037 "VXLAN Network Identifier\n"
5041 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5042 struct bgpevpn
*vpn
;
5047 vni
= strtoul(argv
[1]->arg
, NULL
, 10);
5049 /* Create VNI, or mark as configured. */
5050 vpn
= evpn_create_update_vni(bgp
, vni
);
5052 vty_out(vty
, "%% Failed to create VNI \n");
5056 VTY_PUSH_CONTEXT_SUB(BGP_EVPN_VNI_NODE
, vpn
);
5060 DEFUN (no_bgp_evpn_vni
,
5061 no_bgp_evpn_vni_cmd
,
5062 "no vni " CMD_VNI_RANGE
,
5064 "VXLAN Network Identifier\n"
5068 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5069 struct bgpevpn
*vpn
;
5074 vni
= strtoul(argv
[2]->arg
, NULL
, 10);
5076 /* Check if we should disallow. */
5077 vpn
= bgp_evpn_lookup_vni(bgp
, vni
);
5079 vty_out(vty
, "%% Specified VNI does not exist\n");
5082 if (!is_vni_configured(vpn
)) {
5083 vty_out(vty
, "%% Specified VNI is not configured\n");
5087 evpn_delete_vni(bgp
, vpn
);
5091 DEFUN_NOSH (exit_vni
,
5094 "Exit from VNI mode\n")
5096 if (vty
->node
== BGP_EVPN_VNI_NODE
)
5097 vty
->node
= BGP_EVPN_NODE
;
5101 DEFUN (bgp_evpn_vrf_rd
,
5102 bgp_evpn_vrf_rd_cmd
,
5103 "rd ASN:NN_OR_IP-ADDRESS:NN",
5104 EVPN_RT_DIST_HELP_STR
5105 EVPN_ASN_IP_HELP_STR
)
5108 struct prefix_rd prd
;
5109 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
5114 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
5116 vty_out(vty
, "%% Malformed Route Distinguisher\n");
5120 /* If same as existing value, there is nothing more to do. */
5121 if (bgp_evpn_vrf_rd_matches_existing(bgp_vrf
, &prd
))
5124 /* Configure or update the RD. */
5125 evpn_configure_vrf_rd(bgp_vrf
, &prd
);
5129 DEFUN (no_bgp_evpn_vrf_rd
,
5130 no_bgp_evpn_vrf_rd_cmd
,
5131 "no rd ASN:NN_OR_IP-ADDRESS:NN",
5133 EVPN_RT_DIST_HELP_STR
5134 EVPN_ASN_IP_HELP_STR
)
5137 struct prefix_rd prd
;
5138 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
5143 ret
= str2prefix_rd(argv
[2]->arg
, &prd
);
5145 vty_out(vty
, "%% Malformed Route Distinguisher\n");
5149 /* Check if we should disallow. */
5150 if (!is_vrf_rd_configured(bgp_vrf
)) {
5151 vty_out(vty
, "%% RD is not configured for this VRF\n");
5155 if (!bgp_evpn_vrf_rd_matches_existing(bgp_vrf
, &prd
)) {
5157 "%% RD specified does not match configuration for this VRF\n");
5161 evpn_unconfigure_vrf_rd(bgp_vrf
);
5165 DEFUN (no_bgp_evpn_vrf_rd_without_val
,
5166 no_bgp_evpn_vrf_rd_without_val_cmd
,
5169 EVPN_RT_DIST_HELP_STR
)
5171 struct bgp
*bgp_vrf
= VTY_GET_CONTEXT(bgp
);
5176 /* Check if we should disallow. */
5177 if (!is_vrf_rd_configured(bgp_vrf
)) {
5178 vty_out(vty
, "%% RD is not configured for this VRF\n");
5182 evpn_unconfigure_vrf_rd(bgp_vrf
);
5186 DEFUN (bgp_evpn_vni_rd
,
5187 bgp_evpn_vni_rd_cmd
,
5188 "rd ASN:NN_OR_IP-ADDRESS:NN",
5189 EVPN_RT_DIST_HELP_STR
5190 EVPN_ASN_IP_HELP_STR
)
5192 struct prefix_rd prd
;
5193 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5194 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
5200 if (!EVPN_ENABLED(bgp
)) {
5202 "This command is only supported under EVPN VRF\n");
5206 ret
= str2prefix_rd(argv
[1]->arg
, &prd
);
5208 vty_out(vty
, "%% Malformed Route Distinguisher\n");
5212 /* If same as existing value, there is nothing more to do. */
5213 if (bgp_evpn_rd_matches_existing(vpn
, &prd
))
5216 /* Configure or update the RD. */
5217 evpn_configure_rd(bgp
, vpn
, &prd
);
5221 DEFUN (no_bgp_evpn_vni_rd
,
5222 no_bgp_evpn_vni_rd_cmd
,
5223 "no rd ASN:NN_OR_IP-ADDRESS:NN",
5225 EVPN_RT_DIST_HELP_STR
5226 EVPN_ASN_IP_HELP_STR
)
5228 struct prefix_rd prd
;
5229 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5230 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
5236 if (!EVPN_ENABLED(bgp
)) {
5238 "This command is only supported under EVPN VRF\n");
5242 ret
= str2prefix_rd(argv
[2]->arg
, &prd
);
5244 vty_out(vty
, "%% Malformed Route Distinguisher\n");
5248 /* Check if we should disallow. */
5249 if (!is_rd_configured(vpn
)) {
5250 vty_out(vty
, "%% RD is not configured for this VNI\n");
5254 if (!bgp_evpn_rd_matches_existing(vpn
, &prd
)) {
5256 "%% RD specified does not match configuration for this VNI\n");
5260 evpn_unconfigure_rd(bgp
, vpn
);
5264 DEFUN (no_bgp_evpn_vni_rd_without_val
,
5265 no_bgp_evpn_vni_rd_without_val_cmd
,
5268 EVPN_RT_DIST_HELP_STR
)
5270 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5271 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
5276 if (!EVPN_ENABLED(bgp
)) {
5278 "This command is only supported under EVPN VRF\n");
5282 /* Check if we should disallow. */
5283 if (!is_rd_configured(vpn
)) {
5284 vty_out(vty
, "%% RD is not configured for this VNI\n");
5288 evpn_unconfigure_rd(bgp
, vpn
);
5293 * Loop over all extended-communities in the route-target list rtl and
5294 * return 1 if we find ecomtarget
5296 static int bgp_evpn_rt_matches_existing(struct list
*rtl
,
5297 struct ecommunity
*ecomtarget
)
5299 struct listnode
*node
, *nnode
;
5300 struct ecommunity
*ecom
;
5302 for (ALL_LIST_ELEMENTS(rtl
, node
, nnode
, ecom
)) {
5303 if (ecommunity_match(ecom
, ecomtarget
))
5310 /* display L3VNI related info for a VRF instance */
5311 DEFUN (show_bgp_vrf_l3vni_info
,
5312 show_bgp_vrf_l3vni_info_cmd
,
5313 "show bgp vrf VRFNAME vni [json]",
5321 char buf
[ETHER_ADDR_STRLEN
];
5322 char buf1
[INET6_ADDRSTRLEN
];
5323 char originator_ip
[BUFSIZ
] = {0};
5325 const char *name
= NULL
;
5326 struct bgp
*bgp
= NULL
;
5327 struct listnode
*node
= NULL
;
5328 struct bgpevpn
*vpn
= NULL
;
5329 struct ecommunity
*ecom
= NULL
;
5330 json_object
*json
= NULL
;
5331 json_object
*json_vnis
= NULL
;
5332 json_object
*json_export_rts
= NULL
;
5333 json_object
*json_import_rts
= NULL
;
5334 bool uj
= use_json(argc
, argv
);
5337 json
= json_object_new_object();
5338 json_vnis
= json_object_new_array();
5339 json_export_rts
= json_object_new_array();
5340 json_import_rts
= json_object_new_array();
5343 name
= argv
[idx_vrf
]->arg
;
5344 bgp
= bgp_lookup_by_name(name
);
5347 vty_out(vty
, "BGP instance for VRF %s not found", name
);
5349 json_object_string_add(json
, "warning",
5350 "BGP instance not found");
5351 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
5352 json_object_free(json
);
5358 vty_out(vty
, "BGP VRF: %s\n", name
);
5359 vty_out(vty
, " Local-Ip: %pI4\n", &bgp
->originator_ip
);
5360 vty_out(vty
, " L3-VNI: %u\n", bgp
->l3vni
);
5361 vty_out(vty
, " Rmac: %s\n",
5362 prefix_mac2str(&bgp
->rmac
, buf
, sizeof(buf
)));
5363 vty_out(vty
, " VNI Filter: %s\n",
5364 CHECK_FLAG(bgp
->vrf_flags
,
5365 BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY
)
5366 ? "prefix-routes-only"
5368 vty_out(vty
, " L2-VNI List:\n");
5370 for (ALL_LIST_ELEMENTS_RO(bgp
->l2vnis
, node
, vpn
))
5371 vty_out(vty
, "%u ", vpn
->vni
);
5373 vty_out(vty
, " Export-RTs:\n");
5375 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_export_rtl
, node
, ecom
))
5376 vty_out(vty
, "%s ", ecommunity_str(ecom
));
5378 vty_out(vty
, " Import-RTs:\n");
5380 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_import_rtl
, node
, ecom
))
5381 vty_out(vty
, "%s ", ecommunity_str(ecom
));
5383 vty_out(vty
, " RD: %s\n",
5384 prefix_rd2str(&bgp
->vrf_prd
, buf1
, RD_ADDRSTRLEN
));
5386 json_object_string_add(json
, "vrf", name
);
5387 json_object_string_add(json
, "local-ip",
5388 inet_ntop(AF_INET
, &bgp
->originator_ip
,
5390 sizeof(originator_ip
)));
5391 json_object_int_add(json
, "l3vni", bgp
->l3vni
);
5392 json_object_string_add(
5394 prefix_mac2str(&bgp
->rmac
, buf
, sizeof(buf
)));
5395 json_object_string_add(
5397 CHECK_FLAG(bgp
->vrf_flags
,
5398 BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY
)
5399 ? "prefix-routes-only"
5401 /* list of l2vnis */
5402 for (ALL_LIST_ELEMENTS_RO(bgp
->l2vnis
, node
, vpn
))
5403 json_object_array_add(json_vnis
,
5404 json_object_new_int(vpn
->vni
));
5405 json_object_object_add(json
, "l2vnis", json_vnis
);
5408 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_export_rtl
, node
, ecom
))
5409 json_object_array_add(
5411 json_object_new_string(ecommunity_str(ecom
)));
5412 json_object_object_add(json
, "export-rts", json_export_rts
);
5415 for (ALL_LIST_ELEMENTS_RO(bgp
->vrf_import_rtl
, node
, ecom
))
5416 json_object_array_add(
5418 json_object_new_string(ecommunity_str(ecom
)));
5419 json_object_object_add(json
, "import-rts", json_import_rts
);
5420 json_object_string_add(
5422 prefix_rd2str(&bgp
->vrf_prd
, buf1
, RD_ADDRSTRLEN
));
5426 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
5427 json
, JSON_C_TO_STRING_PRETTY
));
5428 json_object_free(json
);
5433 /* import/export rt for l3vni-vrf */
5434 DEFUN (bgp_evpn_vrf_rt
,
5435 bgp_evpn_vrf_rt_cmd
,
5436 "route-target <both|import|export> RT",
5438 "import and export\n"
5441 "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
5444 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5445 struct ecommunity
*ecomadd
= NULL
;
5450 if (!strcmp(argv
[1]->arg
, "import"))
5451 rt_type
= RT_TYPE_IMPORT
;
5452 else if (!strcmp(argv
[1]->arg
, "export"))
5453 rt_type
= RT_TYPE_EXPORT
;
5454 else if (!strcmp(argv
[1]->arg
, "both"))
5455 rt_type
= RT_TYPE_BOTH
;
5457 vty_out(vty
, "%% Invalid Route Target type\n");
5461 /* Add/update the import route-target */
5462 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_IMPORT
) {
5463 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
5464 ECOMMUNITY_ROUTE_TARGET
, 0);
5466 vty_out(vty
, "%% Malformed Route Target list\n");
5469 ecommunity_str(ecomadd
);
5471 /* Do nothing if we already have this import route-target */
5472 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_import_rtl
, ecomadd
))
5473 bgp_evpn_configure_import_rt_for_vrf(bgp
, ecomadd
);
5476 /* Add/update the export route-target */
5477 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_EXPORT
) {
5478 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
5479 ECOMMUNITY_ROUTE_TARGET
, 0);
5481 vty_out(vty
, "%% Malformed Route Target list\n");
5484 ecommunity_str(ecomadd
);
5486 /* Do nothing if we already have this export route-target */
5487 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_export_rtl
, ecomadd
))
5488 bgp_evpn_configure_export_rt_for_vrf(bgp
, ecomadd
);
5494 DEFUN (no_bgp_evpn_vrf_rt
,
5495 no_bgp_evpn_vrf_rt_cmd
,
5496 "no route-target <both|import|export> RT",
5499 "import and export\n"
5502 EVPN_ASN_IP_HELP_STR
)
5504 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5505 int rt_type
, found_ecomdel
;
5506 struct ecommunity
*ecomdel
= NULL
;
5511 if (!strcmp(argv
[2]->arg
, "import"))
5512 rt_type
= RT_TYPE_IMPORT
;
5513 else if (!strcmp(argv
[2]->arg
, "export"))
5514 rt_type
= RT_TYPE_EXPORT
;
5515 else if (!strcmp(argv
[2]->arg
, "both"))
5516 rt_type
= RT_TYPE_BOTH
;
5518 vty_out(vty
, "%% Invalid Route Target type\n");
5522 if (rt_type
== RT_TYPE_IMPORT
) {
5523 if (!CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
)) {
5525 "%% Import RT is not configured for this VRF\n");
5528 } else if (rt_type
== RT_TYPE_EXPORT
) {
5529 if (!CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
)) {
5531 "%% Export RT is not configured for this VRF\n");
5534 } else if (rt_type
== RT_TYPE_BOTH
) {
5535 if (!CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
)
5536 && !CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
)) {
5538 "%% Import/Export RT is not configured for this VRF\n");
5543 ecomdel
= ecommunity_str2com(argv
[3]->arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
5545 vty_out(vty
, "%% Malformed Route Target list\n");
5548 ecommunity_str(ecomdel
);
5550 if (rt_type
== RT_TYPE_IMPORT
) {
5551 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_import_rtl
,
5553 ecommunity_free(&ecomdel
);
5555 "%% RT specified does not match configuration for this VRF\n");
5558 bgp_evpn_unconfigure_import_rt_for_vrf(bgp
, ecomdel
);
5559 } else if (rt_type
== RT_TYPE_EXPORT
) {
5560 if (!bgp_evpn_rt_matches_existing(bgp
->vrf_export_rtl
,
5562 ecommunity_free(&ecomdel
);
5564 "%% RT specified does not match configuration for this VRF\n");
5567 bgp_evpn_unconfigure_export_rt_for_vrf(bgp
, ecomdel
);
5568 } else if (rt_type
== RT_TYPE_BOTH
) {
5571 if (bgp_evpn_rt_matches_existing(bgp
->vrf_import_rtl
,
5573 bgp_evpn_unconfigure_import_rt_for_vrf(bgp
, ecomdel
);
5577 if (bgp_evpn_rt_matches_existing(bgp
->vrf_export_rtl
,
5579 bgp_evpn_unconfigure_export_rt_for_vrf(bgp
, ecomdel
);
5583 if (!found_ecomdel
) {
5584 ecommunity_free(&ecomdel
);
5586 "%% RT specified does not match configuration for this VRF\n");
5591 ecommunity_free(&ecomdel
);
5595 DEFUN (bgp_evpn_vni_rt
,
5596 bgp_evpn_vni_rt_cmd
,
5597 "route-target <both|import|export> RT",
5599 "import and export\n"
5602 "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
5604 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5605 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
5607 struct ecommunity
*ecomadd
= NULL
;
5612 if (!EVPN_ENABLED(bgp
)) {
5614 "This command is only supported under EVPN VRF\n");
5618 if (!strcmp(argv
[1]->text
, "import"))
5619 rt_type
= RT_TYPE_IMPORT
;
5620 else if (!strcmp(argv
[1]->text
, "export"))
5621 rt_type
= RT_TYPE_EXPORT
;
5622 else if (!strcmp(argv
[1]->text
, "both"))
5623 rt_type
= RT_TYPE_BOTH
;
5625 vty_out(vty
, "%% Invalid Route Target type\n");
5629 /* Add/update the import route-target */
5630 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_IMPORT
) {
5631 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
5632 ECOMMUNITY_ROUTE_TARGET
, 0);
5634 vty_out(vty
, "%% Malformed Route Target list\n");
5637 ecommunity_str(ecomadd
);
5639 /* Do nothing if we already have this import route-target */
5640 if (!bgp_evpn_rt_matches_existing(vpn
->import_rtl
, ecomadd
))
5641 evpn_configure_import_rt(bgp
, vpn
, ecomadd
);
5644 /* Add/update the export route-target */
5645 if (rt_type
== RT_TYPE_BOTH
|| rt_type
== RT_TYPE_EXPORT
) {
5646 ecomadd
= ecommunity_str2com(argv
[2]->arg
,
5647 ECOMMUNITY_ROUTE_TARGET
, 0);
5649 vty_out(vty
, "%% Malformed Route Target list\n");
5652 ecommunity_str(ecomadd
);
5654 /* Do nothing if we already have this export route-target */
5655 if (!bgp_evpn_rt_matches_existing(vpn
->export_rtl
, ecomadd
))
5656 evpn_configure_export_rt(bgp
, vpn
, ecomadd
);
5662 DEFUN (no_bgp_evpn_vni_rt
,
5663 no_bgp_evpn_vni_rt_cmd
,
5664 "no route-target <both|import|export> RT",
5667 "import and export\n"
5670 EVPN_ASN_IP_HELP_STR
)
5672 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5673 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
5674 int rt_type
, found_ecomdel
;
5675 struct ecommunity
*ecomdel
= NULL
;
5680 if (!EVPN_ENABLED(bgp
)) {
5682 "This command is only supported under EVPN VRF\n");
5686 if (!strcmp(argv
[2]->text
, "import"))
5687 rt_type
= RT_TYPE_IMPORT
;
5688 else if (!strcmp(argv
[2]->text
, "export"))
5689 rt_type
= RT_TYPE_EXPORT
;
5690 else if (!strcmp(argv
[2]->text
, "both"))
5691 rt_type
= RT_TYPE_BOTH
;
5693 vty_out(vty
, "%% Invalid Route Target type\n");
5697 /* The user did "no route-target import", check to see if there are any
5698 * import route-targets configured. */
5699 if (rt_type
== RT_TYPE_IMPORT
) {
5700 if (!is_import_rt_configured(vpn
)) {
5702 "%% Import RT is not configured for this VNI\n");
5705 } else if (rt_type
== RT_TYPE_EXPORT
) {
5706 if (!is_export_rt_configured(vpn
)) {
5708 "%% Export RT is not configured for this VNI\n");
5711 } else if (rt_type
== RT_TYPE_BOTH
) {
5712 if (!is_import_rt_configured(vpn
)
5713 && !is_export_rt_configured(vpn
)) {
5715 "%% Import/Export RT is not configured for this VNI\n");
5720 ecomdel
= ecommunity_str2com(argv
[3]->arg
, ECOMMUNITY_ROUTE_TARGET
, 0);
5722 vty_out(vty
, "%% Malformed Route Target list\n");
5725 ecommunity_str(ecomdel
);
5727 if (rt_type
== RT_TYPE_IMPORT
) {
5728 if (!bgp_evpn_rt_matches_existing(vpn
->import_rtl
, ecomdel
)) {
5730 "%% RT specified does not match configuration for this VNI\n");
5733 evpn_unconfigure_import_rt(bgp
, vpn
, ecomdel
);
5734 } else if (rt_type
== RT_TYPE_EXPORT
) {
5735 if (!bgp_evpn_rt_matches_existing(vpn
->export_rtl
, ecomdel
)) {
5737 "%% RT specified does not match configuration for this VNI\n");
5740 evpn_unconfigure_export_rt(bgp
, vpn
, ecomdel
);
5741 } else if (rt_type
== RT_TYPE_BOTH
) {
5744 if (bgp_evpn_rt_matches_existing(vpn
->import_rtl
, ecomdel
)) {
5745 evpn_unconfigure_import_rt(bgp
, vpn
, ecomdel
);
5749 if (bgp_evpn_rt_matches_existing(vpn
->export_rtl
, ecomdel
)) {
5750 evpn_unconfigure_export_rt(bgp
, vpn
, ecomdel
);
5754 if (!found_ecomdel
) {
5756 "%% RT specified does not match configuration for this VNI\n");
5764 DEFUN (no_bgp_evpn_vni_rt_without_val
,
5765 no_bgp_evpn_vni_rt_without_val_cmd
,
5766 "no route-target <import|export>",
5772 struct bgp
*bgp
= VTY_GET_CONTEXT(bgp
);
5773 VTY_DECLVAR_CONTEXT_SUB(bgpevpn
, vpn
);
5779 if (!EVPN_ENABLED(bgp
)) {
5781 "This command is only supported under EVPN VRF\n");
5785 if (!strcmp(argv
[2]->text
, "import")) {
5786 rt_type
= RT_TYPE_IMPORT
;
5787 } else if (!strcmp(argv
[2]->text
, "export")) {
5788 rt_type
= RT_TYPE_EXPORT
;
5790 vty_out(vty
, "%% Invalid Route Target type\n");
5794 /* Check if we should disallow. */
5795 if (rt_type
== RT_TYPE_IMPORT
) {
5796 if (!is_import_rt_configured(vpn
)) {
5798 "%% Import RT is not configured for this VNI\n");
5802 if (!is_export_rt_configured(vpn
)) {
5804 "%% Export RT is not configured for this VNI\n");
5809 /* Unconfigure the RT. */
5810 if (rt_type
== RT_TYPE_IMPORT
)
5811 evpn_unconfigure_import_rt(bgp
, vpn
, NULL
);
5813 evpn_unconfigure_export_rt(bgp
, vpn
, NULL
);
5817 static int vni_cmp(const void **a
, const void **b
)
5819 const struct bgpevpn
*first
= *a
;
5820 const struct bgpevpn
*secnd
= *b
;
5822 return secnd
->vni
- first
->vni
;
5826 * Output EVPN configuration information.
5828 void bgp_config_write_evpn_info(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5831 char buf1
[RD_ADDRSTRLEN
];
5832 char buf2
[INET6_ADDRSTRLEN
];
5834 if (bgp
->advertise_all_vni
)
5835 vty_out(vty
, " advertise-all-vni\n");
5838 struct list
*vnilist
= hash_to_list(bgp
->vnihash
);
5839 struct listnode
*ln
;
5840 struct bgpevpn
*data
;
5842 list_sort(vnilist
, vni_cmp
);
5843 for (ALL_LIST_ELEMENTS_RO(vnilist
, ln
, data
))
5844 write_vni_config(vty
, data
);
5846 list_delete(&vnilist
);
5849 if (bgp
->advertise_autort_rfc8365
)
5850 vty_out(vty
, " autort rfc8365-compatible\n");
5852 if (bgp
->advertise_gw_macip
)
5853 vty_out(vty
, " advertise-default-gw\n");
5855 if (bgp
->evpn_info
->advertise_svi_macip
)
5856 vty_out(vty
, " advertise-svi-ip\n");
5858 if (bgp_mh_info
->host_routes_use_l3nhg
!=
5859 BGP_EVPN_MH_USE_ES_L3NHG_DEF
) {
5860 if (bgp_mh_info
->host_routes_use_l3nhg
)
5861 vty_out(vty
, " use-es-l3nhg\n");
5863 vty_out(vty
, " no use-es-l3nhg\n");
5866 if (bgp_mh_info
->ead_evi_rx
!= BGP_EVPN_MH_EAD_EVI_RX_DEF
) {
5867 if (bgp_mh_info
->ead_evi_rx
)
5868 vty_out(vty
, " no disable-ead-evi-rx\n");
5870 vty_out(vty
, " disable-ead-evi-rx\n");
5873 if (bgp_mh_info
->ead_evi_tx
!= BGP_EVPN_MH_EAD_EVI_TX_DEF
) {
5874 if (bgp_mh_info
->ead_evi_tx
)
5875 vty_out(vty
, " no disable-ead-evi-tx\n");
5877 vty_out(vty
, " disable-ead-evi-tx\n");
5880 if (!bgp
->evpn_info
->dup_addr_detect
)
5881 vty_out(vty
, " no dup-addr-detection\n");
5883 if (bgp
->evpn_info
->dad_max_moves
!=
5884 EVPN_DAD_DEFAULT_MAX_MOVES
||
5885 bgp
->evpn_info
->dad_time
!= EVPN_DAD_DEFAULT_TIME
)
5886 vty_out(vty
, " dup-addr-detection max-moves %u time %u\n",
5887 bgp
->evpn_info
->dad_max_moves
,
5888 bgp
->evpn_info
->dad_time
);
5890 if (bgp
->evpn_info
->dad_freeze
) {
5891 if (bgp
->evpn_info
->dad_freeze_time
)
5893 " dup-addr-detection freeze %u\n",
5894 bgp
->evpn_info
->dad_freeze_time
);
5897 " dup-addr-detection freeze permanent\n");
5900 if (bgp
->vxlan_flood_ctrl
== VXLAN_FLOOD_DISABLED
)
5901 vty_out(vty
, " flooding disable\n");
5903 if (CHECK_FLAG(bgp
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
5904 BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST
)) {
5905 if (bgp
->adv_cmd_rmap
[AFI_IP
][SAFI_UNICAST
].name
)
5906 vty_out(vty
, " advertise ipv4 unicast route-map %s\n",
5907 bgp
->adv_cmd_rmap
[AFI_IP
][SAFI_UNICAST
].name
);
5909 vty_out(vty
, " advertise ipv4 unicast\n");
5912 if (CHECK_FLAG(bgp
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
5913 BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST
)) {
5914 if (bgp
->adv_cmd_rmap
[AFI_IP6
][SAFI_UNICAST
].name
)
5915 vty_out(vty
, " advertise ipv6 unicast route-map %s\n",
5916 bgp
->adv_cmd_rmap
[AFI_IP6
][SAFI_UNICAST
].name
);
5918 vty_out(vty
, " advertise ipv6 unicast\n");
5921 if (CHECK_FLAG(bgp
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
5922 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4
))
5923 vty_out(vty
, " default-originate ipv4\n");
5925 if (CHECK_FLAG(bgp
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
5926 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6
))
5927 vty_out(vty
, " default-originate ipv6\n");
5929 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
5930 if (!bgp
->evpn_info
->advertise_pip
)
5931 vty_out(vty
, " no advertise-pip\n");
5932 if (bgp
->evpn_info
->advertise_pip
) {
5933 if (bgp
->evpn_info
->pip_ip_static
.s_addr
5935 vty_out(vty
, " advertise-pip ip %s",
5937 &bgp
->evpn_info
->pip_ip_static
,
5938 buf2
, INET_ADDRSTRLEN
));
5940 bgp
->evpn_info
->pip_rmac_static
))) {
5941 char buf
[ETHER_ADDR_STRLEN
];
5943 vty_out(vty
, " mac %s",
5953 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_RD_CFGD
))
5954 vty_out(vty
, " rd %s\n",
5955 prefix_rd2str(&bgp
->vrf_prd
, buf1
, sizeof(buf1
)));
5957 /* import route-target */
5958 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_IMPORT_RT_CFGD
)) {
5960 struct listnode
*node
, *nnode
;
5961 struct ecommunity
*ecom
;
5963 for (ALL_LIST_ELEMENTS(bgp
->vrf_import_rtl
, node
, nnode
,
5965 ecom_str
= ecommunity_ecom2str(
5966 ecom
, ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
5967 vty_out(vty
, " route-target import %s\n", ecom_str
);
5968 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
5972 /* export route-target */
5973 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_EXPORT_RT_CFGD
)) {
5975 struct listnode
*node
, *nnode
;
5976 struct ecommunity
*ecom
;
5978 for (ALL_LIST_ELEMENTS(bgp
->vrf_export_rtl
, node
, nnode
,
5980 ecom_str
= ecommunity_ecom2str(
5981 ecom
, ECOMMUNITY_FORMAT_ROUTE_MAP
, 0);
5982 vty_out(vty
, " route-target export %s\n", ecom_str
);
5983 XFREE(MTYPE_ECOMMUNITY_STR
, ecom_str
);
5988 void bgp_ethernetvpn_init(void)
5990 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_cmd
);
5991 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_rd_cmd
);
5992 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_tags_cmd
);
5993 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd
);
5994 install_element(VIEW_NODE
,
5995 &show_ip_bgp_l2vpn_evpn_neighbor_routes_cmd
);
5996 install_element(VIEW_NODE
,
5997 &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd
);
6000 &show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes_cmd
);
6003 &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd
);
6004 install_element(VIEW_NODE
, &show_ip_bgp_evpn_rd_overlay_cmd
);
6005 install_element(VIEW_NODE
, &show_ip_bgp_l2vpn_evpn_all_overlay_cmd
);
6006 install_element(BGP_EVPN_NODE
, &no_evpnrt5_network_cmd
);
6007 install_element(BGP_EVPN_NODE
, &evpnrt5_network_cmd
);
6008 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_all_vni_cmd
);
6009 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_all_vni_cmd
);
6010 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_autort_rfc8365_cmd
);
6011 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_autort_rfc8365_cmd
);
6012 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_default_gw_cmd
);
6013 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_default_gw_cmd
);
6014 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_svi_ip_cmd
);
6015 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_type5_cmd
);
6016 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_advertise_type5_cmd
);
6017 install_element(BGP_EVPN_NODE
, &bgp_evpn_default_originate_cmd
);
6018 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_default_originate_cmd
);
6019 install_element(BGP_EVPN_NODE
, &dup_addr_detection_cmd
);
6020 install_element(BGP_EVPN_NODE
, &dup_addr_detection_auto_recovery_cmd
);
6021 install_element(BGP_EVPN_NODE
, &no_dup_addr_detection_cmd
);
6022 install_element(BGP_EVPN_NODE
, &bgp_evpn_flood_control_cmd
);
6023 install_element(BGP_EVPN_NODE
, &bgp_evpn_advertise_pip_ip_mac_cmd
);
6024 install_element(BGP_EVPN_NODE
, &bgp_evpn_use_es_l3nhg_cmd
);
6025 install_element(BGP_EVPN_NODE
, &bgp_evpn_ead_evi_rx_disable_cmd
);
6026 install_element(BGP_EVPN_NODE
, &bgp_evpn_ead_evi_tx_disable_cmd
);
6029 install_element(BGP_EVPN_NODE
, &test_es_add_cmd
);
6030 install_element(BGP_EVPN_NODE
, &test_es_vni_add_cmd
);
6032 /* "show bgp l2vpn evpn" commands. */
6033 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_es_cmd
);
6034 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_es_evi_cmd
);
6035 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_es_vrf_cmd
);
6036 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_nh_cmd
);
6037 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_vni_cmd
);
6038 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_summary_cmd
);
6039 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_cmd
);
6040 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_rd_cmd
);
6041 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_rd_macip_cmd
);
6042 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_esi_cmd
);
6043 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vni_cmd
);
6044 install_element(VIEW_NODE
,
6045 &show_bgp_l2vpn_evpn_route_vni_multicast_cmd
);
6046 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vni_macip_cmd
);
6047 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_route_vni_all_cmd
);
6048 install_element(VIEW_NODE
,
6049 &show_bgp_l2vpn_evpn_route_mac_ip_evi_es_cmd
);
6050 install_element(VIEW_NODE
,
6051 &show_bgp_l2vpn_evpn_route_mac_ip_global_es_cmd
);
6052 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_import_rt_cmd
);
6053 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_vrf_import_rt_cmd
);
6055 /* "show bgp evpn" commands. */
6056 install_element(VIEW_NODE
, &show_bgp_evpn_vni_cmd
);
6057 install_element(VIEW_NODE
, &show_bgp_evpn_summary_cmd
);
6058 install_element(VIEW_NODE
, &show_bgp_evpn_route_cmd
);
6059 install_element(VIEW_NODE
, &show_bgp_evpn_route_rd_cmd
);
6060 install_element(VIEW_NODE
, &show_bgp_evpn_route_rd_macip_cmd
);
6061 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_cmd
);
6062 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_multicast_cmd
);
6063 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_macip_cmd
);
6064 install_element(VIEW_NODE
, &show_bgp_evpn_route_vni_all_cmd
);
6065 install_element(VIEW_NODE
, &show_bgp_evpn_import_rt_cmd
);
6066 install_element(VIEW_NODE
, &show_bgp_vrf_l3vni_info_cmd
);
6067 install_element(VIEW_NODE
, &show_bgp_l2vpn_evpn_com_cmd
);
6069 install_element(BGP_EVPN_NODE
, &bgp_evpn_vni_cmd
);
6070 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_vni_cmd
);
6071 install_element(BGP_EVPN_VNI_NODE
, &exit_vni_cmd
);
6072 install_element(BGP_EVPN_VNI_NODE
, &bgp_evpn_vni_rd_cmd
);
6073 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rd_cmd
);
6074 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rd_without_val_cmd
);
6075 install_element(BGP_EVPN_VNI_NODE
, &bgp_evpn_vni_rt_cmd
);
6076 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rt_cmd
);
6077 install_element(BGP_EVPN_VNI_NODE
, &no_bgp_evpn_vni_rt_without_val_cmd
);
6078 install_element(BGP_EVPN_NODE
, &bgp_evpn_vrf_rd_cmd
);
6079 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_vrf_rd_cmd
);
6080 install_element(BGP_NODE
, &no_bgp_evpn_vrf_rd_without_val_cmd
);
6081 install_element(BGP_EVPN_NODE
, &bgp_evpn_vrf_rt_cmd
);
6082 install_element(BGP_EVPN_NODE
, &no_bgp_evpn_vrf_rt_cmd
);
6083 install_element(BGP_EVPN_VNI_NODE
, &bgp_evpn_advertise_svi_ip_vni_cmd
);
6084 install_element(BGP_EVPN_VNI_NODE
,
6085 &bgp_evpn_advertise_default_gw_vni_cmd
);
6086 install_element(BGP_EVPN_VNI_NODE
,
6087 &no_bgp_evpn_advertise_default_gw_vni_cmd
);
6088 install_element(BGP_EVPN_VNI_NODE
, &bgp_evpn_advertise_vni_subnet_cmd
);
6089 install_element(BGP_EVPN_VNI_NODE
,
6090 &no_bgp_evpn_advertise_vni_subnet_cmd
);