]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_evpn_vty.c
Merge pull request #10558 from Jafaral/ospf-net-or-iface
[mirror_frr.git] / bgpd / bgp_evpn_vty.c
CommitLineData
784d3a42 1/* Ethernet-VPN Packet and vty Processing File
896014f4
DL
2 * Copyright (C) 2017 6WIND
3 *
4 * This file is part of FRRouting
5 *
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
9 * later version.
10 *
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.
15 *
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
19 */
784d3a42
PG
20
21#include <zebra.h>
22#include "command.h"
23#include "prefix.h"
24#include "lib/json.h"
23d0a753 25#include "lib/printfrr.h"
74e2bd89 26#include "lib/vxlan.h"
937652c6 27#include "stream.h"
784d3a42
PG
28
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"
3da6fcd5 36#include "bgpd/bgp_evpn.h"
7724c0a1 37#include "bgpd/bgp_evpn_private.h"
185fb14a 38#include "bgpd/bgp_evpn_mh.h"
7724c0a1 39#include "bgpd/bgp_zebra.h"
520d5d76 40#include "bgpd/bgp_vty.h"
14454c9f 41#include "bgpd/bgp_errors.h"
5a0ccebf 42#include "bgpd/bgp_ecommunity.h"
7f433a5e
LK
43#include "bgpd/bgp_lcommunity.h"
44#include "bgpd/bgp_community.h"
784d3a42 45
784d3a42
PG
46#define SHOW_DISPLAY_STANDARD 0
47#define SHOW_DISPLAY_TAGS 1
48#define SHOW_DISPLAY_OVERLAY 2
60466a63 49#define VNI_STR_LEN 32
784d3a42 50
520d5d76 51/*
52 * Context for VNI hash walk - used by callbacks.
53 */
d62a17ae 54struct vni_walk_ctx {
55 struct bgp *bgp;
56 struct vty *vty;
57 struct in_addr vtep_ip;
9c92b5f7 58 json_object *json;
c7ef6cf2 59 int detail;
520d5d76 60};
61
d4a88de3
AD
62int argv_find_and_parse_oly_idx(struct cmd_token **argv, int argc, int *oly_idx,
63 enum overlay_index_type *oly)
64{
65 *oly = OVERLAY_INDEX_TYPE_NONE;
a09811ff
IR
66 if (argv_find(argv, argc, "gateway-ip", oly_idx))
67 *oly = OVERLAY_INDEX_GATEWAY_IP;
d4a88de3
AD
68 return 1;
69}
70
996c9314 71static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt,
10ebe1ab
MK
72 json_object *json)
73{
1be1693e 74 const uint8_t *pnt;
d7c0a89a 75 uint8_t type, sub_type;
10ebe1ab
MK
76 struct ecommunity_as eas;
77 struct ecommunity_ip eip;
78 struct listnode *node, *nnode;
79 struct bgp *tmp_bgp_vrf = NULL;
80 json_object *json_rt = NULL;
81 json_object *json_vrfs = NULL;
82 char rt_buf[RT_ADDRSTRLEN];
83
84 if (json) {
85 json_rt = json_object_new_object();
86 json_vrfs = json_object_new_array();
87 }
88
d7c0a89a 89 pnt = (uint8_t *)&irt->rt.val;
10ebe1ab
MK
90 type = *pnt++;
91 sub_type = *pnt++;
92 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
93 return;
94
95 memset(&eas, 0, sizeof(eas));
96 switch (type) {
97 case ECOMMUNITY_ENCODE_AS:
98 eas.as = (*pnt++ << 8);
99 eas.as |= (*pnt++);
100cb793 100 ptr_get_be32(pnt, &eas.val);
10ebe1ab 101
772270f3 102 snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val);
10ebe1ab
MK
103
104 if (json)
105 json_object_string_add(json_rt, "rt", rt_buf);
106 else
107 vty_out(vty, "Route-target: %s", rt_buf);
108
109 break;
110
111 case ECOMMUNITY_ENCODE_IP:
112 memcpy(&eip.ip, pnt, 4);
113 pnt += 4;
114 eip.val = (*pnt++ << 8);
115 eip.val |= (*pnt++);
116
23d0a753 117 snprintfrr(rt_buf, sizeof(rt_buf), "%pI4:%u", &eip.ip, eip.val);
10ebe1ab
MK
118
119 if (json)
120 json_object_string_add(json_rt, "rt", rt_buf);
121 else
122 vty_out(vty, "Route-target: %s", rt_buf);
123
124 break;
125
126 case ECOMMUNITY_ENCODE_AS4:
127 pnt = ptr_get_be32(pnt, &eas.val);
128 eas.val = (*pnt++ << 8);
129 eas.val |= (*pnt++);
130
772270f3 131 snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val);
10ebe1ab
MK
132
133 if (json)
134 json_object_string_add(json_rt, "rt", rt_buf);
135 else
136 vty_out(vty, "Route-target: %s", rt_buf);
137
138 break;
139
140 default:
141 return;
142 }
143
144 if (!json) {
145 vty_out(vty,
146 "\nList of VRFs importing routes with this route-target:\n");
147 }
148
149 for (ALL_LIST_ELEMENTS(irt->vrfs, node, nnode, tmp_bgp_vrf)) {
150 if (json)
151 json_object_array_add(
152 json_vrfs,
153 json_object_new_string(
996c9314 154 vrf_id_to_name(tmp_bgp_vrf->vrf_id)));
10ebe1ab
MK
155 else
156 vty_out(vty, " %s\n",
157 vrf_id_to_name(tmp_bgp_vrf->vrf_id));
158 }
159
160 if (json) {
161 json_object_object_add(json_rt, "vrfs", json_vrfs);
162 json_object_object_add(json, rt_buf, json_rt);
163 }
164}
165
e3b78da8 166static void show_vrf_import_rt_entry(struct hash_bucket *bucket, void *args[])
10ebe1ab
MK
167{
168 json_object *json = NULL;
169 struct vty *vty = NULL;
e3b78da8 170 struct vrf_irt_node *irt = (struct vrf_irt_node *)bucket->data;
10ebe1ab 171
181c08c6
MK
172 vty = (struct vty *)args[0];
173 json = (struct json_object *)args[1];
10ebe1ab
MK
174
175 display_vrf_import_rt(vty, irt, json);
176}
177
9c92b5f7
MK
178static void display_import_rt(struct vty *vty, struct irt_node *irt,
179 json_object *json)
d62a17ae 180{
1be1693e 181 const uint8_t *pnt;
d7c0a89a 182 uint8_t type, sub_type;
5a0ccebf
QY
183 struct ecommunity_as eas;
184 struct ecommunity_ip eip;
d62a17ae 185 struct listnode *node, *nnode;
186 struct bgpevpn *tmp_vpn;
9c92b5f7
MK
187 json_object *json_rt = NULL;
188 json_object *json_vnis = NULL;
189 char rt_buf[RT_ADDRSTRLEN];
d62a17ae 190
9c92b5f7 191 if (json) {
b682f6de 192 json_rt = json_object_new_object();
193 json_vnis = json_object_new_array();
9c92b5f7 194 }
d62a17ae 195
196 /* TODO: This needs to go into a function */
197
d7c0a89a 198 pnt = (uint8_t *)&irt->rt.val;
d62a17ae 199 type = *pnt++;
200 sub_type = *pnt++;
201 if (sub_type != ECOMMUNITY_ROUTE_TARGET)
202 return;
203
88a837f6 204 memset(&eas, 0, sizeof(eas));
d62a17ae 205 switch (type) {
206 case ECOMMUNITY_ENCODE_AS:
207 eas.as = (*pnt++ << 8);
208 eas.as |= (*pnt++);
100cb793 209 ptr_get_be32(pnt, &eas.val);
d62a17ae 210
772270f3 211 snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val);
9c92b5f7
MK
212
213 if (json)
214 json_object_string_add(json_rt, "rt", rt_buf);
215 else
216 vty_out(vty, "Route-target: %s", rt_buf);
217
d62a17ae 218 break;
219
220 case ECOMMUNITY_ENCODE_IP:
221 memcpy(&eip.ip, pnt, 4);
222 pnt += 4;
223 eip.val = (*pnt++ << 8);
224 eip.val |= (*pnt++);
225
23d0a753 226 snprintfrr(rt_buf, sizeof(rt_buf), "%pI4:%u", &eip.ip, eip.val);
9c92b5f7
MK
227
228 if (json)
229 json_object_string_add(json_rt, "rt", rt_buf);
230 else
231 vty_out(vty, "Route-target: %s", rt_buf);
232
d62a17ae 233 break;
234
235 case ECOMMUNITY_ENCODE_AS4:
937652c6 236 pnt = ptr_get_be32(pnt, &eas.val);
d62a17ae 237 eas.val = (*pnt++ << 8);
238 eas.val |= (*pnt++);
239
772270f3 240 snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val);
9c92b5f7
MK
241
242 if (json)
243 json_object_string_add(json_rt, "rt", rt_buf);
244 else
245 vty_out(vty, "Route-target: %s", rt_buf);
246
d62a17ae 247 break;
248
249 default:
250 return;
251 }
252
9c92b5f7
MK
253 if (!json) {
254 vty_out(vty,
255 "\nList of VNIs importing routes with this route-target:\n");
256 }
257
258 for (ALL_LIST_ELEMENTS(irt->vnis, node, nnode, tmp_vpn)) {
259 if (json)
260 json_object_array_add(
f00ba699 261 json_vnis, json_object_new_int(tmp_vpn->vni));
9c92b5f7
MK
262 else
263 vty_out(vty, " %u\n", tmp_vpn->vni);
264 }
265
266 if (json) {
267 json_object_object_add(json_rt, "vnis", json_vnis);
268 json_object_object_add(json, rt_buf, json_rt);
269 }
d62a17ae 270}
271
e3b78da8 272static void show_import_rt_entry(struct hash_bucket *bucket, void *args[])
520d5d76 273{
9c92b5f7
MK
274 json_object *json = NULL;
275 struct vty *vty = NULL;
e3b78da8 276 struct irt_node *irt = (struct irt_node *)bucket->data;
9c92b5f7
MK
277
278 vty = args[0];
279 json = args[1];
280
dff8f48d 281 display_import_rt(vty, irt, json);
9c92b5f7
MK
282
283 return;
d62a17ae 284}
520d5d76 285
d62a17ae 286static void bgp_evpn_show_route_rd_header(struct vty *vty,
9bcb3eef
DS
287 struct bgp_dest *rd_dest,
288 json_object *json, char *rd_str,
289 int len)
d62a17ae 290{
d7c0a89a 291 uint16_t type;
d62a17ae 292 struct rd_as rd_as;
293 struct rd_ip rd_ip;
b54892e0 294 const uint8_t *pnt;
9bcb3eef 295 const struct prefix *p = bgp_dest_get_prefix(rd_dest);
520d5d76 296
b54892e0 297 pnt = p->u.val;
520d5d76 298
d62a17ae 299 /* Decode RD type. */
300 type = decode_rd_type(pnt);
520d5d76 301
c69e79f1
LK
302 if (!json)
303 vty_out(vty, "Route Distinguisher: ");
520d5d76 304
d62a17ae 305 switch (type) {
306 case RD_TYPE_AS:
307 decode_rd_as(pnt + 2, &rd_as);
c69e79f1
LK
308 snprintf(rd_str, len, "%u:%d", rd_as.as, rd_as.val);
309 if (json)
310 json_object_string_add(json, "rd", rd_str);
311 else
527fd6de 312 vty_out(vty, "%s\n", rd_str);
c69e79f1
LK
313 break;
314
315 case RD_TYPE_AS4:
316 decode_rd_as4(pnt + 2, &rd_as);
317 snprintf(rd_str, len, "%u:%d", rd_as.as, rd_as.val);
318 if (json)
319 json_object_string_add(json, "rd", rd_str);
320 else
527fd6de 321 vty_out(vty, "%s\n", rd_str);
d62a17ae 322 break;
520d5d76 323
d62a17ae 324 case RD_TYPE_IP:
325 decode_rd_ip(pnt + 2, &rd_ip);
23d0a753 326 snprintfrr(rd_str, len, "%pI4:%d", &rd_ip.ip, rd_ip.val);
c69e79f1
LK
327 if (json)
328 json_object_string_add(json, "rd", rd_str);
329 else
527fd6de 330 vty_out(vty, "%s\n", rd_str);
d62a17ae 331 break;
520d5d76 332
d62a17ae 333 default:
c69e79f1
LK
334 if (json) {
335 snprintf(rd_str, len, "Unknown");
336 json_object_string_add(json, "rd", rd_str);
337 } else {
338 snprintf(rd_str, len, "Unknown RD type");
527fd6de 339 vty_out(vty, "%s\n", rd_str);
c69e79f1 340 }
d62a17ae 341 break;
342 }
d62a17ae 343}
344
9c92b5f7 345static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp,
2dd32217 346 uint64_t tbl_ver, json_object *json)
d62a17ae 347{
348 char ri_header[] =
349 " Network Next Hop Metric LocPrf Weight Path\n";
520d5d76 350
9c92b5f7
MK
351 if (json)
352 return;
353
23d0a753
DA
354 vty_out(vty,
355 "BGP table version is %" PRIu64 ", local router ID is %pI4\n",
356 tbl_ver, &bgp->router_id);
d62a17ae 357 vty_out(vty,
3efd0893 358 "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
d62a17ae 359 vty_out(vty, "Origin codes: i - IGP, e - EGP, ? - incomplete\n");
b5e140c8 360 vty_out(vty,
f13b2527 361 "EVPN type-1 prefix: [1]:[EthTag]:[ESI]:[IPlen]:[VTEP-IP]\n");
d62a17ae 362 vty_out(vty,
554cd77a 363 "EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]\n");
b3628c70 364 vty_out(vty, "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
50f74cf1 365 vty_out(vty, "EVPN type-4 prefix: [4]:[ESI]:[IPlen]:[OrigIP]\n");
554cd77a 366 vty_out(vty, "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
d62a17ae 367 vty_out(vty, "%s", ri_header);
368}
520d5d76 369
4cce389e
MK
370static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
371 json_object *json)
372{
373 char buf1[INET6_ADDRSTRLEN];
374 char *ecom_str;
375 struct listnode *node, *nnode;
376 struct ecommunity *ecom;
377 json_object *json_import_rtl = NULL;
378 json_object *json_export_rtl = NULL;
23c7421d 379 char buf2[ETHER_ADDR_STRLEN];
4cce389e
MK
380
381 json_import_rtl = json_export_rtl = 0;
382
383 if (json) {
384 json_import_rtl = json_object_new_array();
385 json_export_rtl = json_object_new_array();
386 json_object_int_add(json, "vni", bgp_vrf->l3vni);
387 json_object_string_add(json, "type", "L3");
37ae1adb 388 json_object_string_add(json, "inKernel", "True");
4cce389e
MK
389 json_object_string_add(
390 json, "rd",
391 prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN));
c949c771
DA
392 json_object_string_addf(json, "originatorIp", "%pI4",
393 &bgp_vrf->originator_ip);
4cce389e 394 json_object_string_add(json, "advertiseGatewayMacip", "n/a");
0b509723 395 json_object_string_add(json, "advertiseSviMacIp", "n/a");
23c7421d
CS
396 json_object_string_add(json, "advertisePip",
397 bgp_vrf->evpn_info->advertise_pip ?
398 "Enabled" : "Disabled");
c949c771
DA
399 json_object_string_addf(json, "sysIP", "%pI4",
400 &bgp_vrf->evpn_info->pip_ip);
23c7421d
CS
401 json_object_string_add(json, "sysMac",
402 prefix_mac2str(&bgp_vrf->evpn_info->pip_rmac,
403 buf2, sizeof(buf2)));
404 json_object_string_add(json, "rmac",
405 prefix_mac2str(&bgp_vrf->rmac,
406 buf2, sizeof(buf2)));
4cce389e
MK
407 } else {
408 vty_out(vty, "VNI: %d", bgp_vrf->l3vni);
409 vty_out(vty, " (known to the kernel)");
410 vty_out(vty, "\n");
411
412 vty_out(vty, " Type: %s\n", "L3");
413 vty_out(vty, " Tenant VRF: %s\n",
414 vrf_id_to_name(bgp_vrf->vrf_id));
415 vty_out(vty, " RD: %s\n",
416 prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN));
23d0a753
DA
417 vty_out(vty, " Originator IP: %pI4\n",
418 &bgp_vrf->originator_ip);
4cce389e 419 vty_out(vty, " Advertise-gw-macip : %s\n", "n/a");
cbdbb1ca 420 vty_out(vty, " Advertise-svi-macip : %s\n", "n/a");
23c7421d
CS
421 vty_out(vty, " Advertise-pip: %s\n",
422 bgp_vrf->evpn_info->advertise_pip ? "Yes" : "No");
423 vty_out(vty, " System-IP: %s\n",
1c97c9fd
CS
424 inet_ntop(AF_INET, &bgp_vrf->evpn_info->pip_ip,
425 buf1, INET_ADDRSTRLEN));
23c7421d
CS
426 vty_out(vty, " System-MAC: %s\n",
427 prefix_mac2str(&bgp_vrf->evpn_info->pip_rmac,
428 buf2, sizeof(buf2)));
429 vty_out(vty, " Router-MAC: %s\n",
430 prefix_mac2str(&bgp_vrf->rmac,
431 buf2, sizeof(buf2)));
4cce389e
MK
432 }
433
434 if (!json)
435 vty_out(vty, " Import Route Target:\n");
436
437 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
438 ecom_str = ecommunity_ecom2str(ecom,
439 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
440
441 if (json)
442 json_object_array_add(json_import_rtl,
443 json_object_new_string(ecom_str));
444 else
445 vty_out(vty, " %s\n", ecom_str);
446
447 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
448 }
449
450 if (json)
451 json_object_object_add(json, "importRts", json_import_rtl);
452 else
453 vty_out(vty, " Export Route Target:\n");
454
455 for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
456 ecom_str = ecommunity_ecom2str(ecom,
457 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
458
459 if (json)
460 json_object_array_add(json_export_rtl,
461 json_object_new_string(ecom_str));
462 else
463 vty_out(vty, " %s\n", ecom_str);
464
465 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
466 }
467
468 if (json)
469 json_object_object_add(json, "exportRts", json_export_rtl);
470}
471
9c92b5f7 472static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
d62a17ae 473{
06b9f471 474 char buf1[RD_ADDRSTRLEN];
d62a17ae 475 char *ecom_str;
476 struct listnode *node, *nnode;
477 struct ecommunity *ecom;
f57514e1
DS
478 json_object *json_import_rtl = NULL;
479 json_object *json_export_rtl = NULL;
2c4654a1
CS
480 struct bgp *bgp_evpn;
481
482 bgp_evpn = bgp_get_evpn();
9c92b5f7
MK
483
484 if (json) {
485 json_import_rtl = json_object_new_array();
486 json_export_rtl = json_object_new_array();
487 json_object_int_add(json, "vni", vpn->vni);
4cce389e 488 json_object_string_add(json, "type", "L2");
37ae1adb
CS
489 json_object_string_add(json, "inKernel",
490 is_vni_live(vpn) ? "True" : "False");
9c92b5f7
MK
491 json_object_string_add(
492 json, "rd",
06b9f471 493 prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
c949c771
DA
494 json_object_string_addf(json, "originatorIp", "%pI4",
495 &vpn->originator_ip);
496 json_object_string_addf(json, "mcastGroup", "%pI4",
497 &vpn->mcast_grp);
2c4654a1
CS
498 /* per vni knob is enabled -- Enabled
499 * Global knob is enabled -- Active
500 * default -- Disabled
501 */
502 if (!vpn->advertise_gw_macip &&
503 bgp_evpn && bgp_evpn->advertise_gw_macip)
504 json_object_string_add(json, "advertiseGatewayMacip",
505 "Active");
506 else if (vpn->advertise_gw_macip)
507 json_object_string_add(json, "advertiseGatewayMacip",
508 "Enabled");
509 else
510 json_object_string_add(json, "advertiseGatewayMacip",
511 "Disabled");
512 if (!vpn->advertise_svi_macip && bgp_evpn &&
513 bgp_evpn->evpn_info->advertise_svi_macip)
0b509723 514 json_object_string_add(json, "advertiseSviMacIp",
2c4654a1
CS
515 "Active");
516 else if (vpn->advertise_svi_macip)
0b509723 517 json_object_string_add(json, "advertiseSviMacIp",
2c4654a1
CS
518 "Enabled");
519 else
0b509723 520 json_object_string_add(json, "advertiseSviMacIp",
2c4654a1 521 "Disabled");
9daa5d47
AD
522 json_object_string_add(
523 json, "sviInterface",
524 ifindex2ifname(vpn->svi_ifindex, vpn->tenant_vrf_id));
9c92b5f7
MK
525 } else {
526 vty_out(vty, "VNI: %d", vpn->vni);
527 if (is_vni_live(vpn))
528 vty_out(vty, " (known to the kernel)");
529 vty_out(vty, "\n");
530
4cce389e 531 vty_out(vty, " Type: %s\n", "L2");
29c53922
MK
532 vty_out(vty, " Tenant-Vrf: %s\n",
533 vrf_id_to_name(vpn->tenant_vrf_id));
9c92b5f7 534 vty_out(vty, " RD: %s\n",
06b9f471 535 prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
23d0a753
DA
536 vty_out(vty, " Originator IP: %pI4\n", &vpn->originator_ip);
537 vty_out(vty, " Mcast group: %pI4\n", &vpn->mcast_grp);
2c4654a1
CS
538 if (!vpn->advertise_gw_macip &&
539 bgp_evpn && bgp_evpn->advertise_gw_macip)
540 vty_out(vty, " Advertise-gw-macip : %s\n",
541 "Active");
542 else if (vpn->advertise_gw_macip)
543 vty_out(vty, " Advertise-gw-macip : %s\n",
544 "Enabled");
545 else
546 vty_out(vty, " Advertise-gw-macip : %s\n",
547 "Disabled");
548 if (!vpn->advertise_svi_macip && bgp_evpn &&
549 bgp_evpn->evpn_info->advertise_svi_macip)
550 vty_out(vty, " Advertise-svi-macip : %s\n",
551 "Active");
552 else if (vpn->advertise_svi_macip)
553 vty_out(vty, " Advertise-svi-macip : %s\n",
554 "Enabled");
555 else
556 vty_out(vty, " Advertise-svi-macip : %s\n",
557 "Disabled");
9daa5d47
AD
558 vty_out(vty, " SVI interface : %s\n",
559 ifindex2ifname(vpn->svi_ifindex, vpn->tenant_vrf_id));
9c92b5f7 560 }
520d5d76 561
9c92b5f7
MK
562 if (!json)
563 vty_out(vty, " Import Route Target:\n");
520d5d76 564
d62a17ae 565 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
566 ecom_str = ecommunity_ecom2str(ecom,
567 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
9c92b5f7
MK
568
569 if (json)
570 json_object_array_add(json_import_rtl,
571 json_object_new_string(ecom_str));
572 else
573 vty_out(vty, " %s\n", ecom_str);
574
d62a17ae 575 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
576 }
520d5d76 577
9c92b5f7
MK
578 if (json)
579 json_object_object_add(json, "importRts", json_import_rtl);
580 else
581 vty_out(vty, " Export Route Target:\n");
582
d62a17ae 583 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom)) {
584 ecom_str = ecommunity_ecom2str(ecom,
585 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
9c92b5f7
MK
586
587 if (json)
588 json_object_array_add(json_export_rtl,
589 json_object_new_string(ecom_str));
590 else
591 vty_out(vty, " %s\n", ecom_str);
592
d62a17ae 593 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
594 }
9c92b5f7
MK
595
596 if (json)
597 json_object_object_add(json, "exportRts", json_export_rtl);
520d5d76 598}
d62a17ae 599
50f74cf1 600static void show_esi_routes(struct bgp *bgp,
b5e140c8 601 struct bgp_evpn_es *es,
50f74cf1 602 struct vty *vty,
603 json_object *json)
604{
605 int header = 1;
9bcb3eef 606 struct bgp_dest *dest;
40381db7 607 struct bgp_path_info *pi;
50f74cf1 608 uint32_t prefix_cnt, path_cnt;
609 uint64_t tbl_ver;
610
611 prefix_cnt = path_cnt = 0;
612
613 tbl_ver = es->route_table->version;
9bcb3eef
DS
614 for (dest = bgp_table_top(es->route_table); dest;
615 dest = bgp_route_next(dest)) {
50f74cf1 616 int add_prefix_to_json = 0;
617 char prefix_str[BUFSIZ];
618 json_object *json_paths = NULL;
619 json_object *json_prefix = NULL;
9bcb3eef 620 const struct prefix *p = bgp_dest_get_prefix(dest);
50f74cf1 621
f137734b
PR
622 prefix2str((struct prefix_evpn *)p, prefix_str,
623 sizeof(prefix_str));
50f74cf1 624
625 if (json)
626 json_prefix = json_object_new_object();
627
9bcb3eef 628 pi = bgp_dest_get_bgp_path_info(dest);
6f94b685 629 if (pi) {
50f74cf1 630 /* Overall header/legend displayed once. */
631 if (header) {
632 bgp_evpn_show_route_header(vty, bgp,
633 tbl_ver, json);
634 header = 0;
635 }
636
637 prefix_cnt++;
638 }
639
640 if (json)
641 json_paths = json_object_new_array();
642
643 /* For EVPN, the prefix is displayed for each path (to fit in
644 * with code that already exists).
645 */
6f94b685 646 for (; pi; pi = pi->next) {
50f74cf1 647 json_object *json_path = NULL;
648
649 if (json)
650 json_path = json_object_new_array();
651
ae248832
MK
652 route_vty_out(vty, p, pi, 0, SAFI_EVPN, json_path,
653 false);
50f74cf1 654
655 if (json)
656 json_object_array_add(json_paths, json_path);
657
658 path_cnt++;
659 add_prefix_to_json = 1;
660 }
661
24882500
CS
662 if (json) {
663 if (add_prefix_to_json) {
664 json_object_string_add(json_prefix, "prefix",
665 prefix_str);
666 json_object_int_add(json_prefix, "prefixLen",
b54892e0 667 p->prefixlen);
24882500
CS
668 json_object_object_add(json_prefix, "paths",
669 json_paths);
670 json_object_object_add(json, prefix_str,
671 json_prefix);
672 } else {
673 json_object_free(json_paths);
674 json_object_free(json_prefix);
675 json_paths = NULL;
676 json_prefix = NULL;
677 }
50f74cf1 678 }
679 }
680
681 if (json) {
682 json_object_int_add(json, "numPrefix", prefix_cnt);
683 json_object_int_add(json, "numPaths", path_cnt);
684 } else {
685 if (prefix_cnt == 0)
a2a8153f 686 vty_out(vty, "No EVPN prefixes exist for this ESI\n");
50f74cf1 687 else
688 vty_out(vty, "\nDisplayed %u prefixes (%u paths)\n",
689 prefix_cnt, path_cnt);
690 }
691}
692
229587fb 693/* Display all MAC-IP VNI routes linked to an ES */
58bff4d1
AK
694static void bgp_evpn_show_routes_mac_ip_es(struct vty *vty, esi_t *esi,
695 json_object *json, int detail,
696 bool global_table)
229587fb
AK
697{
698 struct bgp_node *rn;
699 struct bgp_path_info *pi;
700 int header = detail ? 0 : 1;
701 uint32_t path_cnt;
702 struct listnode *node;
703 struct bgp_evpn_es *es;
704 struct bgp_path_es_info *es_info;
705 struct bgp *bgp = bgp_get_evpn();
706 json_object *json_paths = NULL;
707
708 if (!bgp)
709 return;
710
711 path_cnt = 0;
712
713 if (json)
714 json_paths = json_object_new_array();
715
716 RB_FOREACH (es, bgp_es_rb_head, &bgp_mh_info->es_rb_tree) {
58bff4d1 717 struct list *es_list;
229587fb
AK
718
719 if (esi && memcmp(esi, &es->esi, sizeof(*esi)))
720 continue;
721
58bff4d1
AK
722 if (global_table)
723 es_list = es->macip_global_path_list;
724 else
725 es_list = es->macip_evi_path_list;
726
727 for (ALL_LIST_ELEMENTS_RO(es_list, node, es_info)) {
229587fb
AK
728 json_object *json_path = NULL;
729
730 pi = es_info->pi;
731 rn = pi->net;
732
733 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
734 continue;
735
736 /* Overall header/legend displayed once. */
737 if (header) {
738 bgp_evpn_show_route_header(vty, bgp, 0, json);
739 header = 0;
740 }
741
742 path_cnt++;
743
744 if (json)
745 json_path = json_object_new_array();
746
747 if (detail)
4933eaaf
DS
748 route_vty_out_detail(
749 vty, bgp, rn, pi, AFI_L2VPN, SAFI_EVPN,
750 RPKI_NOT_BEING_USED, json_path);
229587fb
AK
751 else
752 route_vty_out(vty, &rn->p, pi, 0, SAFI_EVPN,
753 json_path, false);
754
755 if (json)
756 json_object_array_add(json_paths, json_path);
757 }
758 }
759
760 if (json) {
761 json_object_object_add(json, "paths", json_paths);
762 json_object_int_add(json, "numPaths", path_cnt);
763 } else {
764 if (path_cnt == 0)
765 vty_out(vty, "There are no MAC-IP ES paths");
766 else
767 vty_out(vty, "\nDisplayed %u paths\n", path_cnt);
768 vty_out(vty, "\n");
769 }
770}
771
58bff4d1
AK
772static void bgp_evpn_show_routes_mac_ip_evi_es(struct vty *vty, esi_t *esi,
773 json_object *json, int detail)
774{
a454d9ab 775 bgp_evpn_show_routes_mac_ip_es(vty, esi, json, detail, false);
58bff4d1
AK
776}
777
778static void bgp_evpn_show_routes_mac_ip_global_es(struct vty *vty, esi_t *esi,
779 json_object *json, int detail)
780{
a454d9ab 781 bgp_evpn_show_routes_mac_ip_es(vty, esi, json, detail, true);
58bff4d1
AK
782}
783
d62a17ae 784static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
9c92b5f7 785 struct vty *vty, struct in_addr vtep_ip,
c7ef6cf2 786 json_object *json, int detail)
520d5d76 787{
9bcb3eef 788 struct bgp_dest *dest;
40381db7 789 struct bgp_path_info *pi;
2dd32217 790 struct bgp_table *table;
c7ef6cf2 791 int header = detail ? 0 : 1;
2dd32217 792 uint64_t tbl_ver;
d7c0a89a 793 uint32_t prefix_cnt, path_cnt;
d62a17ae 794
795 prefix_cnt = path_cnt = 0;
796
2dd32217 797 table = vpn->route_table;
798 tbl_ver = table->version;
9bcb3eef 799 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
b54892e0 800 const struct prefix_evpn *evp =
9bcb3eef 801 (const struct prefix_evpn *)bgp_dest_get_prefix(dest);
9c92b5f7
MK
802 int add_prefix_to_json = 0;
803 char prefix_str[BUFSIZ];
804 json_object *json_paths = NULL;
805 json_object *json_prefix = NULL;
9bcb3eef 806 const struct prefix *p = bgp_dest_get_prefix(dest);
9c92b5f7 807
f137734b
PR
808 prefix2str((struct prefix_evpn *)bgp_dest_get_prefix(dest),
809 prefix_str, sizeof(prefix_str));
d62a17ae 810
811 if (type && evp->prefix.route_type != type)
812 continue;
813
9c92b5f7
MK
814 if (json)
815 json_prefix = json_object_new_object();
816
9bcb3eef 817 pi = bgp_dest_get_bgp_path_info(dest);
6f94b685 818 if (pi) {
d62a17ae 819 /* Overall header/legend displayed once. */
820 if (header) {
2dd32217 821 bgp_evpn_show_route_header(vty, bgp,
822 tbl_ver, json);
d62a17ae 823 header = 0;
824 }
825
826 prefix_cnt++;
827 }
828
9c92b5f7
MK
829 if (json)
830 json_paths = json_object_new_array();
831
d62a17ae 832 /* For EVPN, the prefix is displayed for each path (to fit in
833 * with code that already exists).
834 */
6f94b685 835 for (; pi; pi = pi->next) {
9c92b5f7
MK
836 json_object *json_path = NULL;
837
975a328e 838 if (vtep_ip.s_addr != INADDR_ANY
d62a17ae 839 && !IPV4_ADDR_SAME(&(vtep_ip),
40381db7 840 &(pi->attr->nexthop)))
d62a17ae 841 continue;
842
9c92b5f7
MK
843 if (json)
844 json_path = json_object_new_array();
845
c7ef6cf2 846 if (detail)
9bcb3eef 847 route_vty_out_detail(vty, bgp, dest, pi,
c7ef6cf2 848 AFI_L2VPN, SAFI_EVPN,
4933eaaf 849 RPKI_NOT_BEING_USED,
c7ef6cf2
NS
850 json_path);
851 else
b54892e0 852 route_vty_out(vty, p, pi, 0, SAFI_EVPN,
ae248832 853 json_path, false);
9c92b5f7
MK
854
855 if (json)
856 json_object_array_add(json_paths, json_path);
857
d62a17ae 858 path_cnt++;
9c92b5f7
MK
859 add_prefix_to_json = 1;
860 }
861
24882500
CS
862 if (json) {
863 if (add_prefix_to_json) {
864 json_object_string_add(json_prefix, "prefix",
865 prefix_str);
866 json_object_int_add(json_prefix, "prefixLen",
b54892e0 867 p->prefixlen);
24882500
CS
868 json_object_object_add(json_prefix, "paths",
869 json_paths);
870 json_object_object_add(json, prefix_str,
871 json_prefix);
872 } else {
873 json_object_free(json_paths);
874 json_object_free(json_prefix);
875 json_paths = NULL;
876 json_prefix = NULL;
877 }
d62a17ae 878 }
879 }
880
9c92b5f7
MK
881 if (json) {
882 json_object_int_add(json, "numPrefix", prefix_cnt);
883 json_object_int_add(json, "numPaths", path_cnt);
884 } else {
885 if (prefix_cnt == 0)
886 vty_out(vty, "No EVPN prefixes %sexist for this VNI",
887 type ? "(of requested type) " : "");
888 else
50f74cf1 889 vty_out(vty, "\nDisplayed %u prefixes (%u paths)%s\n",
9c92b5f7
MK
890 prefix_cnt, path_cnt,
891 type ? " (of requested type)" : "");
c7ef6cf2 892 vty_out(vty, "\n");
9c92b5f7 893 }
520d5d76 894}
895
e3b78da8 896static void show_vni_routes_hash(struct hash_bucket *bucket, void *arg)
520d5d76 897{
e3b78da8 898 struct bgpevpn *vpn = (struct bgpevpn *)bucket->data;
d62a17ae 899 struct vni_walk_ctx *wctx = arg;
900 struct vty *vty = wctx->vty;
9c92b5f7
MK
901 json_object *json = wctx->json;
902 json_object *json_vni = NULL;
903 char vni_str[VNI_STR_LEN];
904
772270f3 905 snprintf(vni_str, sizeof(vni_str), "%d", vpn->vni);
9c92b5f7
MK
906 if (json) {
907 json_vni = json_object_new_object();
908 json_object_int_add(json_vni, "vni", vpn->vni);
909 } else {
910 vty_out(vty, "\nVNI: %d\n\n", vpn->vni);
911 }
912
c7ef6cf2
NS
913 show_vni_routes(wctx->bgp, vpn, 0, wctx->vty, wctx->vtep_ip, json_vni,
914 wctx->detail);
520d5d76 915
9c92b5f7
MK
916 if (json)
917 json_object_object_add(json, vni_str, json_vni);
520d5d76 918}
919
4cce389e 920static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
996c9314 921 json_object *json)
4cce389e 922{
dcfe4716
DS
923 json_object *json_vni = NULL;
924 json_object *json_import_rtl = NULL;
925 json_object *json_export_rtl = NULL;
4cce389e
MK
926 char buf1[10];
927 char buf2[INET6_ADDRSTRLEN];
928 char rt_buf[25];
929 char *ecom_str;
930 struct listnode *node, *nnode;
931 struct ecommunity *ecom;
932
933 if (!bgp->l3vni)
934 return;
935
936 if (json) {
937 json_vni = json_object_new_object();
938 json_import_rtl = json_object_new_array();
939 json_export_rtl = json_object_new_array();
940 }
941
942 /* if an l3vni is present in bgp it is live */
943 buf1[0] = '\0';
772270f3 944 snprintf(buf1, sizeof(buf1), "*");
4cce389e
MK
945
946 if (json) {
947 json_object_int_add(json_vni, "vni", bgp->l3vni);
948 json_object_string_add(json_vni, "type", "L3");
949 json_object_string_add(json_vni, "inKernel", "True");
c949c771
DA
950 json_object_string_addf(json_vni, "originatorIp", "%pI4",
951 &bgp->originator_ip);
4cce389e
MK
952 json_object_string_add(
953 json_vni, "rd",
954 prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
7c9cb387
CS
955 json_object_string_add(json_vni, "advertiseGatewayMacip",
956 "n/a");
0b509723 957 json_object_string_add(json_vni, "advertiseSviMacIp", "n/a");
7c9cb387
CS
958 json_object_string_add(
959 json_vni, "advertisePip",
960 bgp->evpn_info->advertise_pip ? "Enabled" : "Disabled");
c949c771
DA
961 json_object_string_addf(json_vni, "sysIP", "%pI4",
962 &bgp->evpn_info->pip_ip);
7c9cb387
CS
963 json_object_string_add(json_vni, "sysMAC",
964 prefix_mac2str(&bgp->evpn_info->pip_rmac,
965 buf2, sizeof(buf2)));
966 json_object_string_add(
967 json_vni, "rmac",
968 prefix_mac2str(&bgp->rmac, buf2, sizeof(buf2)));
4cce389e 969 } else {
996c9314 970 vty_out(vty, "%-1s %-10u %-4s %-21s", buf1, bgp->l3vni, "L3",
4cce389e
MK
971 prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
972 }
973
974 for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode, ecom)) {
975 ecom_str = ecommunity_ecom2str(ecom,
976 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
977
978 if (json) {
979 json_object_array_add(json_import_rtl,
980 json_object_new_string(ecom_str));
981 } else {
982 if (listcount(bgp->vrf_import_rtl) > 1)
772270f3
QY
983 snprintf(rt_buf, sizeof(rt_buf), "%s, ...",
984 ecom_str);
4cce389e 985 else
772270f3
QY
986 snprintf(rt_buf, sizeof(rt_buf), "%s",
987 ecom_str);
4cce389e
MK
988 vty_out(vty, " %-25s", rt_buf);
989 }
990
991 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
992
993 /* If there are multiple import RTs we break here and show only
994 * one */
995 if (!json)
996 break;
997 }
998
999 if (json)
1000 json_object_object_add(json_vni, "importRTs", json_import_rtl);
1001
1002 for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode, ecom)) {
1003 ecom_str = ecommunity_ecom2str(ecom,
1004 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1005
1006 if (json) {
1007 json_object_array_add(json_export_rtl,
1008 json_object_new_string(ecom_str));
1009 } else {
1010 if (listcount(bgp->vrf_export_rtl) > 1)
772270f3
QY
1011 snprintf(rt_buf, sizeof(rt_buf), "%s, ...",
1012 ecom_str);
4cce389e 1013 else
772270f3
QY
1014 snprintf(rt_buf, sizeof(rt_buf), "%s",
1015 ecom_str);
4cce389e
MK
1016 vty_out(vty, " %-25s", rt_buf);
1017 }
1018
1019 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
1020
1021 /* If there are multiple export RTs we break here and show only
1022 * one */
1023 if (!json)
1024 break;
1025 }
1026
1027 if (!json)
1028 vty_out(vty, "%-37s", vrf_id_to_name(bgp->vrf_id));
1029
1030 if (json) {
1031 char vni_str[VNI_STR_LEN];
1032
1033 json_object_object_add(json_vni, "exportRTs", json_export_rtl);
772270f3 1034 snprintf(vni_str, sizeof(vni_str), "%u", bgp->l3vni);
4cce389e
MK
1035 json_object_object_add(json, vni_str, json_vni);
1036 } else {
1037 vty_out(vty, "\n");
1038 }
1039}
1040
e3b78da8 1041static void show_vni_entry(struct hash_bucket *bucket, void *args[])
520d5d76 1042{
9c92b5f7
MK
1043 struct vty *vty;
1044 json_object *json;
fb8f41e4
RB
1045 json_object *json_vni = NULL;
1046 json_object *json_import_rtl = NULL;
1047 json_object *json_export_rtl = NULL;
e3b78da8 1048 struct bgpevpn *vpn = (struct bgpevpn *)bucket->data;
d62a17ae 1049 char buf1[10];
06b9f471 1050 char buf2[RD_ADDRSTRLEN];
d62a17ae 1051 char rt_buf[25];
1052 char *ecom_str;
1053 struct listnode *node, *nnode;
1054 struct ecommunity *ecom;
7c9cb387 1055 struct bgp *bgp_evpn;
520d5d76 1056
9c92b5f7
MK
1057 vty = args[0];
1058 json = args[1];
1059
7c9cb387
CS
1060 bgp_evpn = bgp_get_evpn();
1061
9c92b5f7
MK
1062 if (json) {
1063 json_vni = json_object_new_object();
1064 json_import_rtl = json_object_new_array();
1065 json_export_rtl = json_object_new_array();
1066 }
1067
d62a17ae 1068 buf1[0] = '\0';
1069 if (is_vni_live(vpn))
772270f3 1070 snprintf(buf1, sizeof(buf1), "*");
520d5d76 1071
9c92b5f7
MK
1072 if (json) {
1073 json_object_int_add(json_vni, "vni", vpn->vni);
4cce389e 1074 json_object_string_add(json_vni, "type", "L2");
9c92b5f7
MK
1075 json_object_string_add(json_vni, "inKernel",
1076 is_vni_live(vpn) ? "True" : "False");
9c92b5f7
MK
1077 json_object_string_add(
1078 json_vni, "rd",
06b9f471 1079 prefix_rd2str(&vpn->prd, buf2, sizeof(buf2)));
c949c771
DA
1080 json_object_string_addf(json_vni, "originatorIp", "%pI4",
1081 &vpn->originator_ip);
1082 json_object_string_addf(json_vni, "mcastGroup", "%pI4",
1083 &vpn->mcast_grp);
7c9cb387
CS
1084 /* per vni knob is enabled -- Enabled
1085 * Global knob is enabled -- Active
1086 * default -- Disabled
1087 */
1088 if (!vpn->advertise_gw_macip && bgp_evpn
1089 && bgp_evpn->advertise_gw_macip)
1090 json_object_string_add(
1091 json_vni, "advertiseGatewayMacip", "Active");
1092 else if (vpn->advertise_gw_macip)
1093 json_object_string_add(
1094 json_vni, "advertiseGatewayMacip", "Enabled");
1095 else
1096 json_object_string_add(
1097 json_vni, "advertiseGatewayMacip", "Disabled");
1098 if (!vpn->advertise_svi_macip && bgp_evpn
1099 && bgp_evpn->evpn_info->advertise_svi_macip)
0b509723 1100 json_object_string_add(json_vni, "advertiseSviMacIp",
7c9cb387
CS
1101 "Active");
1102 else if (vpn->advertise_svi_macip)
0b509723 1103 json_object_string_add(json_vni, "advertiseSviMacIp",
7c9cb387
CS
1104 "Enabled");
1105 else
0b509723 1106 json_object_string_add(json_vni, "advertiseSviMacIp",
7c9cb387 1107 "Disabled");
9c92b5f7 1108 } else {
996c9314 1109 vty_out(vty, "%-1s %-10u %-4s %-21s", buf1, vpn->vni, "L2",
29c53922 1110 prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN));
9c92b5f7 1111 }
520d5d76 1112
d62a17ae 1113 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
1114 ecom_str = ecommunity_ecom2str(ecom,
1115 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
520d5d76 1116
9c92b5f7
MK
1117 if (json) {
1118 json_object_array_add(json_import_rtl,
1119 json_object_new_string(ecom_str));
1120 } else {
1121 if (listcount(vpn->import_rtl) > 1)
772270f3
QY
1122 snprintf(rt_buf, sizeof(rt_buf), "%s, ...",
1123 ecom_str);
9c92b5f7 1124 else
772270f3
QY
1125 snprintf(rt_buf, sizeof(rt_buf), "%s",
1126 ecom_str);
9c92b5f7
MK
1127 vty_out(vty, " %-25s", rt_buf);
1128 }
520d5d76 1129
d62a17ae 1130 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
9c92b5f7
MK
1131
1132 /* If there are multiple import RTs we break here and show only
1133 * one */
1134 if (!json)
1135 break;
d62a17ae 1136 }
1137
9c92b5f7
MK
1138 if (json)
1139 json_object_object_add(json_vni, "importRTs", json_import_rtl);
1140
d62a17ae 1141 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom)) {
1142 ecom_str = ecommunity_ecom2str(ecom,
1143 ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
1144
9c92b5f7
MK
1145 if (json) {
1146 json_object_array_add(json_export_rtl,
1147 json_object_new_string(ecom_str));
1148 } else {
1149 if (listcount(vpn->export_rtl) > 1)
772270f3
QY
1150 snprintf(rt_buf, sizeof(rt_buf), "%s, ...",
1151 ecom_str);
9c92b5f7 1152 else
772270f3
QY
1153 snprintf(rt_buf, sizeof(rt_buf), "%s",
1154 ecom_str);
9c92b5f7
MK
1155 vty_out(vty, " %-25s", rt_buf);
1156 }
d62a17ae 1157
1158 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
9c92b5f7
MK
1159
1160 /* If there are multiple export RTs we break here and show only
1161 * one */
1162 if (!json)
1163 break;
1164 }
1165
6be9a208
MK
1166 if (!json)
1167 vty_out(vty, "%-37s", vrf_id_to_name(vpn->tenant_vrf_id));
1168
9c92b5f7
MK
1169 if (json) {
1170 char vni_str[VNI_STR_LEN];
b682f6de 1171
9c92b5f7 1172 json_object_object_add(json_vni, "exportRTs", json_export_rtl);
772270f3 1173 snprintf(vni_str, sizeof(vni_str), "%u", vpn->vni);
9c92b5f7
MK
1174 json_object_object_add(json, vni_str, json_vni);
1175 } else {
1176 vty_out(vty, "\n");
d62a17ae 1177 }
520d5d76 1178}
1179
d62a17ae 1180static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
1181 enum bgp_show_type type, void *output_arg,
9f049418 1182 int option, bool use_json)
784d3a42 1183{
4d0e6ece
PG
1184 afi_t afi = AFI_L2VPN;
1185 struct bgp *bgp;
1186 struct bgp_table *table;
9bcb3eef
DS
1187 struct bgp_dest *dest;
1188 struct bgp_dest *rm;
40381db7 1189 struct bgp_path_info *pi;
4d0e6ece
PG
1190 int rd_header;
1191 int header = 1;
c69e79f1 1192 char rd_str[RD_ADDRSTRLEN];
597f4b1a 1193 char buf[BUFSIZ];
0afbd728 1194 int no_display;
4d0e6ece
PG
1195
1196 unsigned long output_count = 0;
1197 unsigned long total_count = 0;
1198 json_object *json = NULL;
4d0e6ece 1199 json_object *json_array = NULL;
597f4b1a
LK
1200 json_object *json_prefix_info = NULL;
1201
c69e79f1 1202 memset(rd_str, 0, RD_ADDRSTRLEN);
4d0e6ece 1203
530db8dc 1204 bgp = bgp_get_evpn();
4d0e6ece
PG
1205 if (bgp == NULL) {
1206 if (!use_json)
d62a17ae 1207 vty_out(vty, "No BGP process is configured\n");
16307668
RW
1208 else
1209 vty_out(vty, "{}\n");
4d0e6ece
PG
1210 return CMD_WARNING;
1211 }
1212
597f4b1a 1213 if (use_json)
4d0e6ece 1214 json = json_object_new_object();
4d0e6ece 1215
9bcb3eef
DS
1216 for (dest = bgp_table_top(bgp->rib[afi][SAFI_EVPN]); dest;
1217 dest = bgp_route_next(dest)) {
2dd32217 1218 uint64_t tbl_ver;
c69e79f1 1219 json_object *json_nroute = NULL;
9bcb3eef 1220 const struct prefix *p = bgp_dest_get_prefix(dest);
2dd32217 1221
b54892e0 1222 if (prd && memcmp(p->u.val, prd->val, 8) != 0)
4d0e6ece
PG
1223 continue;
1224
9bcb3eef 1225 table = bgp_dest_get_bgp_table_info(dest);
67009e22 1226 if (!table)
ea47320b 1227 continue;
4d0e6ece 1228
ea47320b 1229 rd_header = 1;
2dd32217 1230 tbl_ver = table->version;
4d0e6ece 1231
0ac811af 1232 for (rm = bgp_table_top(table); rm; rm = bgp_route_next(rm)) {
9bcb3eef 1233 pi = bgp_dest_get_bgp_path_info(rm);
0afbd728
KA
1234 if (pi == NULL)
1235 continue;
1236
1237 no_display = 0;
0afbd728 1238 for (; pi; pi = pi->next) {
ea47320b
DL
1239 total_count++;
1240 if (type == bgp_show_type_neighbor) {
dcc1615e 1241 struct peer *peer = output_arg;
ea47320b 1242
dcc1615e 1243 if (peer_cmp(peer, pi->peer) != 0)
ea47320b
DL
1244 continue;
1245 }
7f433a5e
LK
1246 if (type == bgp_show_type_lcommunity_exact) {
1247 struct lcommunity *lcom = output_arg;
1248
1bcf3a96
DA
1249 if (!bgp_attr_get_lcommunity(
1250 pi->attr) ||
1251 !lcommunity_cmp(
1252 bgp_attr_get_lcommunity(
1253 pi->attr),
1254 lcom))
7f433a5e
LK
1255 continue;
1256 }
1257 if (type == bgp_show_type_lcommunity) {
1258 struct lcommunity *lcom = output_arg;
1259
1bcf3a96
DA
1260 if (!bgp_attr_get_lcommunity(
1261 pi->attr) ||
1262 !lcommunity_match(
1263 bgp_attr_get_lcommunity(
1264 pi->attr),
1265 lcom))
7f433a5e
LK
1266 continue;
1267 }
1268 if (type == bgp_show_type_community) {
1269 struct community *com = output_arg;
1270
1271 if (!pi->attr->community ||
1272 !community_match(
1273 pi->attr->community, com))
1274 continue;
1275 }
1276 if (type == bgp_show_type_community_exact) {
1277 struct community *com = output_arg;
1278
1279 if (!pi->attr->community ||
1280 !community_cmp(
1281 pi->attr->community, com))
1282 continue;
1283 }
597f4b1a 1284 if (header) {
ea47320b 1285 if (use_json) {
597f4b1a
LK
1286 json_object_int_add(
1287 json, "bgpTableVersion",
1288 tbl_ver);
c949c771 1289 json_object_string_addf(
597f4b1a
LK
1290 json,
1291 "bgpLocalRouterId",
c949c771
DA
1292 "%pI4",
1293 &bgp->router_id);
597f4b1a
LK
1294 json_object_int_add(
1295 json,
1296 "defaultLocPrf",
1297 bgp->default_local_pref);
1298 json_object_int_add(
1299 json, "localAS",
1300 bgp->as);
ea47320b 1301 } else {
60466a63 1302 if (option == SHOW_DISPLAY_TAGS)
ea47320b
DL
1303 vty_out(vty,
1304 V4_HEADER_TAG);
1305 else if (
1306 option
1307 == SHOW_DISPLAY_OVERLAY)
1308 vty_out(vty,
1309 V4_HEADER_OVERLAY);
1310 else {
0afbd728 1311 bgp_evpn_show_route_header(vty, bgp, tbl_ver, NULL);
4d0e6ece 1312 }
4d0e6ece 1313 }
ea47320b 1314 header = 0;
4d0e6ece 1315 }
ea47320b 1316 if (rd_header) {
c69e79f1
LK
1317 if (use_json)
1318 json_nroute =
1319 json_object_new_object();
9bcb3eef
DS
1320 bgp_evpn_show_route_rd_header(
1321 vty, dest, json_nroute, rd_str,
c69e79f1 1322 RD_ADDRSTRLEN);
ea47320b
DL
1323 rd_header = 0;
1324 }
c69e79f1
LK
1325 if (use_json && !json_array)
1326 json_array = json_object_new_array();
0ac811af 1327
ea47320b 1328 if (option == SHOW_DISPLAY_TAGS)
b54892e0 1329 route_vty_out_tag(
9bcb3eef 1330 vty, bgp_dest_get_prefix(rm),
b54892e0
DS
1331 pi, no_display, SAFI_EVPN,
1332 json_array);
ea47320b 1333 else if (option == SHOW_DISPLAY_OVERLAY)
b54892e0 1334 route_vty_out_overlay(
9bcb3eef 1335 vty, bgp_dest_get_prefix(rm),
b54892e0 1336 pi, no_display, json_array);
ea47320b 1337 else
b54892e0 1338 route_vty_out(vty,
9bcb3eef 1339 bgp_dest_get_prefix(rm),
b54892e0 1340 pi, no_display, SAFI_EVPN,
ae248832 1341 json_array, false);
0afbd728 1342 no_display = 1;
ea47320b 1343 }
0afbd728
KA
1344
1345 if (no_display)
1346 output_count++;
1347
c69e79f1 1348 if (use_json && json_array) {
b54892e0 1349 const struct prefix *p =
9bcb3eef 1350 bgp_dest_get_prefix(rm);
b54892e0 1351
c69e79f1
LK
1352 json_prefix_info = json_object_new_object();
1353
67d7e256
DA
1354 prefix2str((struct prefix_evpn *)p, buf,
1355 BUFSIZ);
1356
1357 json_object_string_addf(
1358 json_prefix_info, "prefix", "%pFX",
1359 (struct prefix_evpn *)p);
c69e79f1
LK
1360
1361 json_object_int_add(json_prefix_info,
b54892e0 1362 "prefixLen", p->prefixlen);
c69e79f1 1363
0ac811af
LK
1364 json_object_object_add(json_prefix_info,
1365 "paths", json_array);
1366 json_object_object_add(json_nroute, buf,
1367 json_prefix_info);
c69e79f1 1368 json_array = NULL;
0ac811af
LK
1369 }
1370 }
597f4b1a 1371
c69e79f1 1372 if (use_json && json_nroute)
597f4b1a 1373 json_object_object_add(json, rd_str, json_nroute);
597f4b1a
LK
1374 }
1375
1376 if (use_json) {
1377 json_object_int_add(json, "numPrefix", output_count);
1378 json_object_int_add(json, "totalPrefix", total_count);
75eeda93 1379 vty_json(vty, json);
597f4b1a
LK
1380 } else {
1381 if (output_count == 0)
1382 vty_out(vty, "No prefixes displayed, %ld exist\n",
1383 total_count);
1384 else
1385 vty_out(vty,
1386 "\nDisplayed %ld out of %ld total prefixes\n",
1387 output_count, total_count);
4d0e6ece 1388 }
4d0e6ece 1389 return CMD_SUCCESS;
784d3a42
PG
1390}
1391
4d0e6ece
PG
1392DEFUN(show_ip_bgp_l2vpn_evpn,
1393 show_ip_bgp_l2vpn_evpn_cmd,
1394 "show [ip] bgp l2vpn evpn [json]",
1395 SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR JSON_STR)
784d3a42 1396{
a111dd97
TA
1397 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL,
1398 SHOW_DISPLAY_STANDARD,
4d0e6ece 1399 use_json(argc, argv));
784d3a42
PG
1400}
1401
4d0e6ece
PG
1402DEFUN(show_ip_bgp_l2vpn_evpn_rd,
1403 show_ip_bgp_l2vpn_evpn_rd_cmd,
a111dd97 1404 "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
4d0e6ece
PG
1405 SHOW_STR
1406 IP_STR
1407 BGP_STR
1408 L2VPN_HELP_STR
1409 EVPN_HELP_STR
1410 "Display information for a route distinguisher\n"
a111dd97
TA
1411 "VPN Route Distinguisher\n"
1412 "All VPN Route Distinguishers\n"
1413 JSON_STR)
784d3a42 1414{
313605cb 1415 int idx_ext_community = 0;
4d0e6ece
PG
1416 int ret;
1417 struct prefix_rd prd;
a111dd97 1418 int rd_all = 0;
313605cb 1419
a111dd97
TA
1420 argv_find(argv, argc, "all", &rd_all);
1421 if (rd_all)
1422 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal,
1423 NULL, SHOW_DISPLAY_STANDARD,
1424 use_json(argc, argv));
10794c49 1425
a111dd97 1426 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
4d0e6ece
PG
1427 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1428 if (!ret) {
d62a17ae 1429 vty_out(vty, "%% Malformed Route Distinguisher\n");
4d0e6ece
PG
1430 return CMD_WARNING;
1431 }
a111dd97
TA
1432 return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL,
1433 SHOW_DISPLAY_STANDARD,
4d0e6ece 1434 use_json(argc, argv));
784d3a42
PG
1435}
1436
4d0e6ece
PG
1437DEFUN(show_ip_bgp_l2vpn_evpn_all_tags,
1438 show_ip_bgp_l2vpn_evpn_all_tags_cmd,
1439 "show [ip] bgp l2vpn evpn all tags",
1440 SHOW_STR
1441 IP_STR
1442 BGP_STR
1443 L2VPN_HELP_STR
1444 EVPN_HELP_STR
1445 "Display information about all EVPN NLRIs\n"
1446 "Display BGP tags for prefixes\n")
784d3a42 1447{
a111dd97
TA
1448 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL,
1449 SHOW_DISPLAY_TAGS, 0);
784d3a42
PG
1450}
1451
4d0e6ece
PG
1452DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags,
1453 show_ip_bgp_l2vpn_evpn_rd_tags_cmd,
a111dd97 1454 "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
4d0e6ece
PG
1455 SHOW_STR
1456 IP_STR
1457 BGP_STR
1458 L2VPN_HELP_STR
1459 EVPN_HELP_STR
1460 "Display information for a route distinguisher\n"
a111dd97
TA
1461 "VPN Route Distinguisher\n"
1462 "All VPN Route Distinguishers\n"
1463 "Display BGP tags for prefixes\n")
784d3a42 1464{
313605cb 1465 int idx_ext_community = 0;
4d0e6ece
PG
1466 int ret;
1467 struct prefix_rd prd;
a111dd97 1468 int rd_all = 0;
313605cb 1469
a111dd97
TA
1470 argv_find(argv, argc, "all", &rd_all);
1471 if (rd_all)
1472 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal,
1473 NULL, SHOW_DISPLAY_TAGS, 0);
10794c49 1474
a111dd97 1475 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
4d0e6ece
PG
1476 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1477 if (!ret) {
d62a17ae 1478 vty_out(vty, "%% Malformed Route Distinguisher\n");
4d0e6ece
PG
1479 return CMD_WARNING;
1480 }
a111dd97
TA
1481 return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL,
1482 SHOW_DISPLAY_TAGS, 0);
784d3a42
PG
1483}
1484
dcc1615e
DD
1485DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_routes,
1486 show_ip_bgp_l2vpn_evpn_neighbor_routes_cmd,
1487 "show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]",
4d0e6ece
PG
1488 SHOW_STR
1489 IP_STR
1490 BGP_STR
1491 L2VPN_HELP_STR
1492 EVPN_HELP_STR
4d0e6ece 1493 "Detailed information on TCP and BGP neighbor connections\n"
dcc1615e
DD
1494 "IPv4 Neighbor to display information about\n"
1495 "IPv6 Neighbor to display information about\n"
1496 "Neighbor on BGP configured interface\n"
4d0e6ece 1497 "Display routes learned from neighbor\n" JSON_STR)
784d3a42 1498{
dcc1615e 1499 int idx = 0;
4d0e6ece 1500 struct peer *peer;
dcc1615e 1501 char *peerstr = NULL;
9f049418 1502 bool uj = use_json(argc, argv);
dcc1615e
DD
1503 afi_t afi = AFI_L2VPN;
1504 safi_t safi = SAFI_EVPN;
1505 struct bgp *bgp = NULL;
4d0e6ece 1506
dcc1615e
DD
1507 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
1508 &bgp, uj);
1509 if (!idx) {
1510 vty_out(vty, "No index\n");
1511 return CMD_WARNING;
1512 }
1513
1514 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1515 argv_find(argv, argc, "neighbors", &idx);
1516 peerstr = argv[++idx]->arg;
313605cb 1517
dcc1615e
DD
1518 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
1519 if (!peer) {
4d0e6ece
PG
1520 if (uj) {
1521 json_object *json_no = NULL;
1522 json_no = json_object_new_object();
1523 json_object_string_add(json_no, "warning",
1524 "Malformed address");
d62a17ae 1525 vty_out(vty, "%s\n",
96ade3ed 1526 json_object_to_json_string(json_no));
4d0e6ece
PG
1527 json_object_free(json_no);
1528 } else
d62a17ae 1529 vty_out(vty, "Malformed address: %s\n",
dcc1615e 1530 argv[idx]->arg);
4d0e6ece
PG
1531 return CMD_WARNING;
1532 }
4d0e6ece
PG
1533 if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) {
1534 if (uj) {
1535 json_object *json_no = NULL;
1536 json_no = json_object_new_object();
d62a17ae 1537 json_object_string_add(
1538 json_no, "warning",
1539 "No such neighbor or address family");
1540 vty_out(vty, "%s\n",
96ade3ed 1541 json_object_to_json_string(json_no));
4d0e6ece
PG
1542 json_object_free(json_no);
1543 } else
d62a17ae 1544 vty_out(vty, "%% No such neighbor or address family\n");
4d0e6ece
PG
1545 return CMD_WARNING;
1546 }
1547
a111dd97
TA
1548 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor, peer,
1549 SHOW_DISPLAY_STANDARD, uj);
784d3a42
PG
1550}
1551
4d0e6ece
PG
1552DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
1553 show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd,
a111dd97 1554 "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]",
4d0e6ece
PG
1555 SHOW_STR
1556 IP_STR
1557 BGP_STR
1558 L2VPN_HELP_STR
1559 EVPN_HELP_STR
1560 "Display information for a route distinguisher\n"
1561 "VPN Route Distinguisher\n"
a111dd97 1562 "All VPN Route Distinguishers\n"
4d0e6ece 1563 "Detailed information on TCP and BGP neighbor connections\n"
dcc1615e
DD
1564 "IPv4 Neighbor to display information about\n"
1565 "IPv6 Neighbor to display information about\n"
1566 "Neighbor on BGP configured interface\n"
4d0e6ece 1567 "Display routes learned from neighbor\n" JSON_STR)
784d3a42 1568{
313605cb 1569 int idx_ext_community = 0;
dcc1615e 1570 int idx = 0;
4d0e6ece 1571 int ret;
4d0e6ece 1572 struct peer *peer;
dcc1615e 1573 char *peerstr = NULL;
4d0e6ece 1574 struct prefix_rd prd;
9f049418 1575 bool uj = use_json(argc, argv);
dcc1615e
DD
1576 afi_t afi = AFI_L2VPN;
1577 safi_t safi = SAFI_EVPN;
1578 struct bgp *bgp = NULL;
a111dd97 1579 int rd_all = 0;
4d0e6ece 1580
dcc1615e
DD
1581 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
1582 &bgp, uj);
1583 if (!idx) {
1584 vty_out(vty, "No index\n");
1585 return CMD_WARNING;
1586 }
313605cb 1587
a111dd97
TA
1588 argv_find(argv, argc, "all", &rd_all);
1589 if (!rd_all) {
1590 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
1591 &idx_ext_community);
1592 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1593 if (!ret) {
1594 if (uj) {
1595 json_object *json_no = NULL;
1596 json_no = json_object_new_object();
1597 json_object_string_add(
1598 json_no, "warning",
1599 "Malformed Route Distinguisher");
1600 vty_out(vty, "%s\n",
1601 json_object_to_json_string(json_no));
1602 json_object_free(json_no);
1603 } else
1604 vty_out(vty,
1605 "%% Malformed Route Distinguisher\n");
1606 return CMD_WARNING;
1607 }
4d0e6ece
PG
1608 }
1609
dcc1615e
DD
1610 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1611 argv_find(argv, argc, "neighbors", &idx);
1612 peerstr = argv[++idx]->arg;
1613
1614 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
1615 if (!peer) {
4d0e6ece
PG
1616 if (uj) {
1617 json_object *json_no = NULL;
1618 json_no = json_object_new_object();
1619 json_object_string_add(json_no, "warning",
1620 "Malformed address");
d62a17ae 1621 vty_out(vty, "%s\n",
96ade3ed 1622 json_object_to_json_string(json_no));
4d0e6ece
PG
1623 json_object_free(json_no);
1624 } else
d62a17ae 1625 vty_out(vty, "Malformed address: %s\n",
dcc1615e 1626 argv[idx]->arg);
4d0e6ece
PG
1627 return CMD_WARNING;
1628 }
4d0e6ece
PG
1629 if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) {
1630 if (uj) {
1631 json_object *json_no = NULL;
1632 json_no = json_object_new_object();
d62a17ae 1633 json_object_string_add(
1634 json_no, "warning",
1635 "No such neighbor or address family");
1636 vty_out(vty, "%s\n",
96ade3ed 1637 json_object_to_json_string(json_no));
4d0e6ece
PG
1638 json_object_free(json_no);
1639 } else
d62a17ae 1640 vty_out(vty, "%% No such neighbor or address family\n");
4d0e6ece
PG
1641 return CMD_WARNING;
1642 }
1643
a111dd97
TA
1644
1645 if (rd_all)
1646 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor,
1647 peer, SHOW_DISPLAY_STANDARD, uj);
1648 else
1649 return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_neighbor,
1650 peer, SHOW_DISPLAY_STANDARD, uj);
784d3a42
PG
1651}
1652
dcc1615e
DD
1653DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes,
1654 show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes_cmd,
1655 "show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]",
4d0e6ece
PG
1656 SHOW_STR
1657 IP_STR
1658 BGP_STR
1659 L2VPN_HELP_STR
1660 EVPN_HELP_STR
4d0e6ece 1661 "Detailed information on TCP and BGP neighbor connections\n"
dcc1615e
DD
1662 "IPv4 Neighbor to display information about\n"
1663 "IPv6 Neighbor to display information about\n"
1664 "Neighbor on BGP configured interface\n"
4d0e6ece 1665 "Display the routes advertised to a BGP neighbor\n" JSON_STR)
784d3a42 1666{
dcc1615e 1667 int idx = 0;
4d0e6ece 1668 struct peer *peer;
9f049418 1669 bool uj = use_json(argc, argv);
dcc1615e
DD
1670 struct bgp *bgp = NULL;
1671 afi_t afi = AFI_L2VPN;
1672 safi_t safi = SAFI_EVPN;
1673 char *peerstr = NULL;
1674
1675 if (uj)
1676 argc--;
4d0e6ece 1677
dcc1615e
DD
1678 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
1679 &bgp, uj);
1680 if (!idx) {
1681 vty_out(vty, "No index\n");
1682 return CMD_WARNING;
1683 }
1684
1685 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1686 argv_find(argv, argc, "neighbors", &idx);
1687 peerstr = argv[++idx]->arg;
313605cb 1688
dcc1615e
DD
1689 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
1690 if (!peer) {
4d0e6ece
PG
1691 if (uj) {
1692 json_object *json_no = NULL;
1693 json_no = json_object_new_object();
1694 json_object_string_add(json_no, "warning",
1695 "Malformed address");
d62a17ae 1696 vty_out(vty, "%s\n",
96ade3ed 1697 json_object_to_json_string(json_no));
4d0e6ece
PG
1698 json_object_free(json_no);
1699 } else
d62a17ae 1700 vty_out(vty, "Malformed address: %s\n",
dcc1615e 1701 argv[idx]->arg);
4d0e6ece
PG
1702 return CMD_WARNING;
1703 }
4d0e6ece
PG
1704 if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) {
1705 if (uj) {
1706 json_object *json_no = NULL;
1707 json_no = json_object_new_object();
d62a17ae 1708 json_object_string_add(
1709 json_no, "warning",
1710 "No such neighbor or address family");
1711 vty_out(vty, "%s\n",
96ade3ed 1712 json_object_to_json_string(json_no));
4d0e6ece
PG
1713 json_object_free(json_no);
1714 } else
d62a17ae 1715 vty_out(vty, "%% No such neighbor or address family\n");
4d0e6ece
PG
1716 return CMD_WARNING;
1717 }
1718
1719 return show_adj_route_vpn(vty, peer, NULL, AFI_L2VPN, SAFI_EVPN, uj);
784d3a42
PG
1720}
1721
4d0e6ece
PG
1722DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
1723 show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd,
a111dd97 1724 "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]",
4d0e6ece
PG
1725 SHOW_STR
1726 IP_STR
1727 BGP_STR
1728 L2VPN_HELP_STR
1729 EVPN_HELP_STR
1730 "Display information for a route distinguisher\n"
1731 "VPN Route Distinguisher\n"
a111dd97 1732 "All VPN Route Distinguishers\n"
4d0e6ece 1733 "Detailed information on TCP and BGP neighbor connections\n"
dcc1615e
DD
1734 "IPv4 Neighbor to display information about\n"
1735 "IPv6 Neighbor to display information about\n"
1736 "Neighbor on BGP configured interface\n"
4d0e6ece 1737 "Display the routes advertised to a BGP neighbor\n" JSON_STR)
784d3a42 1738{
313605cb 1739 int idx_ext_community = 0;
dcc1615e 1740 int idx = 0;
4d0e6ece
PG
1741 int ret;
1742 struct peer *peer;
1743 struct prefix_rd prd;
dcc1615e 1744 struct bgp *bgp = NULL;
9f049418 1745 bool uj = use_json(argc, argv);
dcc1615e
DD
1746 char *peerstr = NULL;
1747 afi_t afi = AFI_L2VPN;
1748 safi_t safi = SAFI_EVPN;
a111dd97 1749 int rd_all = 0;
dcc1615e
DD
1750
1751 if (uj)
1752 argc--;
1753
1754 if (uj)
1755 argc--;
1756
1757 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
1758 &bgp, uj);
1759 if (!idx) {
1760 vty_out(vty, "No index\n");
1761 return CMD_WARNING;
1762 }
4d0e6ece 1763
dcc1615e
DD
1764 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
1765 argv_find(argv, argc, "neighbors", &idx);
1766 peerstr = argv[++idx]->arg;
1767
1768 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
1769 if (!peer) {
4d0e6ece
PG
1770 if (uj) {
1771 json_object *json_no = NULL;
1772 json_no = json_object_new_object();
1773 json_object_string_add(json_no, "warning",
1774 "Malformed address");
d62a17ae 1775 vty_out(vty, "%s\n",
96ade3ed 1776 json_object_to_json_string(json_no));
4d0e6ece
PG
1777 json_object_free(json_no);
1778 } else
d62a17ae 1779 vty_out(vty, "Malformed address: %s\n",
dcc1615e 1780 argv[idx]->arg);
4d0e6ece
PG
1781 return CMD_WARNING;
1782 }
4d0e6ece
PG
1783 if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) {
1784 if (uj) {
1785 json_object *json_no = NULL;
1786 json_no = json_object_new_object();
d62a17ae 1787 json_object_string_add(
1788 json_no, "warning",
1789 "No such neighbor or address family");
1790 vty_out(vty, "%s\n",
96ade3ed 1791 json_object_to_json_string(json_no));
4d0e6ece
PG
1792 json_object_free(json_no);
1793 } else
d62a17ae 1794 vty_out(vty, "%% No such neighbor or address family\n");
4d0e6ece
PG
1795 return CMD_WARNING;
1796 }
1797
a111dd97
TA
1798 argv_find(argv, argc, "all", &rd_all);
1799 if (rd_all)
1800 return show_adj_route_vpn(vty, peer, NULL, AFI_L2VPN, SAFI_EVPN,
1801 uj);
1802 else {
1803 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
1804 &idx_ext_community);
1805 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1806 if (!ret) {
1807 if (uj) {
1808 json_object *json_no = NULL;
1809 json_no = json_object_new_object();
1810 json_object_string_add(
1811 json_no, "warning",
1812 "Malformed Route Distinguisher");
1813 vty_out(vty, "%s\n",
1814 json_object_to_json_string(json_no));
1815 json_object_free(json_no);
1816 } else
1817 vty_out(vty,
1818 "%% Malformed Route Distinguisher\n");
1819 return CMD_WARNING;
1820 }
4d0e6ece
PG
1821 }
1822
1823 return show_adj_route_vpn(vty, peer, &prd, AFI_L2VPN, SAFI_EVPN, uj);
784d3a42
PG
1824}
1825
4d0e6ece
PG
1826DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay,
1827 show_ip_bgp_l2vpn_evpn_all_overlay_cmd,
14f51eba 1828 "show [ip] bgp l2vpn evpn all overlay [json]",
4d0e6ece
PG
1829 SHOW_STR
1830 IP_STR
1831 BGP_STR
1832 L2VPN_HELP_STR
1833 EVPN_HELP_STR
1834 "Display information about all EVPN NLRIs\n"
14f51eba
LK
1835 "Display BGP Overlay Information for prefixes\n"
1836 JSON_STR)
784d3a42 1837{
4d0e6ece 1838 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL,
d62a17ae 1839 SHOW_DISPLAY_OVERLAY,
1840 use_json(argc, argv));
784d3a42
PG
1841}
1842
4d0e6ece
PG
1843DEFUN(show_ip_bgp_evpn_rd_overlay,
1844 show_ip_bgp_evpn_rd_overlay_cmd,
a111dd97 1845 "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> overlay",
4d0e6ece
PG
1846 SHOW_STR
1847 IP_STR
1848 BGP_STR
1849 L2VPN_HELP_STR
1850 EVPN_HELP_STR
1851 "Display information for a route distinguisher\n"
1852 "VPN Route Distinguisher\n"
a111dd97 1853 "All VPN Route Distinguishers\n"
4d0e6ece 1854 "Display BGP Overlay Information for prefixes\n")
784d3a42 1855{
313605cb 1856 int idx_ext_community = 0;
4d0e6ece
PG
1857 int ret;
1858 struct prefix_rd prd;
a111dd97 1859 int rd_all = 0;
313605cb 1860
a111dd97
TA
1861 argv_find(argv, argc, "all", &rd_all);
1862 if (rd_all)
1863 return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal,
1864 NULL, SHOW_DISPLAY_OVERLAY,
1865 use_json(argc, argv));
10794c49 1866
a111dd97 1867 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
4d0e6ece
PG
1868 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
1869 if (!ret) {
d62a17ae 1870 vty_out(vty, "%% Malformed Route Distinguisher\n");
4d0e6ece
PG
1871 return CMD_WARNING;
1872 }
1873 return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL,
d62a17ae 1874 SHOW_DISPLAY_OVERLAY,
1875 use_json(argc, argv));
784d3a42
PG
1876}
1877
7f433a5e
LK
1878DEFUN(show_bgp_l2vpn_evpn_com,
1879 show_bgp_l2vpn_evpn_com_cmd,
1880 "show bgp l2vpn evpn \
1881 <community AA:NN|large-community AA:BB:CC> \
1882 [exact-match] [json]",
1883 SHOW_STR
1884 BGP_STR
1885 L2VPN_HELP_STR
1886 EVPN_HELP_STR
1887 "Display routes matching the community\n"
1888 "Community number where AA and NN are (0-65535)\n"
1889 "Display routes matching the large-community\n"
1890 "List of large-community numbers\n"
1891 "Exact match of the communities\n"
1892 JSON_STR)
1893{
1894 int idx = 0;
1895 int ret = 0;
1896 const char *clist_number_or_name;
1897 int show_type = bgp_show_type_normal;
1898 struct community *com;
1899 struct lcommunity *lcom;
1900
1901 if (argv_find(argv, argc, "large-community", &idx)) {
1902 clist_number_or_name = argv[++idx]->arg;
1903 show_type = bgp_show_type_lcommunity;
1904
1905 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
1906 show_type = bgp_show_type_lcommunity_exact;
1907
1908 lcom = lcommunity_str2com(clist_number_or_name);
1909 if (!lcom) {
1910 vty_out(vty, "%% Large-community malformed\n");
1911 return CMD_WARNING;
1912 }
1913
1914 ret = bgp_show_ethernet_vpn(vty, NULL, show_type, lcom,
1915 SHOW_DISPLAY_STANDARD,
1916 use_json(argc, argv));
1917
1918 lcommunity_free(&lcom);
1919 } else if (argv_find(argv, argc, "community", &idx)) {
1920 clist_number_or_name = argv[++idx]->arg;
1921 show_type = bgp_show_type_community;
1922
1923 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
1924 show_type = bgp_show_type_community_exact;
1925
1926 com = community_str2com(clist_number_or_name);
1927
1928 if (!com) {
1929 vty_out(vty, "%% Community malformed: %s\n",
1930 clist_number_or_name);
1931 return CMD_WARNING;
1932 }
1933
1934 ret = bgp_show_ethernet_vpn(vty, NULL, show_type, com,
1935 SHOW_DISPLAY_STANDARD,
1936 use_json(argc, argv));
1937 community_free(&com);
1938 }
1939
1940 return ret;
1941}
1942
dcc1615e 1943/* For testing purpose, static route of EVPN RT-5. */
4d0e6ece
PG
1944DEFUN(evpnrt5_network,
1945 evpnrt5_network_cmd,
d114b977 1946 "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]",
4d0e6ece
PG
1947 "Specify a network to announce via BGP\n"
1948 "IP prefix\n"
1949 "IPv6 prefix\n"
1950 "Specify Route Distinguisher\n"
1951 "VPN Route Distinguisher\n"
1952 "Ethernet Tag\n"
1953 "Ethernet Tag Value\n"
1954 "BGP label\n"
1955 "label value\n"
1956 "Ethernet Segment Identifier\n"
1957 "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
1958 "Gateway IP\n"
1959 "Gateway IP ( A.B.C.D )\n"
1960 "Gateway IPv6 ( X:X::X:X )\n"
1961 "Router Mac Ext Comm\n"
55daa605
DS
1962 "Router Mac address Value ( aa:bb:cc:dd:ee:ff format)\n"
1963 "Route-map to modify the attributes\n"
1964 "Name of the route map\n")
3da6fcd5 1965{
4d0e6ece 1966 int idx_ipv4_prefixlen = 1;
197cb530
PG
1967 int idx_route_distinguisher = 3;
1968 int idx_label = 7;
4d0e6ece
PG
1969 int idx_esi = 9;
1970 int idx_gwip = 11;
1971 int idx_ethtag = 5;
1972 int idx_routermac = 13;
197cb530 1973
d62a17ae 1974 return bgp_static_set_safi(
1975 AFI_L2VPN, SAFI_EVPN, vty, argv[idx_ipv4_prefixlen]->arg,
996c9314 1976 argv[idx_route_distinguisher]->arg, argv[idx_label]->arg, NULL,
d62a17ae 1977 BGP_EVPN_IP_PREFIX_ROUTE, argv[idx_esi]->arg,
1978 argv[idx_gwip]->arg, argv[idx_ethtag]->arg,
1979 argv[idx_routermac]->arg);
3da6fcd5
PG
1980}
1981
dcc1615e 1982/* For testing purpose, static route of EVPN RT-5. */
4d0e6ece
PG
1983DEFUN(no_evpnrt5_network,
1984 no_evpnrt5_network_cmd,
d114b977 1985 "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>",
4d0e6ece
PG
1986 NO_STR
1987 "Specify a network to announce via BGP\n"
1988 "IP prefix\n"
1989 "IPv6 prefix\n"
1990 "Specify Route Distinguisher\n"
1991 "VPN Route Distinguisher\n"
1992 "Ethernet Tag\n"
1993 "Ethernet Tag Value\n"
1994 "BGP label\n"
1995 "label value\n"
1996 "Ethernet Segment Identifier\n"
1997 "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n"
1998 "Gateway IP\n" "Gateway IP ( A.B.C.D )\n" "Gateway IPv6 ( X:X::X:X )\n")
3da6fcd5 1999{
4d0e6ece
PG
2000 int idx_ipv4_prefixlen = 2;
2001 int idx_ext_community = 4;
2002 int idx_label = 8;
2003 int idx_ethtag = 6;
2004 int idx_esi = 10;
2005 int idx_gwip = 12;
d62a17ae 2006 return bgp_static_unset_safi(
2007 AFI_L2VPN, SAFI_EVPN, vty, argv[idx_ipv4_prefixlen]->arg,
2008 argv[idx_ext_community]->arg, argv[idx_label]->arg,
2009 BGP_EVPN_IP_PREFIX_ROUTE, argv[idx_esi]->arg,
2010 argv[idx_gwip]->arg, argv[idx_ethtag]->arg);
3da6fcd5
PG
2011}
2012
d62a17ae 2013static void evpn_import_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2014{
c581d8b0 2015 evpn_rt_delete_auto(bgp, vpn->vni, vpn->import_rtl);
90e60aa7 2016}
2017
d62a17ae 2018static void evpn_export_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2019{
c581d8b0 2020 evpn_rt_delete_auto(bgp, vpn->vni, vpn->export_rtl);
90e60aa7 2021}
2022
2023/*
2024 * Configure the Import RTs for a VNI (vty handler). Caller expected to
2025 * check that this is a change.
2026 */
d62a17ae 2027static void evpn_configure_import_rt(struct bgp *bgp, struct bgpevpn *vpn,
2028 struct ecommunity *ecomadd)
90e60aa7 2029{
d62a17ae 2030 /* If the VNI is "live", we need to uninstall routes using the current
2031 * import RT(s) first before we update the import RT, and subsequently
2032 * install routes.
2033 */
2034 if (is_vni_live(vpn))
2035 bgp_evpn_uninstall_routes(bgp, vpn);
90e60aa7 2036
d62a17ae 2037 /* Cleanup the RT to VNI mapping and get rid of existing import RT. */
2038 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
90e60aa7 2039
d62a17ae 2040 /* If the auto route-target is in use we must remove it */
2041 evpn_import_rt_delete_auto(bgp, vpn);
90e60aa7 2042
d62a17ae 2043 /* Add new RT and rebuild the RT to VNI mapping */
2044 listnode_add_sort(vpn->import_rtl, ecomadd);
90e60aa7 2045
d62a17ae 2046 SET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
2047 bgp_evpn_map_vni_to_its_rts(bgp, vpn);
90e60aa7 2048
d62a17ae 2049 /* Install routes that match new import RT */
2050 if (is_vni_live(vpn))
2051 bgp_evpn_install_routes(bgp, vpn);
90e60aa7 2052}
2053
2054/*
2055 * Unconfigure Import RT(s) for a VNI (vty handler).
2056 */
d62a17ae 2057static void evpn_unconfigure_import_rt(struct bgp *bgp, struct bgpevpn *vpn,
2058 struct ecommunity *ecomdel)
2059{
2060 struct listnode *node, *nnode, *node_to_del;
2061 struct ecommunity *ecom;
2062
2063 /* Along the lines of "configure" except we have to reset to the
2064 * automatic value.
2065 */
2066 if (is_vni_live(vpn))
2067 bgp_evpn_uninstall_routes(bgp, vpn);
2068
2069 /* Cleanup the RT to VNI mapping and get rid of existing import RT. */
2070 bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
2071
2072 /* Delete all import RTs */
2073 if (ecomdel == NULL) {
1b7db1df 2074 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
d62a17ae 2075 ecommunity_free(&ecom);
1b7db1df
KA
2076 list_delete_node(vpn->import_rtl, node);
2077 }
d62a17ae 2078 }
2079
2080 /* Delete a specific import RT */
2081 else {
2082 node_to_del = NULL;
2083
2084 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
2085 if (ecommunity_match(ecom, ecomdel)) {
2086 ecommunity_free(&ecom);
2087 node_to_del = node;
2088 break;
2089 }
2090 }
2091
2092 if (node_to_del)
2093 list_delete_node(vpn->import_rtl, node_to_del);
2094 }
2095
b3a4db3d 2096 assert(vpn->import_rtl);
d62a17ae 2097 /* Reset to auto RT - this also rebuilds the RT to VNI mapping */
2098 if (list_isempty(vpn->import_rtl)) {
2099 UNSET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
2100 bgp_evpn_derive_auto_rt_import(bgp, vpn);
2101 }
2102 /* Rebuild the RT to VNI mapping */
2103 else
2104 bgp_evpn_map_vni_to_its_rts(bgp, vpn);
2105
2106 /* Install routes that match new import RT */
2107 if (is_vni_live(vpn))
2108 bgp_evpn_install_routes(bgp, vpn);
90e60aa7 2109}
2110
2111/*
2112 * Configure the Export RT for a VNI (vty handler). Caller expected to
2113 * check that this is a change. Note that only a single export RT is
2114 * allowed for a VNI and any change to configuration is implemented as
2115 * a "replace" (similar to other configuration).
2116 */
d62a17ae 2117static void evpn_configure_export_rt(struct bgp *bgp, struct bgpevpn *vpn,
2118 struct ecommunity *ecomadd)
90e60aa7 2119{
d62a17ae 2120 /* If the auto route-target is in use we must remove it */
2121 evpn_export_rt_delete_auto(bgp, vpn);
90e60aa7 2122
d62a17ae 2123 listnode_add_sort(vpn->export_rtl, ecomadd);
2124 SET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
90e60aa7 2125
d62a17ae 2126 if (is_vni_live(vpn))
2127 bgp_evpn_handle_export_rt_change(bgp, vpn);
90e60aa7 2128}
2129
2130/*
2131 * Unconfigure the Export RT for a VNI (vty handler)
2132 */
d62a17ae 2133static void evpn_unconfigure_export_rt(struct bgp *bgp, struct bgpevpn *vpn,
2134 struct ecommunity *ecomdel)
2135{
2136 struct listnode *node, *nnode, *node_to_del;
2137 struct ecommunity *ecom;
2138
2139 /* Delete all export RTs */
2140 if (ecomdel == NULL) {
2141 /* Reset to default and process all routes. */
1b7db1df 2142 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom)) {
d62a17ae 2143 ecommunity_free(&ecom);
1b7db1df
KA
2144 list_delete_node(vpn->export_rtl, node);
2145 }
d62a17ae 2146 }
2147
2148 /* Delete a specific export RT */
2149 else {
2150 node_to_del = NULL;
2151
2152 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode, ecom)) {
2153 if (ecommunity_match(ecom, ecomdel)) {
2154 ecommunity_free(&ecom);
2155 node_to_del = node;
2156 break;
2157 }
2158 }
2159
2160 if (node_to_del)
2161 list_delete_node(vpn->export_rtl, node_to_del);
2162 }
2163
b3a4db3d 2164 assert(vpn->export_rtl);
d62a17ae 2165 if (list_isempty(vpn->export_rtl)) {
2166 UNSET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
2167 bgp_evpn_derive_auto_rt_export(bgp, vpn);
2168 }
2169
2170 if (is_vni_live(vpn))
2171 bgp_evpn_handle_export_rt_change(bgp, vpn);
90e60aa7 2172}
2173
676f83b9 2174/*
2175 * Configure RD for VRF
2176 */
996c9314 2177static void evpn_configure_vrf_rd(struct bgp *bgp_vrf, struct prefix_rd *rd)
676f83b9 2178{
2179 /* If we have already advertise type-5 routes with a diffrent RD, we
523cafc4 2180 * have to delete and withdraw them firs
2181 */
06d2e8f3 2182 bgp_evpn_handle_vrf_rd_change(bgp_vrf, 1);
676f83b9 2183
2184 /* update RD */
2185 memcpy(&bgp_vrf->vrf_prd, rd, sizeof(struct prefix_rd));
2186 SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD);
2187
2188 /* We have a new RD for VRF.
523cafc4 2189 * Advertise all type-5 routes again with the new RD
2190 */
06d2e8f3 2191 bgp_evpn_handle_vrf_rd_change(bgp_vrf, 0);
676f83b9 2192}
2193
2194/*
2195 * Unconfigure RD for VRF
2196 */
2197static void evpn_unconfigure_vrf_rd(struct bgp *bgp_vrf)
2198{
2199 /* If we have already advertise type-5 routes with a diffrent RD, we
523cafc4 2200 * have to delete and withdraw them firs
2201 */
06d2e8f3 2202 bgp_evpn_handle_vrf_rd_change(bgp_vrf, 1);
676f83b9 2203
2204 /* fall back to default RD */
2205 bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
99b4e972 2206 UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD);
676f83b9 2207
2208 /* We have a new RD for VRF.
523cafc4 2209 * Advertise all type-5 routes again with the new RD
2210 */
06d2e8f3 2211 bgp_evpn_handle_vrf_rd_change(bgp_vrf, 0);
676f83b9 2212}
2213
90e60aa7 2214/*
2215 * Configure RD for a VNI (vty handler)
2216 */
d62a17ae 2217static void evpn_configure_rd(struct bgp *bgp, struct bgpevpn *vpn,
2218 struct prefix_rd *rd)
90e60aa7 2219{
d62a17ae 2220 /* If the VNI is "live", we need to delete and withdraw this VNI's
2221 * local routes with the prior RD first. Then, after updating RD,
2222 * need to re-advertise.
2223 */
2224 if (is_vni_live(vpn))
2225 bgp_evpn_handle_rd_change(bgp, vpn, 1);
90e60aa7 2226
d62a17ae 2227 /* update RD */
2228 memcpy(&vpn->prd, rd, sizeof(struct prefix_rd));
2229 SET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
90e60aa7 2230
d62a17ae 2231 if (is_vni_live(vpn))
2232 bgp_evpn_handle_rd_change(bgp, vpn, 0);
90e60aa7 2233}
2234
2235/*
2236 * Unconfigure RD for a VNI (vty handler)
2237 */
d62a17ae 2238static void evpn_unconfigure_rd(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2239{
d62a17ae 2240 /* If the VNI is "live", we need to delete and withdraw this VNI's
2241 * local routes with the prior RD first. Then, after resetting RD
2242 * to automatic value, need to re-advertise.
2243 */
2244 if (is_vni_live(vpn))
2245 bgp_evpn_handle_rd_change(bgp, vpn, 1);
90e60aa7 2246
d62a17ae 2247 /* reset RD to default */
2248 bgp_evpn_derive_auto_rd(bgp, vpn);
90e60aa7 2249
d62a17ae 2250 if (is_vni_live(vpn))
2251 bgp_evpn_handle_rd_change(bgp, vpn, 0);
90e60aa7 2252}
2253
2254/*
2255 * Create VNI, if not already present (VTY handler). Mark as configured.
2256 */
d62a17ae 2257static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni)
90e60aa7 2258{
d62a17ae 2259 struct bgpevpn *vpn;
76d07c7a 2260 struct in_addr mcast_grp = {INADDR_ANY};
90e60aa7 2261
d62a17ae 2262 if (!bgp->vnihash)
2263 return NULL;
90e60aa7 2264
d62a17ae 2265 vpn = bgp_evpn_lookup_vni(bgp, vni);
2266 if (!vpn) {
7df407ed
CS
2267 /* Check if this L2VNI is already configured as L3VNI */
2268 if (bgp_evpn_lookup_l3vni_l2vni_table(vni)) {
1c50c1c0
QY
2269 flog_err(
2270 EC_BGP_VNI,
2271 "%u: Failed to create L2VNI %u, it is configured as L3VNI",
2272 bgp->vrf_id, vni);
7df407ed
CS
2273 return NULL;
2274 }
2275
29c53922 2276 /* tenant vrf will be updated when we get local_vni_add from
523cafc4 2277 * zebra
2278 */
9daa5d47 2279 vpn = bgp_evpn_new(bgp, vni, bgp->router_id, 0, mcast_grp, 0);
d62a17ae 2280 if (!vpn) {
af4c2728 2281 flog_err(
e50f7cfd 2282 EC_BGP_VNI,
d62a17ae 2283 "%u: Failed to allocate VNI entry for VNI %u - at Config",
2284 bgp->vrf_id, vni);
2285 return NULL;
2286 }
2287 }
90e60aa7 2288
d62a17ae 2289 /* Mark as configured. */
2290 SET_FLAG(vpn->flags, VNI_FLAG_CFGD);
2291 return vpn;
90e60aa7 2292}
2293
2294/*
2295 * Delete VNI. If VNI does not exist in the system (i.e., just
2296 * configuration), all that is needed is to free it. Otherwise,
2297 * any parameters configured for the VNI need to be reset (with
2298 * appropriate action) and the VNI marked as unconfigured; the
2299 * VNI will continue to exist, purely as a "learnt" entity.
2300 */
3dc339cd 2301static void evpn_delete_vni(struct bgp *bgp, struct bgpevpn *vpn)
90e60aa7 2302{
d62a17ae 2303 assert(bgp->vnihash);
90e60aa7 2304
d62a17ae 2305 if (!is_vni_live(vpn)) {
2306 bgp_evpn_free(bgp, vpn);
3dc339cd 2307 return;
d62a17ae 2308 }
90e60aa7 2309
d62a17ae 2310 /* We need to take the unconfigure action for each parameter of this VNI
2311 * that is configured. Some optimization is possible, but not worth the
2312 * additional code for an operation that should be pretty rare.
2313 */
2314 UNSET_FLAG(vpn->flags, VNI_FLAG_CFGD);
90e60aa7 2315
d62a17ae 2316 /* First, deal with the export side - RD and export RT changes. */
2317 if (is_rd_configured(vpn))
2318 evpn_unconfigure_rd(bgp, vpn);
2319 if (is_export_rt_configured(vpn))
2320 evpn_unconfigure_export_rt(bgp, vpn, NULL);
90e60aa7 2321
d62a17ae 2322 /* Next, deal with the import side. */
2323 if (is_import_rt_configured(vpn))
2324 evpn_unconfigure_import_rt(bgp, vpn, NULL);
90e60aa7 2325}
2326
10ebe1ab
MK
2327/*
2328 * Display import RT mapping to VRFs (vty handler)
5e53dce3 2329 * bgp_evpn: evpn bgp instance
10ebe1ab 2330 */
5e53dce3 2331static void evpn_show_vrf_import_rts(struct vty *vty, struct bgp *bgp_evpn,
10ebe1ab
MK
2332 json_object *json)
2333{
2334 void *args[2];
2335
2336 args[0] = vty;
2337 args[1] = json;
2338
5e53dce3 2339 hash_iterate(bgp_evpn->vrf_import_rt_hash,
e3b78da8 2340 (void (*)(struct hash_bucket *,
996c9314 2341 void *))show_vrf_import_rt_entry,
10ebe1ab
MK
2342 args);
2343}
2344
520d5d76 2345/*
2346 * Display import RT mapping to VNIs (vty handler)
2347 */
9c92b5f7
MK
2348static void evpn_show_import_rts(struct vty *vty, struct bgp *bgp,
2349 json_object *json)
520d5d76 2350{
9c92b5f7
MK
2351 void *args[2];
2352
2353 args[0] = vty;
2354 args[1] = json;
2355
d62a17ae 2356 hash_iterate(
2357 bgp->import_rt_hash,
e3b78da8 2358 (void (*)(struct hash_bucket *, void *))show_import_rt_entry,
9c92b5f7 2359 args);
520d5d76 2360}
2361
2362/*
2363 * Display EVPN routes for all VNIs - vty handler.
2364 */
d62a17ae 2365static void evpn_show_routes_vni_all(struct vty *vty, struct bgp *bgp,
c7ef6cf2
NS
2366 struct in_addr vtep_ip, json_object *json,
2367 int detail)
520d5d76 2368{
d7c0a89a 2369 uint32_t num_vnis;
d62a17ae 2370 struct vni_walk_ctx wctx;
520d5d76 2371
d62a17ae 2372 num_vnis = hashcount(bgp->vnihash);
2373 if (!num_vnis)
2374 return;
2375 memset(&wctx, 0, sizeof(struct vni_walk_ctx));
2376 wctx.bgp = bgp;
2377 wctx.vty = vty;
2378 wctx.vtep_ip = vtep_ip;
9c92b5f7 2379 wctx.json = json;
c7ef6cf2 2380 wctx.detail = detail;
e3b78da8 2381 hash_iterate(bgp->vnihash, (void (*)(struct hash_bucket *,
9d303b37
DL
2382 void *))show_vni_routes_hash,
2383 &wctx);
520d5d76 2384}
2385
2386/*
2387 * Display EVPN routes for a VNI -- for specific type-3 route (vty handler).
2388 */
d62a17ae 2389static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
9c92b5f7
MK
2390 vni_t vni, struct in_addr orig_ip,
2391 json_object *json)
d62a17ae 2392{
2393 struct bgpevpn *vpn;
2394 struct prefix_evpn p;
9bcb3eef 2395 struct bgp_dest *dest;
40381db7 2396 struct bgp_path_info *pi;
d7c0a89a 2397 uint32_t path_cnt = 0;
d62a17ae 2398 afi_t afi;
2399 safi_t safi;
9c92b5f7 2400 json_object *json_paths = NULL;
d62a17ae 2401
2402 afi = AFI_L2VPN;
2403 safi = SAFI_EVPN;
2404
2405 /* Locate VNI. */
2406 vpn = bgp_evpn_lookup_vni(bgp, vni);
2407 if (!vpn) {
2408 vty_out(vty, "VNI not found\n");
2409 return;
2410 }
2411
2412 /* See if route exists. */
2413 build_evpn_type3_prefix(&p, orig_ip);
9bcb3eef
DS
2414 dest = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
2415 if (!dest || !bgp_dest_has_bgp_path_info_data(dest)) {
9c92b5f7
MK
2416 if (!json)
2417 vty_out(vty, "%% Network not in table\n");
e71ad4b6
DA
2418
2419 if (dest)
2420 bgp_dest_unlock_node(dest);
2421
d62a17ae 2422 return;
2423 }
2424
9c92b5f7
MK
2425 if (json)
2426 json_paths = json_object_new_array();
2427
d62a17ae 2428 /* Prefix and num paths displayed once per prefix. */
9bcb3eef 2429 route_vty_out_detail_header(vty, bgp, dest, NULL, afi, safi, json);
d62a17ae 2430
2431 /* Display each path for this prefix. */
9bcb3eef 2432 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
9c92b5f7
MK
2433 json_object *json_path = NULL;
2434
2435 if (json)
2436 json_path = json_object_new_array();
2437
4933eaaf
DS
2438 route_vty_out_detail(vty, bgp, dest, pi, afi, safi,
2439 RPKI_NOT_BEING_USED, json_path);
9c92b5f7
MK
2440
2441 if (json)
2442 json_object_array_add(json_paths, json_path);
2443
d62a17ae 2444 path_cnt++;
2445 }
2446
9c92b5f7
MK
2447 if (json) {
2448 if (path_cnt)
2449 json_object_object_add(json, "paths", json_paths);
2450
2451 json_object_int_add(json, "numPaths", path_cnt);
2452 } else {
2453 vty_out(vty, "\nDisplayed %u paths for requested prefix\n",
2454 path_cnt);
2455 }
e71ad4b6
DA
2456
2457 bgp_dest_unlock_node(dest);
520d5d76 2458}
2459
2460/*
2461 * Display EVPN routes for a VNI -- for specific MAC and/or IP (vty handler).
2462 * By definition, only matching type-2 route will be displayed.
2463 */
d62a17ae 2464static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
2465 vni_t vni, struct ethaddr *mac,
9c92b5f7 2466 struct ipaddr *ip, json_object *json)
d62a17ae 2467{
2468 struct bgpevpn *vpn;
2469 struct prefix_evpn p;
9bcb3eef 2470 struct bgp_dest *dest;
40381db7 2471 struct bgp_path_info *pi;
d7c0a89a 2472 uint32_t path_cnt = 0;
d62a17ae 2473 afi_t afi;
2474 safi_t safi;
9c92b5f7 2475 json_object *json_paths = NULL;
d62a17ae 2476
2477 afi = AFI_L2VPN;
2478 safi = SAFI_EVPN;
2479
2480 /* Locate VNI. */
2481 vpn = bgp_evpn_lookup_vni(bgp, vni);
2482 if (!vpn) {
9c92b5f7
MK
2483 if (!json)
2484 vty_out(vty, "VNI not found\n");
d62a17ae 2485 return;
2486 }
2487
2488 /* See if route exists. Look for both non-sticky and sticky. */
2489 build_evpn_type2_prefix(&p, mac, ip);
9bcb3eef
DS
2490 dest = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
2491 if (!dest || !bgp_dest_has_bgp_path_info_data(dest)) {
9c92b5f7
MK
2492 if (!json)
2493 vty_out(vty, "%% Network not in table\n");
e71ad4b6
DA
2494
2495 if (dest)
2496 bgp_dest_unlock_node(dest);
2497
d62a17ae 2498 return;
2499 }
2500
9c92b5f7
MK
2501 if (json)
2502 json_paths = json_object_new_array();
2503
d62a17ae 2504 /* Prefix and num paths displayed once per prefix. */
9bcb3eef 2505 route_vty_out_detail_header(vty, bgp, dest, NULL, afi, safi, json);
d62a17ae 2506
2507 /* Display each path for this prefix. */
9bcb3eef 2508 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
9c92b5f7
MK
2509 json_object *json_path = NULL;
2510
2511 if (json)
2512 json_path = json_object_new_array();
2513
4933eaaf
DS
2514 route_vty_out_detail(vty, bgp, dest, pi, afi, safi,
2515 RPKI_NOT_BEING_USED, json_path);
9c92b5f7
MK
2516
2517 if (json)
2518 json_object_array_add(json_paths, json_path);
2519
d62a17ae 2520 path_cnt++;
2521 }
2522
9c92b5f7
MK
2523 if (json) {
2524 if (path_cnt)
2525 json_object_object_add(json, "paths", json_paths);
2526
2527 json_object_int_add(json, "numPaths", path_cnt);
2528 } else {
2529 vty_out(vty, "\nDisplayed %u paths for requested prefix\n",
2530 path_cnt);
2531 }
e71ad4b6
DA
2532
2533 bgp_dest_unlock_node(dest);
520d5d76 2534}
2535
50f74cf1 2536/* Disaplay EVPN routes for a ESI - VTY handler */
2537static void evpn_show_routes_esi(struct vty *vty, struct bgp *bgp,
2538 esi_t *esi, json_object *json)
2539{
b5e140c8 2540 struct bgp_evpn_es *es = NULL;
50f74cf1 2541
2542 /* locate the ES */
b5e140c8 2543 es = bgp_evpn_es_find(esi);
50f74cf1 2544 if (!es) {
2545 if (!json)
2546 vty_out(vty, "ESI not found\n");
2547 return;
2548 }
2549
2550 show_esi_routes(bgp, es, vty, json);
2551}
2552
520d5d76 2553/*
2554 * Display EVPN routes for a VNI - vty handler.
2555 * If 'type' is non-zero, only routes matching that type are shown.
2556 * If the vtep_ip is non zero, only routes behind that vtep are shown
2557 */
d62a17ae 2558static void evpn_show_routes_vni(struct vty *vty, struct bgp *bgp, vni_t vni,
9c92b5f7
MK
2559 int type, struct in_addr vtep_ip,
2560 json_object *json)
520d5d76 2561{
d62a17ae 2562 struct bgpevpn *vpn;
520d5d76 2563
d62a17ae 2564 /* Locate VNI. */
2565 vpn = bgp_evpn_lookup_vni(bgp, vni);
2566 if (!vpn) {
9c92b5f7
MK
2567 if (!json)
2568 vty_out(vty, "VNI not found\n");
d62a17ae 2569 return;
2570 }
520d5d76 2571
d62a17ae 2572 /* Walk this VNI's route table and display appropriate routes. */
c7ef6cf2 2573 show_vni_routes(bgp, vpn, type, vty, vtep_ip, json, 0);
520d5d76 2574}
2575
2576/*
2577 * Display BGP EVPN routing table -- for specific RD and MAC and/or
2578 * IP (vty handler). By definition, only matching type-2 route will be
2579 * displayed.
2580 */
d62a17ae 2581static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
2582 struct prefix_rd *prd, struct ethaddr *mac,
9c92b5f7 2583 struct ipaddr *ip, json_object *json)
d62a17ae 2584{
2585 struct prefix_evpn p;
9bcb3eef 2586 struct bgp_dest *dest;
40381db7 2587 struct bgp_path_info *pi;
d62a17ae 2588 afi_t afi;
2589 safi_t safi;
d7c0a89a 2590 uint32_t path_cnt = 0;
9c92b5f7
MK
2591 json_object *json_paths = NULL;
2592 char prefix_str[BUFSIZ];
d62a17ae 2593
2594 afi = AFI_L2VPN;
2595 safi = SAFI_EVPN;
2596
2597 /* See if route exists. Look for both non-sticky and sticky. */
2598 build_evpn_type2_prefix(&p, mac, ip);
9bcb3eef
DS
2599 dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
2600 (struct prefix *)&p, prd);
2601 if (!dest || !bgp_dest_has_bgp_path_info_data(dest)) {
9c92b5f7
MK
2602 if (!json)
2603 vty_out(vty, "%% Network not in table\n");
e71ad4b6
DA
2604
2605 if (dest)
2606 bgp_dest_unlock_node(dest);
2607
d62a17ae 2608 return;
2609 }
2610
f137734b 2611 prefix2str(&p, prefix_str, sizeof(prefix_str));
9c92b5f7 2612
d62a17ae 2613 /* Prefix and num paths displayed once per prefix. */
9bcb3eef 2614 route_vty_out_detail_header(vty, bgp, dest, prd, afi, safi, json);
9c92b5f7
MK
2615
2616 if (json)
2617 json_paths = json_object_new_array();
d62a17ae 2618
2619 /* Display each path for this prefix. */
9bcb3eef 2620 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
9c92b5f7
MK
2621 json_object *json_path = NULL;
2622
2623 if (json)
2624 json_path = json_object_new_array();
2625
4933eaaf
DS
2626 route_vty_out_detail(vty, bgp, dest, pi, afi, safi,
2627 RPKI_NOT_BEING_USED, json_path);
9c92b5f7
MK
2628
2629 if (json)
2630 json_object_array_add(json_paths, json_path);
2631
d62a17ae 2632 path_cnt++;
2633 }
2634
9c92b5f7
MK
2635 if (json && path_cnt) {
2636 if (path_cnt)
2637 json_object_object_add(json, prefix_str, json_paths);
2638 json_object_int_add(json, "numPaths", path_cnt);
2639 } else {
2640 vty_out(vty, "\nDisplayed %u paths for requested prefix\n",
2641 path_cnt);
2642 }
e71ad4b6
DA
2643
2644 bgp_dest_unlock_node(dest);
520d5d76 2645}
2646
2647/*
2648 * Display BGP EVPN routing table -- for specific RD (vty handler)
2649 * If 'type' is non-zero, only routes matching that type are shown.
2650 */
d62a17ae 2651static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
9c92b5f7
MK
2652 struct prefix_rd *prd, int type,
2653 json_object *json)
d62a17ae 2654{
9bcb3eef 2655 struct bgp_dest *rd_dest;
d62a17ae 2656 struct bgp_table *table;
9bcb3eef 2657 struct bgp_dest *dest;
40381db7 2658 struct bgp_path_info *pi;
d62a17ae 2659 int rd_header = 1;
2660 afi_t afi;
2661 safi_t safi;
d7c0a89a 2662 uint32_t prefix_cnt, path_cnt;
9c92b5f7
MK
2663 char rd_str[RD_ADDRSTRLEN];
2664 json_object *json_rd = NULL;
2665 int add_rd_to_json = 0;
d62a17ae 2666
2667 afi = AFI_L2VPN;
2668 safi = SAFI_EVPN;
2669 prefix_cnt = path_cnt = 0;
2670
c4efd0f4 2671 prefix_rd2str(prd, rd_str, sizeof(rd_str));
9c92b5f7 2672
9bcb3eef
DS
2673 rd_dest = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)prd);
2674 if (!rd_dest)
d62a17ae 2675 return;
9c92b5f7 2676
9bcb3eef 2677 table = bgp_dest_get_bgp_table_info(rd_dest);
e71ad4b6
DA
2678 if (table == NULL) {
2679 bgp_dest_unlock_node(rd_dest);
d62a17ae 2680 return;
e71ad4b6 2681 }
d62a17ae 2682
9c92b5f7
MK
2683 if (json) {
2684 json_rd = json_object_new_object();
2685 json_object_string_add(json_rd, "rd", rd_str);
2686 }
2687
e71ad4b6
DA
2688 bgp_dest_unlock_node(rd_dest);
2689
d62a17ae 2690 /* Display all prefixes with this RD. */
9bcb3eef 2691 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
b54892e0 2692 const struct prefix_evpn *evp =
9bcb3eef 2693 (const struct prefix_evpn *)bgp_dest_get_prefix(dest);
9c92b5f7
MK
2694 json_object *json_prefix = NULL;
2695 json_object *json_paths = NULL;
2696 char prefix_str[BUFSIZ];
2697 int add_prefix_to_json = 0;
2698
f137734b
PR
2699 prefix2str((struct prefix_evpn *)evp, prefix_str,
2700 sizeof(prefix_str));
d62a17ae 2701
2702 if (type && evp->prefix.route_type != type)
2703 continue;
2704
9c92b5f7
MK
2705 if (json)
2706 json_prefix = json_object_new_object();
2707
9bcb3eef 2708 pi = bgp_dest_get_bgp_path_info(dest);
6f94b685 2709 if (pi) {
d62a17ae 2710 /* RD header and legend - once overall. */
9c92b5f7 2711 if (rd_header && !json) {
6c111b51 2712 vty_out(vty,
0a5c5f13 2713 "EVPN type-1 prefix: [1]:[EthTag]:[ESI]:[IPlen]:[VTEP-IP]\n");
d62a17ae 2714 vty_out(vty,
554cd77a 2715 "EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]\n");
d62a17ae 2716 vty_out(vty,
342dd0c6 2717 "EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]\n");
6c111b51
AK
2718 vty_out(vty,
2719 "EVPN type-4 prefix: [4]:[ESI]:[IPlen]:[OrigIP]\n");
342dd0c6 2720 vty_out(vty,
554cd77a 2721 "EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]\n\n");
d62a17ae 2722 rd_header = 0;
2723 }
2724
2725 /* Prefix and num paths displayed once per prefix. */
9bcb3eef 2726 route_vty_out_detail_header(vty, bgp, dest, prd, afi,
9c92b5f7 2727 safi, json_prefix);
d62a17ae 2728
2729 prefix_cnt++;
2730 }
2731
9c92b5f7
MK
2732 if (json)
2733 json_paths = json_object_new_array();
2734
d62a17ae 2735 /* Display each path for this prefix. */
6f94b685 2736 for (; pi; pi = pi->next) {
9c92b5f7
MK
2737 json_object *json_path = NULL;
2738
2739 if (json)
2740 json_path = json_object_new_array();
2741
9bcb3eef 2742 route_vty_out_detail(vty, bgp, dest, pi, afi, safi,
4933eaaf 2743 RPKI_NOT_BEING_USED, json_path);
9c92b5f7
MK
2744
2745 if (json)
2746 json_object_array_add(json_paths, json_path);
2747
d62a17ae 2748 path_cnt++;
9c92b5f7
MK
2749 add_prefix_to_json = 1;
2750 add_rd_to_json = 1;
2751 }
2752
a1df2ac5
CS
2753 if (json) {
2754 if (add_prefix_to_json) {
2755 json_object_object_add(json_prefix, "paths",
2756 json_paths);
2757 json_object_object_add(json_rd, prefix_str,
2758 json_prefix);
2759 } else {
2760 json_object_free(json_paths);
2761 json_object_free(json_prefix);
2762 json_paths = NULL;
2763 json_prefix = NULL;
2764 }
d62a17ae 2765 }
2766 }
2767
9c92b5f7 2768 if (json) {
a1df2ac5
CS
2769 if (add_rd_to_json)
2770 json_object_object_add(json, rd_str, json_rd);
2771 else {
2772 json_object_free(json_rd);
2773 json_rd = NULL;
2774 }
2775
9c92b5f7
MK
2776 json_object_int_add(json, "numPrefix", prefix_cnt);
2777 json_object_int_add(json, "numPaths", path_cnt);
2778 } else {
2779 if (prefix_cnt == 0)
2780 vty_out(vty, "No prefixes exist with this RD%s\n",
2781 type ? " (of requested type)" : "");
2782 else
2783 vty_out(vty,
2784 "\nDisplayed %u prefixes (%u paths) with this RD%s\n",
2785 prefix_cnt, path_cnt,
2786 type ? " (of requested type)" : "");
2787 }
520d5d76 2788}
2789
a111dd97
TA
2790/*
2791 * Display BGP EVPN routing table -- all RDs and MAC and/or IP
2792 * (vty handler). Only matching type-2 routes will be displayed.
2793 */
2794static void evpn_show_route_rd_all_macip(struct vty *vty, struct bgp *bgp,
2795 struct ethaddr *mac, struct ipaddr *ip,
2796 json_object *json)
2797{
2798 struct bgp_dest *rd_dest;
2799 struct bgp_table *table;
2800 struct bgp_dest *dest;
2801 struct bgp_path_info *pi;
2802 afi_t afi = AFI_L2VPN;
2803 safi_t safi = SAFI_EVPN;
2804 uint32_t prefix_cnt, path_cnt;
2805 prefix_cnt = path_cnt = 0;
2806
2807 /* EVPN routing table is a 2-level table with the first level being
2808 * the RD. We need to look in every RD we know about.
2809 */
2810 for (rd_dest = bgp_table_top(bgp->rib[afi][safi]); rd_dest;
2811 rd_dest = bgp_route_next(rd_dest)) {
2812 json_object *json_paths = NULL; /* paths array for prefix */
2813 json_object *json_prefix = NULL; /* prefix within an RD */
2814 json_object *json_rd = NULL; /* holds all prefixes for RD */
2815 char rd_str[RD_ADDRSTRLEN];
2816 char prefix_str[BUFSIZ];
2817 int add_rd_to_json = 0;
2818 struct prefix_evpn ep;
2819 const struct prefix *rd_destp = bgp_dest_get_prefix(rd_dest);
2820
2821 table = bgp_dest_get_bgp_table_info(rd_dest);
2822 if (table == NULL)
2823 continue;
2824
2825 prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
2826 sizeof(rd_str));
2827
2828 /* Construct an RT-2 from the user-supplied mac(ip),
2829 * then search the l2vpn evpn table for it.
2830 */
2831 build_evpn_type2_prefix(&ep, mac, ip);
2832 dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
2833 (struct prefix *)&ep,
2834 (struct prefix_rd *)rd_destp);
2835 if (!dest)
2836 continue;
2837
2838 if (json)
2839 json_rd = json_object_new_object();
2840
2841 const struct prefix *p = bgp_dest_get_prefix(dest);
2842
2843 prefix2str(p, prefix_str, sizeof(prefix_str));
2844
2845 pi = bgp_dest_get_bgp_path_info(dest);
2846 if (pi) {
2847 /* RD header - per RD. */
2848 bgp_evpn_show_route_rd_header(vty, rd_dest, json_rd,
2849 rd_str, RD_ADDRSTRLEN);
2850 prefix_cnt++;
2851 }
2852
2853 if (json) {
2854 json_prefix = json_object_new_object();
2855 json_paths = json_object_new_array();
2856 json_object_string_add(json_prefix, "prefix",
2857 prefix_str);
2858 json_object_int_add(json_prefix, "prefixLen",
2859 p->prefixlen);
2860 } else
2861 /* Prefix and num paths displayed once per prefix. */
2862 route_vty_out_detail_header(
2863 vty, bgp, dest, (struct prefix_rd *)rd_destp,
2864 AFI_L2VPN, SAFI_EVPN, json_prefix);
2865
2866 /* For EVPN, the prefix is displayed for each path (to
2867 * fit in with code that already exists).
2868 */
2869 for (; pi; pi = pi->next) {
2870 json_object *json_path = NULL;
2871
2872 add_rd_to_json = 1;
2873 path_cnt++;
2874
2875 if (json)
2876 json_path = json_object_new_array();
2877
2878 route_vty_out_detail(vty, bgp, dest, pi, AFI_L2VPN,
2879 SAFI_EVPN, RPKI_NOT_BEING_USED,
2880 json_path);
2881
2882 if (json)
2883 json_object_array_add(json_paths, json_path);
2884 else
2885 vty_out(vty, "\n");
2886 }
2887
2888 if (json) {
2889 json_object_object_add(json_prefix, "paths",
2890 json_paths);
2891 json_object_object_add(json_rd, prefix_str,
2892 json_prefix);
2893 if (add_rd_to_json)
2894 json_object_object_add(json, rd_str, json_rd);
2895 else {
2896 json_object_free(json_rd);
2897 json_rd = NULL;
2898 }
2899 }
e71ad4b6
DA
2900
2901 bgp_dest_unlock_node(dest);
a111dd97
TA
2902 }
2903
2904 if (json) {
2905 json_object_int_add(json, "numPrefix", prefix_cnt);
2906 json_object_int_add(json, "numPaths", path_cnt);
2907 } else {
2908 if (prefix_cnt == 0) {
2909 vty_out(vty, "No Matching EVPN prefixes exist\n");
2910 } else {
2911 vty_out(vty, "Displayed %u prefixes (%u paths)\n",
2912 prefix_cnt, path_cnt);
2913 }
2914 }
2915}
2916
520d5d76 2917/*
2918 * Display BGP EVPN routing table - all routes (vty handler).
2919 * If 'type' is non-zero, only routes matching that type are shown.
2920 */
9c92b5f7 2921static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
21f3551e 2922 json_object *json, int detail)
d62a17ae 2923{
9bcb3eef 2924 struct bgp_dest *rd_dest;
d62a17ae 2925 struct bgp_table *table;
9bcb3eef 2926 struct bgp_dest *dest;
40381db7 2927 struct bgp_path_info *pi;
21f3551e 2928 int header = detail ? 0 : 1;
d62a17ae 2929 int rd_header;
2930 afi_t afi;
2931 safi_t safi;
d7c0a89a 2932 uint32_t prefix_cnt, path_cnt;
d62a17ae 2933
2934 afi = AFI_L2VPN;
2935 safi = SAFI_EVPN;
2936 prefix_cnt = path_cnt = 0;
2937
2938 /* EVPN routing table is a 2-level table with the first level being
2939 * the RD.
2940 */
9bcb3eef
DS
2941 for (rd_dest = bgp_table_top(bgp->rib[afi][safi]); rd_dest;
2942 rd_dest = bgp_route_next(rd_dest)) {
9c92b5f7
MK
2943 char rd_str[RD_ADDRSTRLEN];
2944 json_object *json_rd = NULL; /* contains routes for an RD */
2945 int add_rd_to_json = 0;
2dd32217 2946 uint64_t tbl_ver;
9bcb3eef 2947 const struct prefix *rd_destp = bgp_dest_get_prefix(rd_dest);
9c92b5f7 2948
9bcb3eef 2949 table = bgp_dest_get_bgp_table_info(rd_dest);
d62a17ae 2950 if (table == NULL)
2951 continue;
2952
2dd32217 2953 tbl_ver = table->version;
9bcb3eef 2954 prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
9c92b5f7
MK
2955 sizeof(rd_str));
2956
90c31d71 2957 if (json)
9c92b5f7 2958 json_rd = json_object_new_object();
9c92b5f7 2959
d62a17ae 2960 rd_header = 1;
2961
2962 /* Display all prefixes for an RD */
9bcb3eef
DS
2963 for (dest = bgp_table_top(table); dest;
2964 dest = bgp_route_next(dest)) {
9c92b5f7
MK
2965 json_object *json_prefix =
2966 NULL; /* contains prefix under a RD */
2967 json_object *json_paths =
2968 NULL; /* array of paths under a prefix*/
b54892e0 2969 const struct prefix_evpn *evp =
9bcb3eef
DS
2970 (const struct prefix_evpn *)bgp_dest_get_prefix(
2971 dest);
9c92b5f7
MK
2972 char prefix_str[BUFSIZ];
2973 int add_prefix_to_json = 0;
9bcb3eef 2974 const struct prefix *p = bgp_dest_get_prefix(dest);
9c92b5f7 2975
f137734b
PR
2976 prefix2str((struct prefix_evpn *)p, prefix_str,
2977 sizeof(prefix_str));
d62a17ae 2978
2979 if (type && evp->prefix.route_type != type)
2980 continue;
2981
9bcb3eef 2982 pi = bgp_dest_get_bgp_path_info(dest);
6f94b685 2983 if (pi) {
d62a17ae 2984 /* Overall header/legend displayed once. */
2985 if (header) {
9c92b5f7 2986 bgp_evpn_show_route_header(vty, bgp,
2dd32217 2987 tbl_ver,
9c92b5f7 2988 json);
c684d477
CS
2989 if (!json)
2990 vty_out(vty,
2991 "%19s Extended Community\n"
6f214dd3 2992 , " ");
d62a17ae 2993 header = 0;
2994 }
2995
2996 /* RD header - per RD. */
2997 if (rd_header) {
9c92b5f7 2998 bgp_evpn_show_route_rd_header(
9bcb3eef 2999 vty, rd_dest, json_rd, rd_str,
c69e79f1 3000 RD_ADDRSTRLEN);
d62a17ae 3001 rd_header = 0;
3002 }
3003
3004 prefix_cnt++;
3005 }
3006
9c92b5f7
MK
3007 if (json) {
3008 json_prefix = json_object_new_object();
3009 json_paths = json_object_new_array();
3010 json_object_string_add(json_prefix, "prefix",
3011 prefix_str);
3012 json_object_int_add(json_prefix, "prefixLen",
b54892e0 3013 p->prefixlen);
9c92b5f7
MK
3014 }
3015
21f3551e
NS
3016 /* Prefix and num paths displayed once per prefix. */
3017 if (detail)
3018 route_vty_out_detail_header(
9bcb3eef
DS
3019 vty, bgp, dest,
3020 (struct prefix_rd *)rd_destp, AFI_L2VPN,
b54892e0 3021 SAFI_EVPN, json_prefix);
21f3551e 3022
d62a17ae 3023 /* For EVPN, the prefix is displayed for each path (to
3024 * fit in
3025 * with code that already exists).
3026 */
6f94b685 3027 for (; pi; pi = pi->next) {
9c92b5f7 3028 json_object *json_path = NULL;
a111dd97 3029
d62a17ae 3030 path_cnt++;
9c92b5f7
MK
3031 add_prefix_to_json = 1;
3032 add_rd_to_json = 1;
3033
3034 if (json)
3035 json_path = json_object_new_array();
3036
21f3551e
NS
3037 if (detail) {
3038 route_vty_out_detail(
9bcb3eef 3039 vty, bgp, dest, pi, AFI_L2VPN,
4933eaaf
DS
3040 SAFI_EVPN, RPKI_NOT_BEING_USED,
3041 json_path);
21f3551e 3042 } else
b54892e0 3043 route_vty_out(vty, p, pi, 0, SAFI_EVPN,
ae248832 3044 json_path, false);
9c92b5f7
MK
3045
3046 if (json)
3047 json_object_array_add(json_paths,
3048 json_path);
3049 }
3050
a1df2ac5
CS
3051 if (json) {
3052 if (add_prefix_to_json) {
3053 json_object_object_add(json_prefix,
3054 "paths",
3055 json_paths);
3056 json_object_object_add(json_rd,
3057 prefix_str,
3058 json_prefix);
3059 } else {
3060 json_object_free(json_prefix);
3061 json_object_free(json_paths);
3062 json_prefix = NULL;
3063 json_paths = NULL;
3064 }
d62a17ae 3065 }
3066 }
9c92b5f7 3067
a1df2ac5
CS
3068 if (json) {
3069 if (add_rd_to_json)
3070 json_object_object_add(json, rd_str, json_rd);
3071 else {
3072 json_object_free(json_rd);
3073 json_rd = NULL;
3074 }
3075 }
d62a17ae 3076 }
3077
9c92b5f7
MK
3078 if (json) {
3079 json_object_int_add(json, "numPrefix", prefix_cnt);
3080 json_object_int_add(json, "numPaths", path_cnt);
3081 } else {
3082 if (prefix_cnt == 0) {
3083 vty_out(vty, "No EVPN prefixes %sexist\n",
3084 type ? "(of requested type) " : "");
3085 } else {
3086 vty_out(vty, "\nDisplayed %u prefixes (%u paths)%s\n",
3087 prefix_cnt, path_cnt,
3088 type ? " (of requested type)" : "");
3089 }
3090 }
520d5d76 3091}
3092
3093/*
3094 * Display specified VNI (vty handler)
3095 */
9c92b5f7
MK
3096static void evpn_show_vni(struct vty *vty, struct bgp *bgp, vni_t vni,
3097 json_object *json)
520d5d76 3098{
d7c0a89a 3099 uint8_t found = 0;
d62a17ae 3100 struct bgpevpn *vpn;
520d5d76 3101
d62a17ae 3102 vpn = bgp_evpn_lookup_vni(bgp, vni);
4cce389e
MK
3103 if (vpn) {
3104 found = 1;
3105 display_vni(vty, vpn, json);
3106 } else {
3107 struct bgp *bgp_temp;
3108 struct listnode *node = NULL;
3109
3110 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_temp)) {
3111 if (bgp_temp->l3vni == vni) {
3112 found = 1;
3113 display_l3vni(vty, bgp_temp, json);
3114 }
3115 }
3116 }
3117
3118 if (!found) {
9c92b5f7
MK
3119 if (json) {
3120 vty_out(vty, "{}\n");
3121 } else {
3122 vty_out(vty, "VNI not found\n");
3123 return;
3124 }
d62a17ae 3125 }
520d5d76 3126}
3127
3128/*
3129 * Display a VNI (upon user query).
3130 */
9c92b5f7
MK
3131static void evpn_show_all_vnis(struct vty *vty, struct bgp *bgp,
3132 json_object *json)
520d5d76 3133{
9c92b5f7 3134 void *args[2];
4cce389e
MK
3135 struct bgp *bgp_temp = NULL;
3136 struct listnode *node;
520d5d76 3137
9c92b5f7 3138
4cce389e 3139 if (!json) {
9c92b5f7 3140 vty_out(vty, "Flags: * - Kernel\n");
4cce389e 3141 vty_out(vty, " %-10s %-4s %-21s %-25s %-25s %-37s\n", "VNI",
996c9314 3142 "Type", "RD", "Import RT", "Export RT", "Tenant VRF");
9c92b5f7
MK
3143 }
3144
4cce389e 3145 /* print all L2 VNIS */
9c92b5f7
MK
3146 args[0] = vty;
3147 args[1] = json;
d62a17ae 3148 hash_iterate(bgp->vnihash,
e3b78da8 3149 (void (*)(struct hash_bucket *, void *))show_vni_entry,
9c92b5f7 3150 args);
4cce389e
MK
3151
3152 /* print all L3 VNIs */
3153 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_temp))
3154 show_l3vni_entry(vty, bgp_temp, json);
520d5d76 3155}
3156
24864e44
CS
3157/*
3158 * evpn - enable advertisement of svi MAC-IP
3159 */
3160static void evpn_set_advertise_svi_macip(struct bgp *bgp, struct bgpevpn *vpn,
3161 uint32_t set)
3162{
3163 if (!vpn) {
3164 if (set && bgp->evpn_info->advertise_svi_macip)
3165 return;
3166 else if (!set && !bgp->evpn_info->advertise_svi_macip)
3167 return;
3168
3169 bgp->evpn_info->advertise_svi_macip = set;
3170 bgp_zebra_advertise_svi_macip(bgp,
3171 bgp->evpn_info->advertise_svi_macip, 0);
3172 } else {
3173 if (set && vpn->advertise_svi_macip)
3174 return;
3175 else if (!set && !vpn->advertise_svi_macip)
3176 return;
3177
3178 vpn->advertise_svi_macip = set;
3179 bgp_zebra_advertise_svi_macip(bgp, vpn->advertise_svi_macip,
3180 vpn->vni);
3181 }
3182}
3183
1a98c087
MK
3184/*
3185 * evpn - enable advertisement of default g/w
3186 */
3187static void evpn_set_advertise_default_gw(struct bgp *bgp, struct bgpevpn *vpn)
3188{
3189 if (!vpn) {
3190 if (bgp->advertise_gw_macip)
3191 return;
3192
3193 bgp->advertise_gw_macip = 1;
3194 bgp_zebra_advertise_gw_macip(bgp, bgp->advertise_gw_macip, 0);
3195 } else {
3196 if (vpn->advertise_gw_macip)
3197 return;
3198
3199 vpn->advertise_gw_macip = 1;
3200 bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip,
3201 vpn->vni);
3202 }
3203 return;
3204}
3205
3206/*
3207 * evpn - disable advertisement of default g/w
3208 */
3209static void evpn_unset_advertise_default_gw(struct bgp *bgp,
3210 struct bgpevpn *vpn)
3211{
3212 if (!vpn) {
3213 if (!bgp->advertise_gw_macip)
3214 return;
3215
3216 bgp->advertise_gw_macip = 0;
3217 bgp_zebra_advertise_gw_macip(bgp, bgp->advertise_gw_macip, 0);
3218 } else {
3219 if (!vpn->advertise_gw_macip)
3220 return;
3221
3222 vpn->advertise_gw_macip = 0;
3223 bgp_zebra_advertise_gw_macip(bgp, vpn->advertise_gw_macip,
3224 vpn->vni);
3225 }
3226 return;
3227}
3228
486456ca
MK
3229/*
3230 * evpn - enable advertisement of default g/w
3231 */
3232static void evpn_process_default_originate_cmd(struct bgp *bgp_vrf,
5fd9c12b 3233 afi_t afi, bool add)
486456ca 3234{
486456ca
MK
3235 safi_t safi = SAFI_UNICAST; /* ipv4/ipv6 unicast */
3236
486456ca
MK
3237 if (add) {
3238 /* bail if we are already advertising default route */
3239 if (evpn_default_originate_set(bgp_vrf, afi, safi))
3240 return;
3241
3242 if (afi == AFI_IP)
3243 SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3244 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
3245 else if (afi == AFI_IP6)
3246 SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3247 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
486456ca
MK
3248 } else {
3249 /* bail out if we havent advertised the default route */
3250 if (!evpn_default_originate_set(bgp_vrf, afi, safi))
3251 return;
3252 if (afi == AFI_IP)
3253 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3254 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
3255 else if (afi == AFI_IP6)
3256 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3257 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
486456ca 3258 }
5fd9c12b
KA
3259
3260 bgp_evpn_install_uninstall_default_route(bgp_vrf, afi, safi, add);
486456ca
MK
3261}
3262
31310b25
MK
3263/*
3264 * evpn - enable advertisement of default g/w
3265 */
3266static void evpn_set_advertise_subnet(struct bgp *bgp,
3267 struct bgpevpn *vpn)
3268{
3269 if (vpn->advertise_subnet)
3270 return;
3271
3272 vpn->advertise_subnet = 1;
3273 bgp_zebra_advertise_subnet(bgp, vpn->advertise_subnet, vpn->vni);
3274}
3275
3276/*
3277 * evpn - disable advertisement of default g/w
3278 */
996c9314 3279static void evpn_unset_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn)
31310b25
MK
3280{
3281 if (!vpn->advertise_subnet)
3282 return;
3283
3284 vpn->advertise_subnet = 0;
3285 bgp_zebra_advertise_subnet(bgp, vpn->advertise_subnet, vpn->vni);
3286}
3287
7724c0a1 3288/*
3289 * EVPN (VNI advertisement) enabled. Register with zebra.
3290 */
d62a17ae 3291static void evpn_set_advertise_all_vni(struct bgp *bgp)
7724c0a1 3292{
d62a17ae 3293 bgp->advertise_all_vni = 1;
e2f3a930 3294 bgp_set_evpn(bgp);
d62a17ae 3295 bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
7724c0a1 3296}
3297
3298/*
3299 * EVPN (VNI advertisement) disabled. De-register with zebra. Cleanup VNI
3300 * cache, EVPN routes (delete and withdraw from peers).
3301 */
d62a17ae 3302static void evpn_unset_advertise_all_vni(struct bgp *bgp)
7724c0a1 3303{
d62a17ae 3304 bgp->advertise_all_vni = 0;
e2f3a930 3305 bgp_set_evpn(bgp_get_default());
d62a17ae 3306 bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
3307 bgp_evpn_cleanup_on_disable(bgp);
7724c0a1 3308}
bf1061d8 3309
dc6cef73
AD
3310/* Set resolve overlay index flag */
3311static void bgp_evpn_set_unset_resolve_overlay_index(struct bgp *bgp, bool set)
3312{
3313 if (set == bgp->resolve_overlay_index)
3314 return;
3315
3316 if (set) {
3317 bgp->resolve_overlay_index = true;
3318 hash_iterate(bgp->vnihash,
3319 (void (*)(struct hash_bucket *, void *))
3320 bgp_evpn_handle_resolve_overlay_index_set,
3321 NULL);
3322 } else {
3323 hash_iterate(
3324 bgp->vnihash,
3325 (void (*)(struct hash_bucket *, void *))
3326 bgp_evpn_handle_resolve_overlay_index_unset,
3327 NULL);
3328 bgp->resolve_overlay_index = false;
3329 }
3330}
3331
bf1061d8
VB
3332/*
3333 * EVPN - use RFC8365 to auto-derive RT
3334 */
3335static void evpn_set_advertise_autort_rfc8365(struct bgp *bgp)
3336{
3337 bgp->advertise_autort_rfc8365 = 1;
3338 bgp_evpn_handle_autort_change(bgp);
3339}
3340
3341/*
3342 * EVPN - don't use RFC8365 to auto-derive RT
3343 */
3344static void evpn_unset_advertise_autort_rfc8365(struct bgp *bgp)
3345{
3346 bgp->advertise_autort_rfc8365 = 0;
3347 bgp_evpn_handle_autort_change(bgp);
3348}
7724c0a1 3349
2b791107 3350static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
d62a17ae 3351{
06b9f471 3352 char buf1[RD_ADDRSTRLEN];
d62a17ae 3353 char *ecom_str;
3354 struct listnode *node, *nnode;
3355 struct ecommunity *ecom;
3356
3357 if (is_vni_configured(vpn)) {
d62a17ae 3358 vty_out(vty, " vni %d\n", vpn->vni);
3359 if (is_rd_configured(vpn))
3360 vty_out(vty, " rd %s\n",
06b9f471 3361 prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
d62a17ae 3362
3363 if (is_import_rt_configured(vpn)) {
3364 for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode,
3365 ecom)) {
3366 ecom_str = ecommunity_ecom2str(
3367 ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
3368 vty_out(vty, " route-target import %s\n",
3369 ecom_str);
3370 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
3371 }
3372 }
3373
3374 if (is_export_rt_configured(vpn)) {
3375 for (ALL_LIST_ELEMENTS(vpn->export_rtl, node, nnode,
3376 ecom)) {
3377 ecom_str = ecommunity_ecom2str(
3378 ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
640751c7 3379 vty_out(vty, " route-target export %s\n",
d62a17ae 3380 ecom_str);
3381 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
3382 }
3383 }
3384
1a98c087
MK
3385 if (vpn->advertise_gw_macip)
3386 vty_out(vty, " advertise-default-gw\n");
3387
24864e44
CS
3388 if (vpn->advertise_svi_macip)
3389 vty_out(vty, " advertise-svi-ip\n");
3390
31310b25
MK
3391 if (vpn->advertise_subnet)
3392 vty_out(vty, " advertise-subnet\n");
3393
d62a17ae 3394 vty_out(vty, " exit-vni\n");
3395 }
3396}
3397
fd069644
DS
3398#ifndef VTYSH_EXTRACT_PL
3399#include "bgpd/bgp_evpn_vty_clippy.c"
3400#endif
3401
3402DEFPY(bgp_evpn_flood_control,
3403 bgp_evpn_flood_control_cmd,
3404 "[no$no] flooding <disable$disable|head-end-replication$her>",
3405 NO_STR
3406 "Specify handling for BUM packets\n"
3407 "Do not flood any BUM packets\n"
3408 "Flood BUM packets using head-end replication\n")
3409{
3410 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3411 enum vxlan_flood_control flood_ctrl;
3412
3413 if (!bgp)
3414 return CMD_WARNING;
3415
3416 if (disable && !no)
3417 flood_ctrl = VXLAN_FLOOD_DISABLED;
3418 else if (her || no)
3419 flood_ctrl = VXLAN_FLOOD_HEAD_END_REPL;
3420 else
3421 return CMD_WARNING;
3422
3423 if (bgp->vxlan_flood_ctrl == flood_ctrl)
3424 return CMD_SUCCESS;
3425
3426 bgp->vxlan_flood_ctrl = flood_ctrl;
3427 bgp_evpn_flood_control_change(bgp);
3428
3429 return CMD_SUCCESS;
3430}
3431
1a98c087
MK
3432DEFUN (bgp_evpn_advertise_default_gw_vni,
3433 bgp_evpn_advertise_default_gw_vni_cmd,
3434 "advertise-default-gw",
078af92e 3435 "Advertise default g/w mac-ip routes in EVPN for a VNI\n")
1a98c087
MK
3436{
3437 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3438 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
3439
3440 if (!bgp)
3441 return CMD_WARNING;
3442
1a98c087
MK
3443 evpn_set_advertise_default_gw(bgp, vpn);
3444
3445 return CMD_SUCCESS;
3446}
3447
3448DEFUN (no_bgp_evpn_advertise_default_vni_gw,
3449 no_bgp_evpn_advertise_default_gw_vni_cmd,
3450 "no advertise-default-gw",
3451 NO_STR
3452 "Withdraw default g/w mac-ip routes from EVPN for a VNI\n")
3453{
3454 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3455 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
3456
3457 if (!bgp)
3458 return CMD_WARNING;
3459
1a98c087
MK
3460 evpn_unset_advertise_default_gw(bgp, vpn);
3461
3462 return CMD_SUCCESS;
3463}
3464
3465
3466DEFUN (bgp_evpn_advertise_default_gw,
3467 bgp_evpn_advertise_default_gw_cmd,
3468 "advertise-default-gw",
078af92e 3469 "Advertise All default g/w mac-ip routes in EVPN\n")
1a98c087
MK
3470{
3471 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3472
3473 if (!bgp)
3474 return CMD_WARNING;
3475
f920dd6d 3476 if (!EVPN_ENABLED(bgp)) {
7da47d66 3477 vty_out(vty,
530db8dc 3478 "This command is only supported under the EVPN VRF\n");
7da47d66
CS
3479 return CMD_WARNING;
3480 }
3481
1a98c087
MK
3482 evpn_set_advertise_default_gw(bgp, NULL);
3483
3484 return CMD_SUCCESS;
3485}
3486
3487DEFUN (no_bgp_evpn_advertise_default_gw,
3488 no_bgp_evpn_advertise_default_gw_cmd,
3489 "no advertise-default-gw",
3490 NO_STR
3491 "Withdraw All default g/w mac-ip routes from EVPN\n")
3492{
3493 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3494
3495 if (!bgp)
3496 return CMD_WARNING;
3497
3498 evpn_unset_advertise_default_gw(bgp, NULL);
3499
3500 return CMD_SUCCESS;
3501}
3502
7724c0a1 3503DEFUN (bgp_evpn_advertise_all_vni,
3504 bgp_evpn_advertise_all_vni_cmd,
3505 "advertise-all-vni",
3506 "Advertise All local VNIs\n")
3507{
d62a17ae 3508 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
e2f3a930 3509 struct bgp *bgp_evpn = NULL;
7724c0a1 3510
d62a17ae 3511 if (!bgp)
3512 return CMD_WARNING;
e2f3a930
T
3513
3514 bgp_evpn = bgp_get_evpn();
3515 if (bgp_evpn && bgp_evpn != bgp) {
3516 vty_out(vty, "%% Please unconfigure EVPN in VRF %s\n",
3517 bgp_evpn->name);
3518 return CMD_WARNING_CONFIG_FAILED;
3519 }
3520
d62a17ae 3521 evpn_set_advertise_all_vni(bgp);
3522 return CMD_SUCCESS;
7724c0a1 3523}
3524
3525DEFUN (no_bgp_evpn_advertise_all_vni,
3526 no_bgp_evpn_advertise_all_vni_cmd,
3527 "no advertise-all-vni",
3528 NO_STR
3529 "Advertise All local VNIs\n")
3530{
d62a17ae 3531 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
7724c0a1 3532
d62a17ae 3533 if (!bgp)
3534 return CMD_WARNING;
3535 evpn_unset_advertise_all_vni(bgp);
3536 return CMD_SUCCESS;
7724c0a1 3537}
3538
bf1061d8
VB
3539DEFUN (bgp_evpn_advertise_autort_rfc8365,
3540 bgp_evpn_advertise_autort_rfc8365_cmd,
3541 "autort rfc8365-compatible",
3542 "Auto-derivation of RT\n"
3543 "Auto-derivation of RT using RFC8365\n")
3544{
3545 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3546
3547 if (!bgp)
3548 return CMD_WARNING;
3549 evpn_set_advertise_autort_rfc8365(bgp);
3550 return CMD_SUCCESS;
3551}
3552
3553DEFUN (no_bgp_evpn_advertise_autort_rfc8365,
3554 no_bgp_evpn_advertise_autort_rfc8365_cmd,
3555 "no autort rfc8365-compatible",
3556 NO_STR
3557 "Auto-derivation of RT\n"
3558 "Auto-derivation of RT using RFC8365\n")
3559{
3560 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3561
3562 if (!bgp)
3563 return CMD_WARNING;
3564 evpn_unset_advertise_autort_rfc8365(bgp);
3565 return CMD_SUCCESS;
3566}
3567
486456ca
MK
3568DEFUN (bgp_evpn_default_originate,
3569 bgp_evpn_default_originate_cmd,
3570 "default-originate <ipv4 | ipv6>",
3571 "originate a default route\n"
3572 "ipv4 address family\n"
3573 "ipv6 address family\n")
3574{
3575 afi_t afi = 0;
3576 int idx_afi = 0;
3577 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
3578
3579 if (!bgp_vrf)
3580 return CMD_WARNING;
3581 argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
5fd9c12b 3582 evpn_process_default_originate_cmd(bgp_vrf, afi, true);
486456ca
MK
3583 return CMD_SUCCESS;
3584}
3585
3586DEFUN (no_bgp_evpn_default_originate,
3587 no_bgp_evpn_default_originate_cmd,
3588 "no default-originate <ipv4 | ipv6>",
3589 NO_STR
3590 "withdraw a default route\n"
3591 "ipv4 address family\n"
3592 "ipv6 address family\n")
3593{
3594 afi_t afi = 0;
3595 int idx_afi = 0;
3596 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
3597
3598 if (!bgp_vrf)
3599 return CMD_WARNING;
3600 argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
5fd9c12b 3601 evpn_process_default_originate_cmd(bgp_vrf, afi, false);
486456ca
MK
3602 return CMD_SUCCESS;
3603}
3604
0b9d9cd0
CS
3605DEFPY (dup_addr_detection,
3606 dup_addr_detection_cmd,
3607 "dup-addr-detection [max-moves (2-1000)$max_moves_val time (2-1800)$time_val]",
3608 "Duplicate address detection\n"
979777b2 3609 "Max allowed moves before address detected as duplicate\n"
0b9d9cd0
CS
3610 "Num of max allowed moves (2-1000) default 5\n"
3611 "Duplicate address detection time\n"
3612 "Time in seconds (2-1800) default 180\n")
3613{
3614 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
3615
3616 if (!bgp_vrf)
3617 return CMD_WARNING;
3618
f920dd6d 3619 if (!EVPN_ENABLED(bgp_vrf)) {
7da47d66 3620 vty_out(vty,
530db8dc 3621 "This command is only supported under the EVPN VRF\n");
7da47d66
CS
3622 return CMD_WARNING;
3623 }
3624
0b9d9cd0
CS
3625 bgp_vrf->evpn_info->dup_addr_detect = true;
3626
3627 if (time_val)
3628 bgp_vrf->evpn_info->dad_time = time_val;
3629 if (max_moves_val)
3630 bgp_vrf->evpn_info->dad_max_moves = max_moves_val;
3631
3632 bgp_zebra_dup_addr_detection(bgp_vrf);
3633
3634 return CMD_SUCCESS;
3635}
3636
3637DEFPY (dup_addr_detection_auto_recovery,
3638 dup_addr_detection_auto_recovery_cmd,
3639 "dup-addr-detection freeze <permanent |(30-3600)$freeze_time_val>",
3640 "Duplicate address detection\n"
3641 "Duplicate address detection freeze\n"
3642 "Duplicate address detection permanent freeze\n"
3643 "Duplicate address detection freeze time (30-3600)\n")
3644{
3645 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
3646 uint32_t freeze_time = freeze_time_val;
3647
3648 if (!bgp_vrf)
3649 return CMD_WARNING;
3650
f920dd6d 3651 if (!EVPN_ENABLED(bgp_vrf)) {
7da47d66 3652 vty_out(vty,
530db8dc 3653 "This command is only supported under the EVPN VRF\n");
7da47d66
CS
3654 return CMD_WARNING;
3655 }
3656
0b9d9cd0
CS
3657 bgp_vrf->evpn_info->dup_addr_detect = true;
3658 bgp_vrf->evpn_info->dad_freeze = true;
3659 bgp_vrf->evpn_info->dad_freeze_time = freeze_time;
3660
3661 bgp_zebra_dup_addr_detection(bgp_vrf);
3662
3663 return CMD_SUCCESS;
3664}
3665
3666DEFPY (no_dup_addr_detection,
3667 no_dup_addr_detection_cmd,
3668 "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>]",
3669 NO_STR
3670 "Duplicate address detection\n"
979777b2 3671 "Max allowed moves before address detected as duplicate\n"
0b9d9cd0
CS
3672 "Num of max allowed moves (2-1000) default 5\n"
3673 "Duplicate address detection time\n"
3674 "Time in seconds (2-1800) default 180\n"
3675 "Duplicate address detection freeze\n"
3676 "Duplicate address detection permanent freeze\n"
3677 "Duplicate address detection freeze time (30-3600)\n")
3678{
3679 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
3680 uint32_t max_moves = (uint32_t)max_moves_val;
3681 uint32_t freeze_time = (uint32_t)freeze_time_val;
3682
3683 if (!bgp_vrf)
3684 return CMD_WARNING;
3685
f920dd6d 3686 if (!EVPN_ENABLED(bgp_vrf)) {
7da47d66 3687 vty_out(vty,
530db8dc 3688 "This command is only supported under the EVPN VRF\n");
7da47d66
CS
3689 return CMD_WARNING;
3690 }
3691
0b9d9cd0
CS
3692 if (argc == 2) {
3693 if (!bgp_vrf->evpn_info->dup_addr_detect)
3694 return CMD_SUCCESS;
3695 /* Reset all parameters to default. */
3696 bgp_vrf->evpn_info->dup_addr_detect = false;
3697 bgp_vrf->evpn_info->dad_time = EVPN_DAD_DEFAULT_TIME;
3698 bgp_vrf->evpn_info->dad_max_moves = EVPN_DAD_DEFAULT_MAX_MOVES;
3699 bgp_vrf->evpn_info->dad_freeze = false;
3700 bgp_vrf->evpn_info->dad_freeze_time = 0;
3701 } else {
3702 if (max_moves) {
3703 if (bgp_vrf->evpn_info->dad_max_moves != max_moves) {
3704 vty_out(vty,
3705 "%% Value does not match with config\n");
3706 return CMD_SUCCESS;
3707 }
3708 bgp_vrf->evpn_info->dad_max_moves =
3709 EVPN_DAD_DEFAULT_MAX_MOVES;
3710 }
3711
3712 if (time_val) {
3713 if (bgp_vrf->evpn_info->dad_time != time_val) {
3714 vty_out(vty,
3715 "%% Value does not match with config\n");
3716 return CMD_SUCCESS;
3717 }
3718 bgp_vrf->evpn_info->dad_time = EVPN_DAD_DEFAULT_TIME;
3719 }
3720
3721 if (freeze_time) {
3722 if (bgp_vrf->evpn_info->dad_freeze_time
3723 != freeze_time) {
3724 vty_out(vty,
3725 "%% Value does not match with config\n");
3726 return CMD_SUCCESS;
3727 }
3728 bgp_vrf->evpn_info->dad_freeze_time = 0;
3729 bgp_vrf->evpn_info->dad_freeze = false;
3730 }
3731
3732 if (permanent_val) {
3733 if (bgp_vrf->evpn_info->dad_freeze_time) {
3734 vty_out(vty,
3735 "%% Value does not match with config\n");
3736 return CMD_SUCCESS;
3737 }
3738 bgp_vrf->evpn_info->dad_freeze = false;
3739 }
3740 }
3741
3742 bgp_zebra_dup_addr_detection(bgp_vrf);
3743
3744 return CMD_SUCCESS;
3745}
3746
24864e44
CS
3747DEFPY(bgp_evpn_advertise_svi_ip,
3748 bgp_evpn_advertise_svi_ip_cmd,
3749 "[no$no] advertise-svi-ip",
3750 NO_STR
3751 "Advertise svi mac-ip routes in EVPN\n")
3752{
3753 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3754
3755 if (!bgp)
3756 return CMD_WARNING;
3757
24864e44
CS
3758 if (no)
3759 evpn_set_advertise_svi_macip(bgp, NULL, 0);
e5aee151
TA
3760 else {
3761 if (!EVPN_ENABLED(bgp)) {
3762 vty_out(vty,
3763 "This command is only supported under EVPN VRF\n");
3764 return CMD_WARNING;
3765 }
24864e44 3766 evpn_set_advertise_svi_macip(bgp, NULL, 1);
e5aee151 3767 }
24864e44
CS
3768
3769 return CMD_SUCCESS;
3770}
3771
3772DEFPY(bgp_evpn_advertise_svi_ip_vni,
3773 bgp_evpn_advertise_svi_ip_vni_cmd,
3774 "[no$no] advertise-svi-ip",
3775 NO_STR
3776 "Advertise svi mac-ip routes in EVPN for a VNI\n")
3777{
3778 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3779 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
3780
3781 if (!bgp)
3782 return CMD_WARNING;
3783
24864e44
CS
3784 if (no)
3785 evpn_set_advertise_svi_macip(bgp, vpn, 0);
3786 else
3787 evpn_set_advertise_svi_macip(bgp, vpn, 1);
3788
3789 return CMD_SUCCESS;
3790}
3791
689b5101
MK
3792DEFUN_HIDDEN (bgp_evpn_advertise_vni_subnet,
3793 bgp_evpn_advertise_vni_subnet_cmd,
3794 "advertise-subnet",
3795 "Advertise the subnet corresponding to VNI\n")
31310b25
MK
3796{
3797 struct bgp *bgp_vrf = NULL;
3798 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3799 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
3800
3801 if (!bgp)
3802 return CMD_WARNING;
3803
31310b25
MK
3804 bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id);
3805 if (!bgp_vrf)
3806 return CMD_WARNING;
3807
31310b25
MK
3808 evpn_set_advertise_subnet(bgp, vpn);
3809 return CMD_SUCCESS;
3810}
3811
689b5101
MK
3812DEFUN_HIDDEN (no_bgp_evpn_advertise_vni_subnet,
3813 no_bgp_evpn_advertise_vni_subnet_cmd,
3814 "no advertise-subnet",
3815 NO_STR
3816 "Advertise All local VNIs\n")
31310b25
MK
3817{
3818 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
3819 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
3820
3821 if (!bgp)
3822 return CMD_WARNING;
3823
31310b25
MK
3824 evpn_unset_advertise_subnet(bgp, vpn);
3825 return CMD_SUCCESS;
3826}
3827
342dd0c6 3828DEFUN (bgp_evpn_advertise_type5,
3829 bgp_evpn_advertise_type5_cmd,
d4a88de3 3830 "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR " [gateway-ip] [route-map WORD]",
342dd0c6 3831 "Advertise prefix routes\n"
053905d2 3832 BGP_AFI_HELP_STR
53c84f78 3833 BGP_SAFI_HELP_STR
d4a88de3 3834 "advertise gateway IP overlay index\n"
53c84f78
MK
3835 "route-map for filtering specific routes\n"
3836 "Name of the route map\n")
342dd0c6 3837{
3838 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
053905d2
MK
3839 int idx_afi = 0;
3840 int idx_safi = 0;
53c84f78 3841 int idx_rmap = 0;
053905d2
MK
3842 afi_t afi = 0;
3843 safi_t safi = 0;
53c84f78
MK
3844 int ret = 0;
3845 int rmap_changed = 0;
d4a88de3
AD
3846 enum overlay_index_type oly = OVERLAY_INDEX_TYPE_NONE;
3847 int idx_oly = 0;
3848 bool adv_flag_changed = false;
053905d2
MK
3849
3850 argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
3851 argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
d4a88de3
AD
3852 argv_find_and_parse_oly_idx(argv, argc, &idx_oly, &oly);
3853
53c84f78
MK
3854 ret = argv_find(argv, argc, "route-map", &idx_rmap);
3855 if (ret) {
3856 if (!bgp_vrf->adv_cmd_rmap[afi][safi].name)
3857 rmap_changed = 1;
3858 else if (strcmp(argv[idx_rmap + 1]->arg,
996c9314
LB
3859 bgp_vrf->adv_cmd_rmap[afi][safi].name)
3860 != 0)
53c84f78
MK
3861 rmap_changed = 1;
3862 } else if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
3863 rmap_changed = 1;
3864 }
053905d2 3865
e779dc76 3866 if (!(afi == AFI_IP || afi == AFI_IP6)) {
053905d2
MK
3867 vty_out(vty,
3868 "%%only ipv4 or ipv6 address families are supported");
342dd0c6 3869 return CMD_WARNING;
3870 }
3871
053905d2
MK
3872 if (safi != SAFI_UNICAST) {
3873 vty_out(vty,
3874 "%%only ipv4 unicast or ipv6 unicast are supported");
3875 return CMD_WARNING;
3876 }
3877
d4a88de3
AD
3878 if ((oly != OVERLAY_INDEX_TYPE_NONE)
3879 && (oly != OVERLAY_INDEX_GATEWAY_IP)) {
3880 vty_out(vty, "%%Unknown overlay-index type specified");
3881 return CMD_WARNING;
3882 }
3883
053905d2 3884 if (afi == AFI_IP) {
d4a88de3
AD
3885 if ((!CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3886 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST))
3887 && (!CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3888 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP))) {
3889
3890 /*
3891 * this is the case for first time ever configuration
3892 * adv ipv4 unicast is enabled for the first time.
3893 * So no need to reset any flag
3894 */
3895 if (oly == OVERLAY_INDEX_TYPE_NONE)
3896 SET_FLAG(
3897 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3898 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST);
3899 else if (oly == OVERLAY_INDEX_GATEWAY_IP)
3900 SET_FLAG(
3901 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3902 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP);
3903 } else if ((oly == OVERLAY_INDEX_TYPE_NONE)
3904 && (!CHECK_FLAG(
3905 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3906 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST))) {
3907
3908 /*
3909 * This is modify case from gateway-ip
3910 * to no overlay index
3911 */
3912 adv_flag_changed = true;
3913 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3914 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP);
3915 SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3916 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST);
3917 } else if ((oly == OVERLAY_INDEX_GATEWAY_IP)
3918 && (!CHECK_FLAG(
3919 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3920 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP))) {
3921
3922 /*
3923 * This is modify case from no overlay index
3924 * to gateway-ip
3925 */
3926 adv_flag_changed = true;
3927 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3928 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST);
3929 SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3930 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP);
3931 } else {
342dd0c6 3932
d4a88de3
AD
3933 /*
3934 * Command is issued with the same option
3935 * (no overlay index or gateway-ip) which was
3936 * already configured. So nothing to do.
3937 * However, route-map may have been modified.
3938 * check if route-map has been modified.
3939 * If not, return an error
3940 */
3941 if (!rmap_changed)
3942 return CMD_WARNING;
3943 }
342dd0c6 3944 } else {
d4a88de3
AD
3945 if ((!CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3946 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST))
3947 && (!CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3948 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))) {
3949
3950 /*
3951 * this is the case for first time ever configuration
3952 * adv ipv6 unicast is enabled for the first time.
3953 * So no need to reset any flag
3954 */
3955 if (oly == OVERLAY_INDEX_TYPE_NONE)
3956 SET_FLAG(
3957 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3958 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST);
3959 else if (oly == OVERLAY_INDEX_GATEWAY_IP)
3960 SET_FLAG(
3961 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3962 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP);
3963 } else if ((oly == OVERLAY_INDEX_TYPE_NONE)
3964 && (!CHECK_FLAG(
3965 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3966 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST))) {
3967
3968 /*
3969 * This is modify case from gateway-ip
3970 * to no overlay index
3971 */
3972 adv_flag_changed = true;
3973 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3974 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP);
3975 SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3976 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST);
3977 } else if ((oly == OVERLAY_INDEX_GATEWAY_IP)
3978 && (!CHECK_FLAG(
3979 bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3980 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))) {
3981
3982 /*
3983 * This is modify case from no overlay index
3984 * to gateway-ip
3985 */
3986 adv_flag_changed = true;
3987 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3988 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST);
3989 SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
3990 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP);
3991 } else {
342dd0c6 3992
d4a88de3
AD
3993 /*
3994 * Command is issued with the same option
3995 * (no overlay index or gateway-ip) which was
3996 * already configured. So nothing to do.
3997 * However, route-map may have been modified.
3998 * check if route-map has been modified.
3999 * If not, return an error
4000 */
4001 if (!rmap_changed)
4002 return CMD_WARNING;
4003 }
53c84f78
MK
4004 }
4005
d4a88de3
AD
4006 if ((rmap_changed) || (adv_flag_changed)) {
4007
4008 /* If either of these are changed, then FRR needs to
4009 * withdraw already advertised type5 routes.
4010 */
53c84f78 4011 bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
d4a88de3
AD
4012 if (rmap_changed) {
4013 if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
4014 XFREE(MTYPE_ROUTE_MAP_NAME,
4015 bgp_vrf->adv_cmd_rmap[afi][safi].name);
4016 route_map_counter_decrement(
b4897fa5 4017 bgp_vrf->adv_cmd_rmap[afi][safi].map);
d4a88de3
AD
4018 bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL;
4019 bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL;
4020 }
342dd0c6 4021 }
4022 }
53c84f78
MK
4023
4024 /* set the route-map for advertise command */
4025 if (ret && argv[idx_rmap + 1]->arg) {
4026 bgp_vrf->adv_cmd_rmap[afi][safi].name =
996c9314 4027 XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[idx_rmap + 1]->arg);
53c84f78
MK
4028 bgp_vrf->adv_cmd_rmap[afi][safi].map =
4029 route_map_lookup_by_name(argv[idx_rmap + 1]->arg);
b4897fa5 4030 route_map_counter_increment(
4031 bgp_vrf->adv_cmd_rmap[afi][safi].map);
53c84f78
MK
4032 }
4033
4034 /* advertise type-5 routes */
456a4697
AK
4035 if (advertise_type5_routes(bgp_vrf, afi))
4036 bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
342dd0c6 4037 return CMD_SUCCESS;
4038}
4039
4040DEFUN (no_bgp_evpn_advertise_type5,
4041 no_bgp_evpn_advertise_type5_cmd,
053905d2 4042 "no advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR,
342dd0c6 4043 NO_STR
4044 "Advertise prefix routes\n"
053905d2
MK
4045 BGP_AFI_HELP_STR
4046 BGP_SAFI_HELP_STR)
342dd0c6 4047{
4048 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
053905d2
MK
4049 int idx_afi = 0;
4050 int idx_safi = 0;
4051 afi_t afi = 0;
4052 safi_t safi = 0;
4053
4054 argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
4055 argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
4056
1ec31309 4057 if (!(afi == AFI_IP || afi == AFI_IP6)) {
053905d2
MK
4058 vty_out(vty,
4059 "%%only ipv4 or ipv6 address families are supported");
4060 return CMD_WARNING;
4061 }
4062
4063 if (safi != SAFI_UNICAST) {
4064 vty_out(vty,
4065 "%%only ipv4 unicast or ipv6 unicast are supported");
342dd0c6 4066 return CMD_WARNING;
4067 }
4068
053905d2 4069 if (afi == AFI_IP) {
342dd0c6 4070
fdf19f06 4071 /* if we are not advertising ipv4 prefix as type-5
523cafc4 4072 * nothing to do
4073 */
d4a88de3
AD
4074 if ((CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
4075 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST)) ||
4076 (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
4077 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP))) {
053905d2 4078 bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
154faa50 4079 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
d4a88de3
AD
4080 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST);
4081 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
4082 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP);
342dd0c6 4083 }
4084 } else {
4085
fdf19f06 4086 /* if we are not advertising ipv6 prefix as type-5
523cafc4 4087 * nothing to do
4088 */
d4a88de3
AD
4089 if ((CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
4090 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST)) ||
4091 (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
4092 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))){
053905d2 4093 bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
d4f7497e 4094 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
d4a88de3
AD
4095 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST);
4096 UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
4097 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP);
342dd0c6 4098 }
4099 }
53c84f78
MK
4100
4101 /* clear the route-map information for advertise ipv4/ipv6 unicast */
4102 if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
4103 XFREE(MTYPE_ROUTE_MAP_NAME,
4104 bgp_vrf->adv_cmd_rmap[afi][safi].name);
4105 bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL;
4106 bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL;
4107 }
4108
342dd0c6 4109 return CMD_SUCCESS;
4110}
4111
2867823e
AK
4112DEFPY (bgp_evpn_use_es_l3nhg,
4113 bgp_evpn_use_es_l3nhg_cmd,
4114 "[no$no] use-es-l3nhg",
4115 NO_STR
4116 "use L3 nexthop group for host routes with ES destination\n")
4117{
4118 bgp_mh_info->host_routes_use_l3nhg = no ? false :true;
4119 return CMD_SUCCESS;
4120}
4121
fe8293c3
AK
4122DEFPY (bgp_evpn_ead_evi_rx_disable,
4123 bgp_evpn_ead_evi_rx_disable_cmd,
4124 "[no$no] disable-ead-evi-rx",
4125 NO_STR
4126 "Activate PE on EAD-ES even if EAD-EVI is not received\n")
4127{
acd1d9bc
AD
4128 bool ead_evi_rx = no? true :false;
4129
4130 if (ead_evi_rx != bgp_mh_info->ead_evi_rx) {
4131 bgp_mh_info->ead_evi_rx = ead_evi_rx;
4132 bgp_evpn_switch_ead_evi_rx();
4133 }
fe8293c3
AK
4134 return CMD_SUCCESS;
4135}
4136
4137DEFPY (bgp_evpn_ead_evi_tx_disable,
4138 bgp_evpn_ead_evi_tx_disable_cmd,
4139 "[no$no] disable-ead-evi-tx",
4140 NO_STR
4141 "Don't advertise EAD-EVI for local ESs\n")
4142{
4143 bgp_mh_info->ead_evi_tx = no? true :false;
4144 return CMD_SUCCESS;
4145}
4146
dc6cef73
AD
4147DEFPY (bgp_evpn_enable_resolve_overlay_index,
4148 bgp_evpn_enable_resolve_overlay_index_cmd,
4149 "[no$no] enable-resolve-overlay-index",
4150 NO_STR
4151 "Enable Recursive Resolution of type-5 route overlay index\n")
4152{
4153 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
4154
4155 if (bgp != bgp_get_evpn()) {
4156 vty_out(vty, "This command is only supported under EVPN VRF\n");
4157 return CMD_WARNING;
4158 }
4159
4160 bgp_evpn_set_unset_resolve_overlay_index(bgp, no ? false : true);
4161 return CMD_SUCCESS;
4162}
4163
5394a276
CS
4164DEFPY (bgp_evpn_advertise_pip_ip_mac,
4165 bgp_evpn_advertise_pip_ip_mac_cmd,
4166 "[no$no] advertise-pip [ip <A.B.C.D> [mac <X:X:X:X:X:X|X:X:X:X:X:X/M>]]",
4167 NO_STR
4168 "evpn system primary IP\n"
4169 IP_STR
4170 "ip address\n"
4171 MAC_STR MAC_STR MAC_STR)
4172{
4173 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
4174 struct bgp *bgp_evpn = NULL;
4175
4176 if (EVPN_ENABLED(bgp_vrf)) {
4177 vty_out(vty,
4178 "This command is supported under L3VNI BGP EVPN VRF\n");
a6e7677e 4179 return CMD_WARNING_CONFIG_FAILED;
5394a276
CS
4180 }
4181 bgp_evpn = bgp_get_evpn();
4182
4183 if (!no) {
4184 /* pip is already enabled */
4185 if (argc == 1 && bgp_vrf->evpn_info->advertise_pip)
4186 return CMD_SUCCESS;
4187
4188 bgp_vrf->evpn_info->advertise_pip = true;
4189 if (ip.s_addr != INADDR_ANY) {
4190 /* Already configured with same IP */
4191 if (IPV4_ADDR_SAME(&ip,
4192 &bgp_vrf->evpn_info->pip_ip_static))
4193 return CMD_SUCCESS;
4194
4195 bgp_vrf->evpn_info->pip_ip_static = ip;
4196 bgp_vrf->evpn_info->pip_ip = ip;
4197 } else {
4198 bgp_vrf->evpn_info->pip_ip_static.s_addr
4199 = INADDR_ANY;
4200 /* default instance router-id assignemt */
4201 if (bgp_evpn)
4202 bgp_vrf->evpn_info->pip_ip =
4203 bgp_evpn->router_id;
4204 }
4205 /* parse sys mac */
4206 if (!is_zero_mac(&mac->eth_addr)) {
4207 /* Already configured with same MAC */
4208 if (memcmp(&bgp_vrf->evpn_info->pip_rmac_static,
4209 &mac->eth_addr, ETH_ALEN) == 0)
4210 return CMD_SUCCESS;
4211
4212 memcpy(&bgp_vrf->evpn_info->pip_rmac_static,
4213 &mac->eth_addr, ETH_ALEN);
4214 memcpy(&bgp_vrf->evpn_info->pip_rmac,
4215 &bgp_vrf->evpn_info->pip_rmac_static,
4216 ETH_ALEN);
4217 } else {
4218 /* Copy zebra sys mac */
4219 if (!is_zero_mac(&bgp_vrf->evpn_info->pip_rmac_zebra))
4220 memcpy(&bgp_vrf->evpn_info->pip_rmac,
4221 &bgp_vrf->evpn_info->pip_rmac_zebra,
4222 ETH_ALEN);
4223 }
4224 } else {
4225 if (argc == 2) {
4226 if (!bgp_vrf->evpn_info->advertise_pip)
4227 return CMD_SUCCESS;
4228 /* Disable PIP feature */
4229 bgp_vrf->evpn_info->advertise_pip = false;
4230 /* copy anycast mac */
4231 memcpy(&bgp_vrf->evpn_info->pip_rmac,
4232 &bgp_vrf->rmac, ETH_ALEN);
4233 } else {
4234 /* remove MAC-IP option retain PIP knob. */
4235 if ((ip.s_addr != INADDR_ANY) &&
4236 !IPV4_ADDR_SAME(&ip,
4237 &bgp_vrf->evpn_info->pip_ip_static)) {
4238 vty_out(vty,
4239 "%% BGP EVPN PIP IP does not match\n");
4240 return CMD_WARNING_CONFIG_FAILED;
4241 }
4242
4243 if (!is_zero_mac(&mac->eth_addr) &&
4244 memcmp(&bgp_vrf->evpn_info->pip_rmac_static,
4245 &mac->eth_addr, ETH_ALEN) != 0) {
4246 vty_out(vty,
4247 "%% BGP EVPN PIP MAC does not match\n");
4248 return CMD_WARNING_CONFIG_FAILED;
4249 }
4250 /* pip_rmac can carry vrr_rmac reset only if it matches
4251 * with static value.
4252 */
4253 if (memcmp(&bgp_vrf->evpn_info->pip_rmac,
4254 &bgp_vrf->evpn_info->pip_rmac_static,
4255 ETH_ALEN) == 0) {
4256 /* Copy zebra sys mac */
4257 if (!is_zero_mac(
4258 &bgp_vrf->evpn_info->pip_rmac_zebra))
4259 memcpy(&bgp_vrf->evpn_info->pip_rmac,
4260 &bgp_vrf->evpn_info->pip_rmac_zebra,
4261 ETH_ALEN);
4262 else {
4263 /* copy anycast mac */
4264 memcpy(&bgp_vrf->evpn_info->pip_rmac,
4265 &bgp_vrf->rmac, ETH_ALEN);
4266 }
4267 }
4268 }
4269 /* reset user configured sys MAC */
4270 memset(&bgp_vrf->evpn_info->pip_rmac_static, 0, ETH_ALEN);
4271 /* reset user configured sys IP */
4272 bgp_vrf->evpn_info->pip_ip_static.s_addr = INADDR_ANY;
4273 /* Assign default PIP IP (bgp instance router-id) */
4274 if (bgp_evpn)
4275 bgp_vrf->evpn_info->pip_ip = bgp_evpn->router_id;
4276 else
4277 bgp_vrf->evpn_info->pip_ip.s_addr = INADDR_ANY;
4278 }
4279
4280 if (is_evpn_enabled()) {
0ca10580
CS
4281 struct listnode *node = NULL;
4282 struct bgpevpn *vpn = NULL;
4283
5f140efe
DS
4284 /*
4285 * At this point if bgp_evpn is NULL and evpn is enabled
4286 * something stupid has gone wrong
4287 */
4288 assert(bgp_evpn);
4289
5394a276 4290 update_advertise_vrf_routes(bgp_vrf);
0ca10580
CS
4291
4292 /* Update (svi) type-2 routes */
4293 for (ALL_LIST_ELEMENTS_RO(bgp_vrf->l2vnis, node, vpn)) {
4294 if (!bgp_evpn_is_svi_macip_enabled(vpn))
4295 continue;
4296 update_routes_for_vni(bgp_evpn, vpn);
4297 }
5394a276
CS
4298 }
4299
4300 return CMD_SUCCESS;
4301}
4302
f2d62262 4303/*
4304 * Display VNI information - for all or a specific VNI
4305 */
9c92b5f7
MK
4306DEFUN(show_bgp_l2vpn_evpn_vni,
4307 show_bgp_l2vpn_evpn_vni_cmd,
093e3f23 4308 "show bgp l2vpn evpn vni [" CMD_VNI_RANGE "] [json]",
9c92b5f7
MK
4309 SHOW_STR
4310 BGP_STR
4311 L2VPN_HELP_STR
4312 EVPN_HELP_STR
4313 "Show VNI\n"
4314 "VNI number\n"
4315 JSON_STR)
520d5d76 4316{
5e53dce3 4317 struct bgp *bgp_evpn;
f2d62262 4318 vni_t vni;
4319 int idx = 0;
9f049418 4320 bool uj = false;
9c92b5f7 4321 json_object *json = NULL;
d7c0a89a
QY
4322 uint32_t num_l2vnis = 0;
4323 uint32_t num_l3vnis = 0;
d4454626 4324 uint32_t num_vnis = 0;
4cce389e
MK
4325 struct listnode *node = NULL;
4326 struct bgp *bgp_temp = NULL;
9c92b5f7
MK
4327
4328 uj = use_json(argc, argv);
520d5d76 4329
5e53dce3
T
4330 bgp_evpn = bgp_get_evpn();
4331 if (!bgp_evpn)
d62a17ae 4332 return CMD_WARNING;
520d5d76 4333
f2d62262 4334 if (!argv_find(argv, argc, "evpn", &idx))
4335 return CMD_WARNING;
4336
9c92b5f7
MK
4337 if (uj)
4338 json = json_object_new_object();
1a98c087 4339
9c92b5f7 4340 if ((uj && argc == ((idx + 1) + 2)) || (!uj && argc == (idx + 1) + 1)) {
4cce389e 4341
5e53dce3 4342 num_l2vnis = hashcount(bgp_evpn->vnihash);
4cce389e
MK
4343
4344 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_temp)) {
4345 if (bgp_temp->l3vni)
4346 num_l3vnis++;
4347 }
d4454626 4348 num_vnis = num_l2vnis + num_l3vnis;
9c92b5f7
MK
4349 if (uj) {
4350 json_object_string_add(json, "advertiseGatewayMacip",
5e53dce3 4351 bgp_evpn->advertise_gw_macip
9c92b5f7
MK
4352 ? "Enabled"
4353 : "Disabled");
0b509723 4354 json_object_string_add(json, "advertiseSviMacIp",
cbdbb1ca
CS
4355 bgp_evpn->evpn_info->advertise_svi_macip
4356 ? "Enabled" : "Disabled");
9c92b5f7 4357 json_object_string_add(json, "advertiseAllVnis",
996c9314
LB
4358 is_evpn_enabled() ? "Enabled"
4359 : "Disabled");
fd069644
DS
4360 json_object_string_add(
4361 json, "flooding",
5e53dce3 4362 bgp_evpn->vxlan_flood_ctrl
fd069644
DS
4363 == VXLAN_FLOOD_HEAD_END_REPL
4364 ? "Head-end replication"
4365 : "Disabled");
d4454626 4366 json_object_int_add(json, "numVnis", num_vnis);
4cce389e
MK
4367 json_object_int_add(json, "numL2Vnis", num_l2vnis);
4368 json_object_int_add(json, "numL3Vnis", num_l3vnis);
9c92b5f7
MK
4369 } else {
4370 vty_out(vty, "Advertise Gateway Macip: %s\n",
5e53dce3 4371 bgp_evpn->advertise_gw_macip ? "Enabled"
996c9314 4372 : "Disabled");
24864e44 4373 vty_out(vty, "Advertise SVI Macip: %s\n",
5e53dce3 4374 bgp_evpn->evpn_info->advertise_svi_macip ? "Enabled"
24864e44 4375 : "Disabled");
9c92b5f7 4376 vty_out(vty, "Advertise All VNI flag: %s\n",
94c2f693 4377 is_evpn_enabled() ? "Enabled" : "Disabled");
fd069644 4378 vty_out(vty, "BUM flooding: %s\n",
5e53dce3 4379 bgp_evpn->vxlan_flood_ctrl
fd069644
DS
4380 == VXLAN_FLOOD_HEAD_END_REPL
4381 ? "Head-end replication"
4382 : "Disabled");
4cce389e
MK
4383 vty_out(vty, "Number of L2 VNIs: %u\n", num_l2vnis);
4384 vty_out(vty, "Number of L3 VNIs: %u\n", num_l3vnis);
9c92b5f7 4385 }
5e53dce3 4386 evpn_show_all_vnis(vty, bgp_evpn, json);
f2d62262 4387 } else {
9c92b5f7
MK
4388 int vni_idx = 0;
4389
4390 if (!argv_find(argv, argc, "vni", &vni_idx))
4391 return CMD_WARNING;
4392
f2d62262 4393 /* Display specific VNI */
9c92b5f7 4394 vni = strtoul(argv[vni_idx + 1]->arg, NULL, 10);
5e53dce3 4395 evpn_show_vni(vty, bgp_evpn, vni, json);
9c92b5f7
MK
4396 }
4397
c48349e3 4398 if (uj)
75eeda93 4399 vty_json(vty, json);
520d5d76 4400
d62a17ae 4401 return CMD_SUCCESS;
520d5d76 4402}
4403
021b6596
AD
4404DEFUN_HIDDEN(show_bgp_l2vpn_evpn_vni_remote_ip_hash,
4405 show_bgp_l2vpn_evpn_vni_remote_ip_hash_cmd,
4406 "show bgp l2vpn evpn vni remote-ip-hash",
4407 SHOW_STR
4408 BGP_STR
4409 L2VPN_HELP_STR
4410 EVPN_HELP_STR
4411 "Show VNI\n"
4412 "Remote IP hash\n")
4413{
4414 struct bgp *bgp_evpn;
4415 int idx = 0;
4416
4417 bgp_evpn = bgp_get_evpn();
4418 if (!bgp_evpn)
4419 return CMD_WARNING;
4420
4421 if (!argv_find(argv, argc, "evpn", &idx))
4422 return CMD_WARNING;
4423
4424 hash_iterate(bgp_evpn->vnihash,
4425 (void (*)(struct hash_bucket *,
4426 void *))bgp_evpn_show_remote_ip_hash,
4427 vty);
4428
4429 return CMD_SUCCESS;
4430}
4431
4432DEFUN_HIDDEN(show_bgp_l2vpn_evpn_vni_svi_hash,
4433 show_bgp_l2vpn_evpn_vni_svi_hash_cmd,
4434 "show bgp l2vpn evpn vni-svi-hash",
4435 SHOW_STR
4436 BGP_STR
4437 L2VPN_HELP_STR
4438 EVPN_HELP_STR
4439 "Show vni-svi-hash\n")
4440{
4441 struct bgp *bgp_evpn;
4442 int idx = 0;
4443
4444 bgp_evpn = bgp_get_evpn();
4445 if (!bgp_evpn)
4446 return CMD_WARNING;
4447
4448 if (!argv_find(argv, argc, "evpn", &idx))
4449 return CMD_WARNING;
4450
4451 hash_iterate(bgp_evpn->vni_svi_hash,
4452 (void (*)(struct hash_bucket *,
4453 void *))bgp_evpn_show_vni_svi_hash,
4454 vty);
4455
4456 return CMD_SUCCESS;
4457}
4458
b5e140c8
AK
4459DEFPY(show_bgp_l2vpn_evpn_es_evi,
4460 show_bgp_l2vpn_evpn_es_evi_cmd,
4461 "show bgp l2vpn evpn es-evi [vni (1-16777215)$vni] [json$uj] [detail$detail]",
4462 SHOW_STR
4463 BGP_STR
4464 L2VPN_HELP_STR
4465 EVPN_HELP_STR
4466 "ES per EVI\n"
4467 "VxLAN Network Identifier\n"
4468 "VNI\n"
4469 JSON_STR
4470 "Detailed information\n")
4471{
4472 if (vni)
4473 bgp_evpn_es_evi_show_vni(vty, vni, !!uj, !!detail);
4474 else
4475 bgp_evpn_es_evi_show(vty, !!uj, !!detail);
4476
4477 return CMD_SUCCESS;
4478}
4479
4480DEFPY(show_bgp_l2vpn_evpn_es,
50f74cf1 4481 show_bgp_l2vpn_evpn_es_cmd,
b5e140c8 4482 "show bgp l2vpn evpn es [NAME$esi_str|detail$detail] [json$uj]",
50f74cf1 4483 SHOW_STR
4484 BGP_STR
4485 L2VPN_HELP_STR
4486 EVPN_HELP_STR
b5e140c8
AK
4487 "Ethernet Segment\n"
4488 "ES ID\n"
4489 "Detailed information\n"
b482a7fd 4490 JSON_STR)
50f74cf1 4491{
6a527b2f 4492 esi_t esi;
50f74cf1 4493
b5e140c8
AK
4494 if (esi_str) {
4495 if (!str_to_esi(esi_str, &esi)) {
4496 vty_out(vty, "%%Malformed ESI\n");
50f74cf1 4497 return CMD_WARNING;
4498 }
b5e140c8
AK
4499 bgp_evpn_es_show_esi(vty, &esi, uj);
4500 } else {
50f74cf1 4501
b5e140c8 4502 bgp_evpn_es_show(vty, uj, !!detail);
50f74cf1 4503 }
4504
4505 return CMD_SUCCESS;
4506}
4507
229587fb
AK
4508DEFPY(show_bgp_l2vpn_evpn_es_vrf, show_bgp_l2vpn_evpn_es_vrf_cmd,
4509 "show bgp l2vpn evpn es-vrf [NAME$esi_str] [json$uj]",
4510 SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR
4511 "Ethernet Segment\n"
4512 "ES ID\n" JSON_STR)
4513{
4514 esi_t esi;
4515
4516 if (esi_str) {
4517 if (!str_to_esi(esi_str, &esi)) {
4518 vty_out(vty, "%%Malformed ESI\n");
4519 return CMD_WARNING;
4520 }
4521 bgp_evpn_es_vrf_show_esi(vty, &esi, uj);
4522 } else {
4523
4524 bgp_evpn_es_vrf_show(vty, uj, NULL);
4525 }
4526
4527 return CMD_SUCCESS;
4528}
4529
090efa2f
AK
4530DEFPY(show_bgp_l2vpn_evpn_nh,
4531 show_bgp_l2vpn_evpn_nh_cmd,
4532 "show bgp l2vpn evpn next-hops [json$uj]",
4533 SHOW_STR
4534 BGP_STR
4535 L2VPN_HELP_STR
4536 EVPN_HELP_STR
4537 "Nexthops\n"
4538 JSON_STR)
4539{
4540 bgp_evpn_nh_show(vty, uj);
4541
4542 return CMD_SUCCESS;
4543}
4544
f2d62262 4545/*
4546 * Display EVPN neighbor summary.
4547 */
8c1d4cd5 4548DEFUN(show_bgp_l2vpn_evpn_summary, show_bgp_l2vpn_evpn_summary_cmd,
96c81f66 4549 "show bgp [vrf VRFNAME] l2vpn evpn summary [established|failed] [<neighbor <A.B.C.D|X:X::X:X|WORD>|remote-as <(1-4294967295)|internal|external>>] [terse] [wide] [json]",
8c1d4cd5 4550 SHOW_STR BGP_STR
ee851c8c 4551 "bgp vrf\n"
8c1d4cd5 4552 "vrf name\n" L2VPN_HELP_STR EVPN_HELP_STR
9c92b5f7 4553 "Summary of BGP neighbor status\n"
10b49f14 4554 "Show only sessions in Established state\n"
3577f1c5 4555 "Show only sessions not in Established state\n"
8c1d4cd5
LS
4556 "Show only the specified neighbor session\n"
4557 "Neighbor to display information about\n"
4558 "Neighbor to display information about\n"
4559 "Neighbor on BGP configured interface\n"
4560 "Show only the specified remote AS sessions\n"
4561 "AS number\n"
4562 "Internal (iBGP) AS sessions\n"
4563 "External (eBGP) AS sessions\n"
96c81f66 4564 "Shorten the information on BGP instances\n"
8c1d4cd5 4565 "Increase table width for longer output\n" JSON_STR)
520d5d76 4566{
ee851c8c 4567 int idx_vrf = 0;
85eeb029 4568 int idx = 0;
ee851c8c 4569 char *vrf = NULL;
8c1d4cd5
LS
4570 char *neighbor = NULL;
4571 as_t as = 0; /* 0 means AS filter not set */
4572 int as_type = AS_UNSPECIFIED;
96c81f66 4573 uint16_t show_flags = 0;
ee851c8c
MK
4574
4575 if (argv_find(argv, argc, "vrf", &idx_vrf))
4576 vrf = argv[++idx_vrf]->arg;
10b49f14 4577
85eeb029
DA
4578 if (argv_find(argv, argc, "failed", &idx))
4579 SET_FLAG(show_flags, BGP_SHOW_OPT_FAILED);
4580
4581 if (argv_find(argv, argc, "established", &idx))
4582 SET_FLAG(show_flags, BGP_SHOW_OPT_ESTABLISHED);
4583
8c1d4cd5
LS
4584
4585 if (argv_find(argv, argc, "neighbor", &idx))
4586 neighbor = argv[idx + 1]->arg;
4587
4588 if (argv_find(argv, argc, "remote-as", &idx)) {
4589 if (argv[idx + 1]->arg[0] == 'i')
4590 as_type = AS_INTERNAL;
4591 else if (argv[idx + 1]->arg[0] == 'e')
4592 as_type = AS_EXTERNAL;
4593 else
4594 as = (as_t)atoi(argv[idx + 1]->arg);
4595 }
4596
96c81f66
LS
4597 if (argv_find(argv, argc, "terse", &idx))
4598 SET_FLAG(show_flags, BGP_SHOW_OPT_TERSE);
4599
85eeb029
DA
4600 if (argv_find(argv, argc, "wide", &idx))
4601 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
4602
4603 if (use_json(argc, argv))
4604 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
4605
8c1d4cd5
LS
4606 return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN, neighbor,
4607 as_type, as, show_flags);
520d5d76 4608}
4609
15dc08a6 4610int bgp_evpn_cli_parse_type(int *type, struct cmd_token **argv, int argc)
2b1364e1
SW
4611{
4612 int type_idx = 0;
4613
4614 if (argv_find(argv, argc, "type", &type_idx)) {
4615 /* Specific type is requested */
4616 if ((strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0)
4617 || (strmatch(argv[type_idx + 1]->arg, "2")))
4618 *type = BGP_EVPN_MAC_IP_ROUTE;
4619 else if ((strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0)
4620 || (strmatch(argv[type_idx + 1]->arg, "3")))
4621 *type = BGP_EVPN_IMET_ROUTE;
4622 else if ((strncmp(argv[type_idx + 1]->arg, "es", 2) == 0)
4623 || (strmatch(argv[type_idx + 1]->arg, "4")))
4624 *type = BGP_EVPN_ES_ROUTE;
4625 else if ((strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0)
4626 || (strmatch(argv[type_idx + 1]->arg, "1")))
4627 *type = BGP_EVPN_AD_ROUTE;
4628 else if ((strncmp(argv[type_idx + 1]->arg, "p", 1) == 0)
4629 || (strmatch(argv[type_idx + 1]->arg, "5")))
4630 *type = BGP_EVPN_IP_PREFIX_ROUTE;
4631 else
4632 return -1;
4633 }
4634
4635 return 0;
4636}
4637
f2d62262 4638/*
4639 * Display global EVPN routing table.
4640 */
60466a63
QY
4641DEFUN(show_bgp_l2vpn_evpn_route,
4642 show_bgp_l2vpn_evpn_route_cmd,
2b1364e1 4643 "show bgp l2vpn evpn route [detail] [type "EVPN_TYPE_ALL_LIST"] [json]",
9c92b5f7
MK
4644 SHOW_STR
4645 BGP_STR
4646 L2VPN_HELP_STR
4647 EVPN_HELP_STR
f5dc0b1a 4648 EVPN_RT_HELP_STR
21f3551e 4649 "Display Detailed Information\n"
f5dc0b1a 4650 EVPN_TYPE_HELP_STR
2b1364e1 4651 EVPN_TYPE_ALL_LIST_HELP_STR
9c92b5f7 4652 JSON_STR)
520d5d76 4653{
d62a17ae 4654 struct bgp *bgp;
21f3551e 4655 int detail = 0;
d62a17ae 4656 int type = 0;
9f049418 4657 bool uj = false;
9c92b5f7
MK
4658 json_object *json = NULL;
4659
4660 uj = use_json(argc, argv);
520d5d76 4661
530db8dc 4662 bgp = bgp_get_evpn();
d62a17ae 4663 if (!bgp)
4664 return CMD_WARNING;
520d5d76 4665
9c92b5f7
MK
4666 if (uj)
4667 json = json_object_new_object();
f2d62262 4668
15dc08a6 4669 if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
2b1364e1 4670 return CMD_WARNING;
520d5d76 4671
21f3551e
NS
4672 if (argv_find(argv, argc, "detail", &detail))
4673 detail = 1;
4674
4675 evpn_show_all_routes(vty, bgp, type, json, detail);
9c92b5f7 4676
c48349e3 4677 if (uj)
75eeda93 4678 vty_json(vty, json);
d62a17ae 4679 return CMD_SUCCESS;
520d5d76 4680}
4681
f2d62262 4682/*
4683 * Display global EVPN routing table for specific RD.
4684 */
60466a63
QY
4685DEFUN(show_bgp_l2vpn_evpn_route_rd,
4686 show_bgp_l2vpn_evpn_route_rd_cmd,
a111dd97 4687 "show bgp l2vpn evpn route rd <ASN:NN_OR_IP-ADDRESS:NN|all> [type "EVPN_TYPE_ALL_LIST"] [json]",
9c92b5f7
MK
4688 SHOW_STR
4689 BGP_STR
4690 L2VPN_HELP_STR
4691 EVPN_HELP_STR
f5dc0b1a
SW
4692 EVPN_RT_HELP_STR
4693 EVPN_RT_DIST_HELP_STR
10794c49 4694 EVPN_ASN_IP_HELP_STR
a111dd97 4695 "All VPN Route Distinguishers\n"
f5dc0b1a 4696 EVPN_TYPE_HELP_STR
2b1364e1 4697 EVPN_TYPE_ALL_LIST_HELP_STR
9c92b5f7 4698 JSON_STR)
520d5d76 4699{
d62a17ae 4700 struct bgp *bgp;
4701 int ret;
4702 struct prefix_rd prd;
4703 int type = 0;
9f049418 4704 bool uj = false;
9c92b5f7 4705 json_object *json = NULL;
a111dd97
TA
4706 int idx_ext_community = 0;
4707 int rd_all = 0;
520d5d76 4708
530db8dc 4709 bgp = bgp_get_evpn();
d62a17ae 4710 if (!bgp)
4711 return CMD_WARNING;
520d5d76 4712
9c92b5f7
MK
4713 /* check if we need json output */
4714 uj = use_json(argc, argv);
4715 if (uj)
4716 json = json_object_new_object();
f2d62262 4717
a111dd97
TA
4718 argv_find(argv, argc, "all", &rd_all);
4719 if (!rd_all) {
4720 /* get the RD */
4721 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
4722 &idx_ext_community);
4723 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
9c92b5f7
MK
4724 if (!ret) {
4725 vty_out(vty, "%% Malformed Route Distinguisher\n");
4726 return CMD_WARNING;
4727 }
d62a17ae 4728 }
520d5d76 4729
15dc08a6 4730 if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
2b1364e1 4731 return CMD_WARNING;
520d5d76 4732
a111dd97
TA
4733 if (rd_all)
4734 evpn_show_all_routes(vty, bgp, type, json, 1);
4735 else
4736 evpn_show_route_rd(vty, bgp, &prd, type, json);
9c92b5f7 4737
c48349e3 4738 if (uj)
75eeda93 4739 vty_json(vty, json);
9c92b5f7 4740
d62a17ae 4741 return CMD_SUCCESS;
520d5d76 4742}
4743
f2d62262 4744/*
4745 * Display global EVPN routing table for specific RD and MACIP.
4746 */
9c92b5f7
MK
4747DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
4748 show_bgp_l2vpn_evpn_route_rd_macip_cmd,
a111dd97 4749 "show bgp l2vpn evpn route rd <ASN:NN_OR_IP-ADDRESS:NN|all> mac WORD [ip WORD] [json]",
9c92b5f7
MK
4750 SHOW_STR
4751 BGP_STR
4752 L2VPN_HELP_STR
4753 EVPN_HELP_STR
f5dc0b1a
SW
4754 EVPN_RT_HELP_STR
4755 EVPN_RT_DIST_HELP_STR
10794c49 4756 EVPN_ASN_IP_HELP_STR
a111dd97 4757 "All VPN Route Distinguishers\n"
9c92b5f7
MK
4758 "MAC\n"
4759 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
4760 "IP\n"
4761 "IP address (IPv4 or IPv6)\n"
4762 JSON_STR)
4763{
0291c246
MK
4764 struct bgp *bgp;
4765 int ret;
4766 struct prefix_rd prd;
4767 struct ethaddr mac;
4768 struct ipaddr ip;
a111dd97 4769 int idx_ext_community = 0;
0291c246
MK
4770 int mac_idx = 0;
4771 int ip_idx = 0;
9f049418 4772 bool uj = false;
0291c246 4773 json_object *json = NULL;
a111dd97 4774 int rd_all = 0;
9c92b5f7
MK
4775
4776 memset(&mac, 0, sizeof(struct ethaddr));
4777 memset(&ip, 0, sizeof(struct ipaddr));
d62a17ae 4778
530db8dc 4779 bgp = bgp_get_evpn();
d62a17ae 4780 if (!bgp)
4781 return CMD_WARNING;
4782
9c92b5f7
MK
4783 /* check if we need json output */
4784 uj = use_json(argc, argv);
4785 if (uj)
4786 json = json_object_new_object();
f2d62262 4787
9c92b5f7 4788 /* get the prd */
a111dd97
TA
4789 argv_find(argv, argc, "all", &rd_all);
4790 if (!rd_all) {
4791 argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
4792 &idx_ext_community);
4793 ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
9c92b5f7
MK
4794 if (!ret) {
4795 vty_out(vty, "%% Malformed Route Distinguisher\n");
4796 return CMD_WARNING;
4797 }
d62a17ae 4798 }
9c92b5f7
MK
4799
4800 /* get the mac */
4801 if (argv_find(argv, argc, "mac", &mac_idx)) {
4802 if (!prefix_str2mac(argv[mac_idx + 1]->arg, &mac)) {
4803 vty_out(vty, "%% Malformed MAC address\n");
4804 return CMD_WARNING;
4805 }
d62a17ae 4806 }
9c92b5f7
MK
4807
4808 /* get the ip if specified */
4809 if (argv_find(argv, argc, "ip", &ip_idx)) {
4810 if (str2ipaddr(argv[ip_idx + 1]->arg, &ip) != 0) {
d62a17ae 4811 vty_out(vty, "%% Malformed IP address\n");
4812 return CMD_WARNING;
4813 }
4814 }
4815
a111dd97
TA
4816 if (rd_all)
4817 evpn_show_route_rd_all_macip(vty, bgp, &mac, &ip, json);
4818 else
4819 evpn_show_route_rd_macip(vty, bgp, &prd, &mac, &ip, json);
9c92b5f7 4820
c48349e3 4821 if (uj)
75eeda93 4822 vty_json(vty, json);
9c92b5f7 4823
d62a17ae 4824 return CMD_SUCCESS;
520d5d76 4825}
4826
50f74cf1 4827/* Display per ESI routing table */
4828DEFUN(show_bgp_l2vpn_evpn_route_esi,
4829 show_bgp_l2vpn_evpn_route_esi_cmd,
4830 "show bgp l2vpn evpn route esi ESI [json]",
4831 SHOW_STR
4832 BGP_STR
4833 L2VPN_HELP_STR
4834 EVPN_HELP_STR
f5dc0b1a 4835 EVPN_RT_HELP_STR
50f74cf1 4836 "Ethernet Segment Identifier\n"
4837 "ESI ID\n"
4838 JSON_STR)
4839{
9f049418 4840 bool uj = false;
6a527b2f 4841 esi_t esi;
50f74cf1 4842 struct bgp *bgp = NULL;
4843 json_object *json = NULL;
4844
6a527b2f 4845 memset(&esi, 0, sizeof(esi));
530db8dc 4846 bgp = bgp_get_evpn();
50f74cf1 4847 if (!bgp)
4848 return CMD_WARNING;
4849
4850 uj = use_json(argc, argv);
4851 if (uj)
4852 json = json_object_new_object();
4853
4854 /* get the ESI - ESI-ID is at argv[6] */
4855 if (!str_to_esi(argv[6]->arg, &esi)) {
4856 vty_out(vty, "%% Malformed ESI\n");
4857 return CMD_WARNING;
4858 }
4859
4860 evpn_show_routes_esi(vty, bgp, &esi, json);
4861
c48349e3 4862 if (uj)
75eeda93 4863 vty_json(vty, json);
50f74cf1 4864
4865 return CMD_SUCCESS;
4866}
4867
4868
f2d62262 4869/*
4870 * Display per-VNI EVPN routing table.
4871 */
9c92b5f7 4872DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
2b1364e1 4873 "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <ead|1|macip|2|multicast|3> | vtep A.B.C.D>] [json]",
9c92b5f7
MK
4874 SHOW_STR
4875 BGP_STR
4876 L2VPN_HELP_STR
4877 EVPN_HELP_STR
f5dc0b1a 4878 EVPN_RT_HELP_STR
9c92b5f7
MK
4879 "VXLAN Network Identifier\n"
4880 "VNI number\n"
f5dc0b1a
SW
4881 EVPN_TYPE_HELP_STR
4882 EVPN_TYPE_1_HELP_STR
2b1364e1 4883 EVPN_TYPE_1_HELP_STR
f5dc0b1a 4884 EVPN_TYPE_2_HELP_STR
2b1364e1
SW
4885 EVPN_TYPE_2_HELP_STR
4886 EVPN_TYPE_3_HELP_STR
f5dc0b1a 4887 EVPN_TYPE_3_HELP_STR
9c92b5f7
MK
4888 "Remote VTEP\n"
4889 "Remote VTEP IP address\n"
4890 JSON_STR)
520d5d76 4891{
d62a17ae 4892 vni_t vni;
4893 struct bgp *bgp;
4894 struct in_addr vtep_ip;
4895 int type = 0;
f2d62262 4896 int idx = 0;
2b1364e1 4897 int vtep_idx = 0;
9f049418 4898 bool uj = false;
9c92b5f7 4899 json_object *json = NULL;
d62a17ae 4900
530db8dc 4901 bgp = bgp_get_evpn();
d62a17ae 4902 if (!bgp)
4903 return CMD_WARNING;
4904
9c92b5f7
MK
4905 /* check if we need json output */
4906 uj = use_json(argc, argv);
4907 if (uj)
4908 json = json_object_new_object();
4909
f2d62262 4910 if (!argv_find(argv, argc, "evpn", &idx))
4911 return CMD_WARNING;
4912
d62a17ae 4913 vtep_ip.s_addr = 0;
4914
f2d62262 4915 vni = strtoul(argv[idx + 3]->arg, NULL, 10);
d62a17ae 4916
15dc08a6 4917 if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
2b1364e1
SW
4918 return CMD_WARNING;
4919
4920 if (argv_find(argv, argc, "vtep", &vtep_idx)) {
4921 if (!inet_aton(argv[vtep_idx + 1]->arg, &vtep_ip)) {
4922 vty_out(vty, "%% Malformed VTEP IP address\n");
d62a17ae 4923 return CMD_WARNING;
2b1364e1 4924 }
d62a17ae 4925 }
4926
9c92b5f7
MK
4927 evpn_show_routes_vni(vty, bgp, vni, type, vtep_ip, json);
4928
c48349e3 4929 if (uj)
75eeda93 4930 vty_json(vty, json);
9c92b5f7 4931
d62a17ae 4932 return CMD_SUCCESS;
520d5d76 4933}
4934
f2d62262 4935/*
4936 * Display per-VNI EVPN routing table for specific MACIP.
4937 */
9c92b5f7
MK
4938DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
4939 show_bgp_l2vpn_evpn_route_vni_macip_cmd,
093e3f23 4940 "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD] [json]",
9c92b5f7
MK
4941 SHOW_STR
4942 BGP_STR
4943 L2VPN_HELP_STR
4944 EVPN_HELP_STR
f5dc0b1a 4945 EVPN_RT_HELP_STR
9c92b5f7
MK
4946 "VXLAN Network Identifier\n"
4947 "VNI number\n"
4948 "MAC\n"
4949 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
4950 "IP\n"
4951 "IP address (IPv4 or IPv6)\n"
4952 JSON_STR)
520d5d76 4953{
d62a17ae 4954 vni_t vni;
4955 struct bgp *bgp;
4956 struct ethaddr mac;
4957 struct ipaddr ip;
f2d62262 4958 int idx = 0;
9f049418 4959 bool uj = false;
9c92b5f7 4960 json_object *json = NULL;
d62a17ae 4961
530db8dc 4962 bgp = bgp_get_evpn();
d62a17ae 4963 if (!bgp)
4964 return CMD_WARNING;
4965
9c92b5f7
MK
4966 /* check if we need json output */
4967 uj = use_json(argc, argv);
4968 if (uj)
4969 json = json_object_new_object();
4970
f2d62262 4971 if (!argv_find(argv, argc, "evpn", &idx))
4972 return CMD_WARNING;
4973
9c92b5f7 4974 /* get the VNI */
f2d62262 4975 vni = strtoul(argv[idx + 3]->arg, NULL, 10);
9c92b5f7
MK
4976
4977 /* get the mac */
f2d62262 4978 if (!prefix_str2mac(argv[idx + 5]->arg, &mac)) {
d62a17ae 4979 vty_out(vty, "%% Malformed MAC address\n");
4980 return CMD_WARNING;
4981 }
9c92b5f7
MK
4982
4983 /* get the ip */
d62a17ae 4984 memset(&ip, 0, sizeof(ip));
9c92b5f7
MK
4985 if ((!uj && ((argc == (idx + 1 + 7)) && argv[idx + 7]->arg != NULL))
4986 || (uj
4987 && ((argc == (idx + 1 + 8)) && argv[idx + 7]->arg != NULL))) {
f2d62262 4988 if (str2ipaddr(argv[idx + 7]->arg, &ip) != 0) {
d62a17ae 4989 vty_out(vty, "%% Malformed IP address\n");
4990 return CMD_WARNING;
4991 }
4992 }
4993
9c92b5f7
MK
4994 evpn_show_route_vni_macip(vty, bgp, vni, &mac, &ip, json);
4995
c48349e3 4996 if (uj)
75eeda93 4997 vty_json(vty, json);
9c92b5f7 4998
d62a17ae 4999 return CMD_SUCCESS;
520d5d76 5000}
5001
f2d62262 5002/*
5003 * Display per-VNI EVPN routing table for specific multicast IP (remote VTEP).
5004 */
9c92b5f7
MK
5005DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast,
5006 show_bgp_l2vpn_evpn_route_vni_multicast_cmd,
093e3f23 5007 "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D [json]",
9c92b5f7
MK
5008 SHOW_STR
5009 BGP_STR
5010 L2VPN_HELP_STR
5011 EVPN_HELP_STR
f5dc0b1a 5012 EVPN_RT_HELP_STR
9c92b5f7
MK
5013 "VXLAN Network Identifier\n"
5014 "VNI number\n"
f5dc0b1a 5015 EVPN_TYPE_3_HELP_STR
9c92b5f7
MK
5016 "Originating Router IP address\n"
5017 JSON_STR)
520d5d76 5018{
d62a17ae 5019 vni_t vni;
5020 struct bgp *bgp;
5021 int ret;
5022 struct in_addr orig_ip;
f2d62262 5023 int idx = 0;
9f049418 5024 bool uj = false;
9c92b5f7 5025 json_object *json = NULL;
520d5d76 5026
530db8dc 5027 bgp = bgp_get_evpn();
d62a17ae 5028 if (!bgp)
5029 return CMD_WARNING;
520d5d76 5030
9c92b5f7
MK
5031 /* check if we need json output */
5032 uj = use_json(argc, argv);
5033 if (uj)
5034 json = json_object_new_object();
5035
f2d62262 5036 if (!argv_find(argv, argc, "evpn", &idx))
5037 return CMD_WARNING;
5038
9c92b5f7 5039 /* get the VNI */
f2d62262 5040 vni = strtoul(argv[idx + 3]->arg, NULL, 10);
9c92b5f7
MK
5041
5042 /* get the ip */
f2d62262 5043 ret = inet_aton(argv[idx + 5]->arg, &orig_ip);
d62a17ae 5044 if (!ret) {
5045 vty_out(vty, "%% Malformed Originating Router IP address\n");
5046 return CMD_WARNING;
5047 }
520d5d76 5048
9c92b5f7
MK
5049 evpn_show_route_vni_multicast(vty, bgp, vni, orig_ip, json);
5050
c48349e3 5051 if (uj)
75eeda93 5052 vty_json(vty, json);
9c92b5f7 5053
d62a17ae 5054 return CMD_SUCCESS;
520d5d76 5055}
5056
f2d62262 5057/*
5058 * Display per-VNI EVPN routing table - for all VNIs.
5059 */
60466a63
QY
5060DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
5061 show_bgp_l2vpn_evpn_route_vni_all_cmd,
c7ef6cf2 5062 "show bgp l2vpn evpn route vni all [detail] [vtep A.B.C.D] [json]",
9c92b5f7
MK
5063 SHOW_STR
5064 BGP_STR
5065 L2VPN_HELP_STR
5066 EVPN_HELP_STR
f5dc0b1a 5067 EVPN_RT_HELP_STR
9c92b5f7
MK
5068 "VXLAN Network Identifier\n"
5069 "All VNIs\n"
c7ef6cf2 5070 "Print Detailed Output\n"
9c92b5f7
MK
5071 "Remote VTEP\n"
5072 "Remote VTEP IP address\n"
5073 JSON_STR)
520d5d76 5074{
d62a17ae 5075 struct bgp *bgp;
5076 struct in_addr vtep_ip;
f2d62262 5077 int idx = 0;
9f049418 5078 bool uj = false;
9c92b5f7 5079 json_object *json = NULL;
c7ef6cf2
NS
5080 /* Detail Adjust. Adjust indexes according to detail option */
5081 int da = 0;
520d5d76 5082
530db8dc 5083 bgp = bgp_get_evpn();
d62a17ae 5084 if (!bgp)
5085 return CMD_WARNING;
520d5d76 5086
9c92b5f7
MK
5087 /* check if we need json output */
5088 uj = use_json(argc, argv);
5089 if (uj)
5090 json = json_object_new_object();
5091
f2d62262 5092 if (!argv_find(argv, argc, "evpn", &idx))
5093 return CMD_WARNING;
5094
c7ef6cf2
NS
5095 if (argv_find(argv, argc, "detail", &da))
5096 da = 1;
5097
5098 /* vtep-ip position depends on detail option */
d62a17ae 5099 vtep_ip.s_addr = 0;
c7ef6cf2
NS
5100 if ((!uj && (argc == (idx + 1 + 5 + da) && argv[idx + 5 + da]->arg))
5101 || (uj
5102 && (argc == (idx + 1 + 6 + da) && argv[idx + 5 + da]->arg))) {
5103 if (!inet_aton(argv[idx + 5 + da]->arg, &vtep_ip)) {
d62a17ae 5104 vty_out(vty, "%% Malformed VTEP IP address\n");
5105 return CMD_WARNING;
5106 }
5107 }
520d5d76 5108
c7ef6cf2 5109 evpn_show_routes_vni_all(vty, bgp, vtep_ip, json, da);
9c92b5f7 5110
c48349e3 5111 if (uj)
75eeda93 5112 vty_json(vty, json);
9c92b5f7 5113
d62a17ae 5114 return CMD_SUCCESS;
520d5d76 5115}
5116
229587fb 5117DEFPY_HIDDEN(
d656e0ae
AK
5118 show_bgp_l2vpn_evpn_route_mac_ip_evi_es,
5119 show_bgp_l2vpn_evpn_route_mac_ip_evi_es_cmd,
5120 "show bgp l2vpn evpn route mac-ip-evi-es [NAME$esi_str|detail$detail] [json$uj]",
229587fb
AK
5121 SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR
5122 "EVPN route information\n"
d656e0ae 5123 "MAC IP routes in the EVI tables linked to the ES\n"
229587fb
AK
5124 "ES ID\n"
5125 "Detailed information\n" JSON_STR)
5126{
5127 esi_t esi;
5128 esi_t *esi_p;
5129 json_object *json = NULL;
5130
5131 if (esi_str) {
5132 if (!str_to_esi(esi_str, &esi)) {
5133 vty_out(vty, "%%Malformed ESI\n");
5134 return CMD_WARNING;
5135 }
5136 esi_p = &esi;
5137 } else {
5138 esi_p = NULL;
5139 }
5140
5141 if (uj)
5142 json = json_object_new_object();
d656e0ae 5143 bgp_evpn_show_routes_mac_ip_evi_es(vty, esi_p, json, !!detail);
c48349e3 5144 if (uj)
75eeda93 5145 vty_json(vty, json);
229587fb
AK
5146
5147 return CMD_SUCCESS;
5148}
5149
58bff4d1
AK
5150DEFPY_HIDDEN(
5151 show_bgp_l2vpn_evpn_route_mac_ip_global_es,
5152 show_bgp_l2vpn_evpn_route_mac_ip_global_es_cmd,
5153 "show bgp l2vpn evpn route mac-ip-global-es [NAME$esi_str|detail$detail] [json$uj]",
5154 SHOW_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR
5155 "EVPN route information\n"
5156 "MAC IP routes in the global table linked to the ES\n"
5157 "ES ID\n"
5158 "Detailed information\n" JSON_STR)
5159{
5160 esi_t esi;
5161 esi_t *esi_p;
5162 json_object *json = NULL;
5163
5164 if (esi_str) {
5165 if (!str_to_esi(esi_str, &esi)) {
5166 vty_out(vty, "%%Malformed ESI\n");
5167 return CMD_WARNING;
5168 }
5169 esi_p = &esi;
5170 } else {
5171 esi_p = NULL;
5172 }
5173
5174 if (uj)
5175 json = json_object_new_object();
5176 bgp_evpn_show_routes_mac_ip_global_es(vty, esi_p, json, !!detail);
c48349e3 5177 if (uj)
75eeda93 5178 vty_json(vty, json);
58bff4d1
AK
5179
5180 return CMD_SUCCESS;
5181}
5182
10ebe1ab
MK
5183/*
5184 * Display EVPN import route-target hash table
5185 */
5186DEFUN(show_bgp_l2vpn_evpn_vrf_import_rt,
5187 show_bgp_l2vpn_evpn_vrf_import_rt_cmd,
5188 "show bgp l2vpn evpn vrf-import-rt [json]",
5189 SHOW_STR
5190 BGP_STR
5191 L2VPN_HELP_STR
5192 EVPN_HELP_STR
5193 "Show vrf import route target\n"
5194 JSON_STR)
5195{
9f049418 5196 bool uj = false;
5e53dce3 5197 struct bgp *bgp_evpn = NULL;
10ebe1ab
MK
5198 json_object *json = NULL;
5199
5e53dce3
T
5200 bgp_evpn = bgp_get_evpn();
5201 if (!bgp_evpn)
10ebe1ab
MK
5202 return CMD_WARNING;
5203
5204 uj = use_json(argc, argv);
5205 if (uj)
5206 json = json_object_new_object();
5207
5e53dce3 5208 evpn_show_vrf_import_rts(vty, bgp_evpn, json);
10ebe1ab 5209
c48349e3 5210 if (uj)
75eeda93 5211 vty_json(vty, json);
10ebe1ab
MK
5212
5213 return CMD_SUCCESS;
5214}
5215
f2d62262 5216/*
5217 * Display EVPN import route-target hash table
5218 */
60466a63
QY
5219DEFUN(show_bgp_l2vpn_evpn_import_rt,
5220 show_bgp_l2vpn_evpn_import_rt_cmd,
9c92b5f7
MK
5221 "show bgp l2vpn evpn import-rt [json]",
5222 SHOW_STR
5223 BGP_STR
5224 L2VPN_HELP_STR
5225 EVPN_HELP_STR
5226 "Show import route target\n"
5227 JSON_STR)
520d5d76 5228{
d62a17ae 5229 struct bgp *bgp;
9f049418 5230 bool uj = false;
9c92b5f7 5231 json_object *json = NULL;
520d5d76 5232
530db8dc 5233 bgp = bgp_get_evpn();
d62a17ae 5234 if (!bgp)
5235 return CMD_WARNING;
520d5d76 5236
9c92b5f7
MK
5237 uj = use_json(argc, argv);
5238 if (uj)
5239 json = json_object_new_object();
5240
5241 evpn_show_import_rts(vty, bgp, json);
5242
c48349e3 5243 if (uj)
75eeda93 5244 vty_json(vty, json);
9c92b5f7 5245
d62a17ae 5246 return CMD_SUCCESS;
520d5d76 5247}
5248
1673a90d 5249DEFPY_HIDDEN(test_es_add,
b5e140c8
AK
5250 test_es_add_cmd,
5251 "[no$no] test es NAME$esi_str [state NAME$state_str]",
5252 NO_STR
5253 "Test\n"
50f74cf1 5254 "Ethernet-segment\n"
b5e140c8
AK
5255 "Ethernet-Segment Identifier\n"
5256 "ES link state\n"
5257 "up|down\n"
5258)
50f74cf1 5259{
5260 int ret = 0;
5261 esi_t esi;
5262 struct bgp *bgp;
b5e140c8
AK
5263 struct in_addr vtep_ip;
5264 bool oper_up;
50f74cf1 5265
530db8dc 5266 bgp = bgp_get_evpn();
50f74cf1 5267 if (!bgp) {
530db8dc 5268 vty_out(vty, "%%EVPN BGP instance not yet created\n");
50f74cf1 5269 return CMD_WARNING;
5270 }
5271
b5e140c8 5272 if (!str_to_esi(esi_str, &esi)) {
50f74cf1 5273 vty_out(vty, "%%Malformed ESI\n");
5274 return CMD_WARNING;
5275 }
5276
b5e140c8
AK
5277 if (no) {
5278 ret = bgp_evpn_local_es_del(bgp, &esi);
5279 if (ret == -1) {
5280 vty_out(vty, "%%Failed to delete ES\n");
5281 return CMD_WARNING;
5282 }
5283 } else {
5284 if (state_str && !strcmp(state_str, "up"))
5285 oper_up = true;
5286 else
5287 oper_up = false;
5288 vtep_ip = bgp->router_id;
50f74cf1 5289
74e2bd89 5290 ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up,
74be8313 5291 EVPN_MH_DF_PREF_MIN, false);
b5e140c8
AK
5292 if (ret == -1) {
5293 vty_out(vty, "%%Failed to add ES\n");
5294 return CMD_WARNING;
5295 }
50f74cf1 5296 }
5297 return CMD_SUCCESS;
5298}
5299
1673a90d 5300DEFPY_HIDDEN(test_es_vni_add,
b5e140c8
AK
5301 test_es_vni_add_cmd,
5302 "[no$no] test es NAME$esi_str vni (1-16777215)$vni",
5303 NO_STR
5304 "Test\n"
50f74cf1 5305 "Ethernet-segment\n"
b5e140c8
AK
5306 "Ethernet-Segment Identifier\n"
5307 "VNI\n"
5308 "1-16777215\n"
5309)
50f74cf1 5310{
5311 int ret = 0;
5312 esi_t esi;
5313 struct bgp *bgp;
50f74cf1 5314
530db8dc 5315 bgp = bgp_get_evpn();
50f74cf1 5316 if (!bgp) {
530db8dc 5317 vty_out(vty, "%%EVPN BGP instance not yet created\n");
50f74cf1 5318 return CMD_WARNING;
5319 }
5320
b5e140c8 5321 if (!str_to_esi(esi_str, &esi)) {
50f74cf1 5322 vty_out(vty, "%%Malformed ESI\n");
5323 return CMD_WARNING;
5324 }
5325
b5e140c8
AK
5326 if (no) {
5327 ret = bgp_evpn_local_es_evi_del(bgp, &esi, vni);
5328 if (ret == -1) {
5329 vty_out(vty, "%%Failed to deref ES VNI\n");
5330 return CMD_WARNING;
5331 }
5332 } else {
5333 ret = bgp_evpn_local_es_evi_add(bgp, &esi, vni);
5334 if (ret == -1) {
5335 vty_out(vty, "%%Failed to ref ES VNI\n");
5336 return CMD_WARNING;
5337 }
50f74cf1 5338 }
5339 return CMD_SUCCESS;
5340}
5341
5014d96f 5342ALIAS_HIDDEN(show_bgp_l2vpn_evpn_vni, show_bgp_evpn_vni_cmd,
093e3f23 5343 "show bgp evpn vni [" CMD_VNI_RANGE "]", SHOW_STR BGP_STR EVPN_HELP_STR
5014d96f
DW
5344 "Show VNI\n"
5345 "VNI number\n")
5346
5347ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary, show_bgp_evpn_summary_cmd,
5348 "show bgp evpn summary [json]", SHOW_STR BGP_STR EVPN_HELP_STR
996c9314 5349 "Summary of BGP neighbor status\n" JSON_STR)
5014d96f
DW
5350
5351ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd,
2b1364e1 5352 "show bgp evpn route [detail] [type <macip|2|multicast|3>]",
5014d96f 5353 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a 5354 EVPN_RT_HELP_STR
21f3551e 5355 "Display Detailed Information\n"
f5dc0b1a
SW
5356 EVPN_TYPE_HELP_STR
5357 EVPN_TYPE_2_HELP_STR
2b1364e1
SW
5358 EVPN_TYPE_2_HELP_STR
5359 EVPN_TYPE_3_HELP_STR
f5dc0b1a 5360 EVPN_TYPE_3_HELP_STR)
5014d96f
DW
5361
5362ALIAS_HIDDEN(
5363 show_bgp_l2vpn_evpn_route_rd, show_bgp_evpn_route_rd_cmd,
2b1364e1 5364 "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|2|multicast|3>]",
5014d96f 5365 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a
SW
5366 EVPN_RT_HELP_STR
5367 EVPN_RT_DIST_HELP_STR
5368 EVPN_ASN_IP_HELP_STR
5369 EVPN_TYPE_HELP_STR
5370 EVPN_TYPE_2_HELP_STR
2b1364e1
SW
5371 EVPN_TYPE_2_HELP_STR
5372 EVPN_TYPE_3_HELP_STR
f5dc0b1a 5373 EVPN_TYPE_3_HELP_STR)
5014d96f
DW
5374
5375ALIAS_HIDDEN(
5376 show_bgp_l2vpn_evpn_route_rd_macip, show_bgp_evpn_route_rd_macip_cmd,
d114b977 5377 "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD]",
5014d96f 5378 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a
SW
5379 EVPN_RT_HELP_STR
5380 EVPN_RT_DIST_HELP_STR
5381 EVPN_ASN_IP_HELP_STR
5014d96f
DW
5382 "MAC\n"
5383 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
5384 "IP\n"
5385 "IP address (IPv4 or IPv6)\n")
5386
5387ALIAS_HIDDEN(
5388 show_bgp_l2vpn_evpn_route_vni, show_bgp_evpn_route_vni_cmd,
2b1364e1 5389 "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|2|multicast|3> | vtep A.B.C.D>]",
5014d96f 5390 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a 5391 EVPN_RT_HELP_STR
5014d96f
DW
5392 "VXLAN Network Identifier\n"
5393 "VNI number\n"
f5dc0b1a
SW
5394 EVPN_TYPE_HELP_STR
5395 EVPN_TYPE_2_HELP_STR
2b1364e1
SW
5396 EVPN_TYPE_2_HELP_STR
5397 EVPN_TYPE_3_HELP_STR
f5dc0b1a 5398 EVPN_TYPE_3_HELP_STR
5014d96f
DW
5399 "Remote VTEP\n"
5400 "Remote VTEP IP address\n")
5401
5402ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
5403 show_bgp_evpn_route_vni_macip_cmd,
093e3f23 5404 "show bgp evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD]",
5014d96f 5405 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a 5406 EVPN_RT_HELP_STR
5014d96f
DW
5407 "VXLAN Network Identifier\n"
5408 "VNI number\n"
5409 "MAC\n"
5410 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
5411 "IP\n"
5412 "IP address (IPv4 or IPv6)\n")
5413
5414ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast,
5415 show_bgp_evpn_route_vni_multicast_cmd,
093e3f23 5416 "show bgp evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D",
5014d96f 5417 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a 5418 EVPN_RT_HELP_STR
5014d96f
DW
5419 "VXLAN Network Identifier\n"
5420 "VNI number\n"
f5dc0b1a 5421 EVPN_TYPE_3_HELP_STR
5014d96f
DW
5422 "Originating Router IP address\n")
5423
5424ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all, show_bgp_evpn_route_vni_all_cmd,
c7ef6cf2 5425 "show bgp evpn route vni all [detail] [vtep A.B.C.D]",
5014d96f 5426 SHOW_STR BGP_STR EVPN_HELP_STR
f5dc0b1a 5427 EVPN_RT_HELP_STR
5014d96f
DW
5428 "VXLAN Network Identifier\n"
5429 "All VNIs\n"
c7ef6cf2 5430 "Print Detailed Output\n"
5014d96f
DW
5431 "Remote VTEP\n"
5432 "Remote VTEP IP address\n")
5433
5434ALIAS_HIDDEN(show_bgp_l2vpn_evpn_import_rt, show_bgp_evpn_import_rt_cmd,
5435 "show bgp evpn import-rt",
5436 SHOW_STR BGP_STR EVPN_HELP_STR "Show import route target\n")
5014d96f 5437
90e60aa7 5438DEFUN_NOSH (bgp_evpn_vni,
5439 bgp_evpn_vni_cmd,
093e3f23 5440 "vni " CMD_VNI_RANGE,
90e60aa7 5441 "VXLAN Network Identifier\n"
5442 "VNI number\n")
5443{
d62a17ae 5444 vni_t vni;
5445 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5446 struct bgpevpn *vpn;
90e60aa7 5447
d62a17ae 5448 if (!bgp)
5449 return CMD_WARNING;
90e60aa7 5450
d62a17ae 5451 vni = strtoul(argv[1]->arg, NULL, 10);
90e60aa7 5452
d62a17ae 5453 /* Create VNI, or mark as configured. */
5454 vpn = evpn_create_update_vni(bgp, vni);
5455 if (!vpn) {
5456 vty_out(vty, "%% Failed to create VNI \n");
5457 return CMD_WARNING;
5458 }
90e60aa7 5459
d62a17ae 5460 VTY_PUSH_CONTEXT_SUB(BGP_EVPN_VNI_NODE, vpn);
5461 return CMD_SUCCESS;
90e60aa7 5462}
5463
5464DEFUN (no_bgp_evpn_vni,
5465 no_bgp_evpn_vni_cmd,
093e3f23 5466 "no vni " CMD_VNI_RANGE,
90e60aa7 5467 NO_STR
5468 "VXLAN Network Identifier\n"
5469 "VNI number\n")
5470{
d62a17ae 5471 vni_t vni;
5472 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5473 struct bgpevpn *vpn;
90e60aa7 5474
d62a17ae 5475 if (!bgp)
5476 return CMD_WARNING;
90e60aa7 5477
d62a17ae 5478 vni = strtoul(argv[2]->arg, NULL, 10);
90e60aa7 5479
d62a17ae 5480 /* Check if we should disallow. */
5481 vpn = bgp_evpn_lookup_vni(bgp, vni);
5482 if (!vpn) {
5483 vty_out(vty, "%% Specified VNI does not exist\n");
5484 return CMD_WARNING;
5485 }
5486 if (!is_vni_configured(vpn)) {
5487 vty_out(vty, "%% Specified VNI is not configured\n");
5488 return CMD_WARNING;
5489 }
90e60aa7 5490
d62a17ae 5491 evpn_delete_vni(bgp, vpn);
5492 return CMD_SUCCESS;
90e60aa7 5493}
5494
5495DEFUN_NOSH (exit_vni,
5496 exit_vni_cmd,
5497 "exit-vni",
5498 "Exit from VNI mode\n")
5499{
d62a17ae 5500 if (vty->node == BGP_EVPN_VNI_NODE)
5501 vty->node = BGP_EVPN_NODE;
5502 return CMD_SUCCESS;
90e60aa7 5503}
5504
676f83b9 5505DEFUN (bgp_evpn_vrf_rd,
5506 bgp_evpn_vrf_rd_cmd,
5507 "rd ASN:NN_OR_IP-ADDRESS:NN",
f5dc0b1a
SW
5508 EVPN_RT_DIST_HELP_STR
5509 EVPN_ASN_IP_HELP_STR)
676f83b9 5510{
5511 int ret;
5512 struct prefix_rd prd;
5513 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
5514
5515 if (!bgp_vrf)
5516 return CMD_WARNING;
5517
5518 ret = str2prefix_rd(argv[1]->arg, &prd);
5519 if (!ret) {
5520 vty_out(vty, "%% Malformed Route Distinguisher\n");
5521 return CMD_WARNING;
5522 }
5523
5524 /* If same as existing value, there is nothing more to do. */
5525 if (bgp_evpn_vrf_rd_matches_existing(bgp_vrf, &prd))
5526 return CMD_SUCCESS;
5527
5528 /* Configure or update the RD. */
5529 evpn_configure_vrf_rd(bgp_vrf, &prd);
5530 return CMD_SUCCESS;
5531}
5532
5533DEFUN (no_bgp_evpn_vrf_rd,
5534 no_bgp_evpn_vrf_rd_cmd,
5535 "no rd ASN:NN_OR_IP-ADDRESS:NN",
5536 NO_STR
f5dc0b1a
SW
5537 EVPN_RT_DIST_HELP_STR
5538 EVPN_ASN_IP_HELP_STR)
676f83b9 5539{
5540 int ret;
5541 struct prefix_rd prd;
5542 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
5543
5544 if (!bgp_vrf)
5545 return CMD_WARNING;
5546
5547 ret = str2prefix_rd(argv[2]->arg, &prd);
5548 if (!ret) {
5549 vty_out(vty, "%% Malformed Route Distinguisher\n");
5550 return CMD_WARNING;
5551 }
5552
5553 /* Check if we should disallow. */
5554 if (!is_vrf_rd_configured(bgp_vrf)) {
5555 vty_out(vty, "%% RD is not configured for this VRF\n");
5556 return CMD_WARNING;
5557 }
5558
5559 if (!bgp_evpn_vrf_rd_matches_existing(bgp_vrf, &prd)) {
5560 vty_out(vty,
5561 "%% RD specified does not match configuration for this VRF\n");
5562 return CMD_WARNING;
5563 }
5564
5565 evpn_unconfigure_vrf_rd(bgp_vrf);
5566 return CMD_SUCCESS;
5567}
5568
5569DEFUN (no_bgp_evpn_vrf_rd_without_val,
5570 no_bgp_evpn_vrf_rd_without_val_cmd,
5571 "no rd",
5572 NO_STR
f5dc0b1a 5573 EVPN_RT_DIST_HELP_STR)
676f83b9 5574{
5575 struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
5576
5577 if (!bgp_vrf)
5578 return CMD_WARNING;
5579
5580 /* Check if we should disallow. */
5581 if (!is_vrf_rd_configured(bgp_vrf)) {
5582 vty_out(vty, "%% RD is not configured for this VRF\n");
5583 return CMD_WARNING;
5584 }
5585
5586 evpn_unconfigure_vrf_rd(bgp_vrf);
5587 return CMD_SUCCESS;
5588}
5589
90e60aa7 5590DEFUN (bgp_evpn_vni_rd,
5591 bgp_evpn_vni_rd_cmd,
d114b977 5592 "rd ASN:NN_OR_IP-ADDRESS:NN",
f5dc0b1a
SW
5593 EVPN_RT_DIST_HELP_STR
5594 EVPN_ASN_IP_HELP_STR)
90e60aa7 5595{
d62a17ae 5596 struct prefix_rd prd;
5597 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5598 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
5599 int ret;
90e60aa7 5600
06fe25f4 5601 if (!bgp)
d62a17ae 5602 return CMD_WARNING;
90e60aa7 5603
f920dd6d 5604 if (!EVPN_ENABLED(bgp)) {
a2a8153f 5605 vty_out(vty,
530db8dc 5606 "This command is only supported under EVPN VRF\n");
a2a8153f
CS
5607 return CMD_WARNING;
5608 }
5609
d62a17ae 5610 ret = str2prefix_rd(argv[1]->arg, &prd);
5611 if (!ret) {
5612 vty_out(vty, "%% Malformed Route Distinguisher\n");
5613 return CMD_WARNING;
5614 }
90e60aa7 5615
d62a17ae 5616 /* If same as existing value, there is nothing more to do. */
5617 if (bgp_evpn_rd_matches_existing(vpn, &prd))
5618 return CMD_SUCCESS;
90e60aa7 5619
d62a17ae 5620 /* Configure or update the RD. */
5621 evpn_configure_rd(bgp, vpn, &prd);
5622 return CMD_SUCCESS;
90e60aa7 5623}
5624
5625DEFUN (no_bgp_evpn_vni_rd,
5626 no_bgp_evpn_vni_rd_cmd,
d114b977 5627 "no rd ASN:NN_OR_IP-ADDRESS:NN",
90e60aa7 5628 NO_STR
f5dc0b1a
SW
5629 EVPN_RT_DIST_HELP_STR
5630 EVPN_ASN_IP_HELP_STR)
90e60aa7 5631{
d62a17ae 5632 struct prefix_rd prd;
5633 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5634 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
5635 int ret;
90e60aa7 5636
06fe25f4 5637 if (!bgp)
d62a17ae 5638 return CMD_WARNING;
90e60aa7 5639
f920dd6d 5640 if (!EVPN_ENABLED(bgp)) {
a2a8153f 5641 vty_out(vty,
530db8dc 5642 "This command is only supported under EVPN VRF\n");
a2a8153f
CS
5643 return CMD_WARNING;
5644 }
5645
d62a17ae 5646 ret = str2prefix_rd(argv[2]->arg, &prd);
5647 if (!ret) {
5648 vty_out(vty, "%% Malformed Route Distinguisher\n");
5649 return CMD_WARNING;
5650 }
90e60aa7 5651
d62a17ae 5652 /* Check if we should disallow. */
5653 if (!is_rd_configured(vpn)) {
5654 vty_out(vty, "%% RD is not configured for this VNI\n");
5655 return CMD_WARNING;
5656 }
90e60aa7 5657
d62a17ae 5658 if (!bgp_evpn_rd_matches_existing(vpn, &prd)) {
5659 vty_out(vty,
5660 "%% RD specified does not match configuration for this VNI\n");
5661 return CMD_WARNING;
5662 }
90e60aa7 5663
d62a17ae 5664 evpn_unconfigure_rd(bgp, vpn);
5665 return CMD_SUCCESS;
90e60aa7 5666}
5667
5668DEFUN (no_bgp_evpn_vni_rd_without_val,
5669 no_bgp_evpn_vni_rd_without_val_cmd,
5670 "no rd",
5671 NO_STR
f5dc0b1a 5672 EVPN_RT_DIST_HELP_STR)
90e60aa7 5673{
d62a17ae 5674 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5675 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
90e60aa7 5676
06fe25f4 5677 if (!bgp)
d62a17ae 5678 return CMD_WARNING;
90e60aa7 5679
f920dd6d 5680 if (!EVPN_ENABLED(bgp)) {
a2a8153f 5681 vty_out(vty,
530db8dc 5682 "This command is only supported under EVPN VRF\n");
a2a8153f
CS
5683 return CMD_WARNING;
5684 }
5685
d62a17ae 5686 /* Check if we should disallow. */
5687 if (!is_rd_configured(vpn)) {
5688 vty_out(vty, "%% RD is not configured for this VNI\n");
5689 return CMD_WARNING;
5690 }
90e60aa7 5691
d62a17ae 5692 evpn_unconfigure_rd(bgp, vpn);
5693 return CMD_SUCCESS;
90e60aa7 5694}
5695
5696/*
5697 * Loop over all extended-communities in the route-target list rtl and
5698 * return 1 if we find ecomtarget
5699 */
d62a17ae 5700static int bgp_evpn_rt_matches_existing(struct list *rtl,
5701 struct ecommunity *ecomtarget)
90e60aa7 5702{
d62a17ae 5703 struct listnode *node, *nnode;
5704 struct ecommunity *ecom;
90e60aa7 5705
d62a17ae 5706 for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
5707 if (ecommunity_match(ecom, ecomtarget))
5708 return 1;
5709 }
90e60aa7 5710
d62a17ae 5711 return 0;
90e60aa7 5712}
5713
c581d8b0
MK
5714/* display L3VNI related info for a VRF instance */
5715DEFUN (show_bgp_vrf_l3vni_info,
5716 show_bgp_vrf_l3vni_info_cmd,
4cce389e 5717 "show bgp vrf VRFNAME vni [json]",
c581d8b0
MK
5718 SHOW_STR
5719 BGP_STR
5720 "show bgp vrf\n"
5721 "VRF Name\n"
5722 "L3-VNI\n"
ceb9a921 5723 JSON_STR)
c581d8b0
MK
5724{
5725 char buf[ETHER_ADDR_STRLEN];
676f83b9 5726 char buf1[INET6_ADDRSTRLEN];
c581d8b0
MK
5727 int idx_vrf = 3;
5728 const char *name = NULL;
5729 struct bgp *bgp = NULL;
5730 struct listnode *node = NULL;
6a8657d0 5731 struct bgpevpn *vpn = NULL;
c581d8b0 5732 struct ecommunity *ecom = NULL;
ceb9a921
MK
5733 json_object *json = NULL;
5734 json_object *json_vnis = NULL;
5735 json_object *json_export_rts = NULL;
5736 json_object *json_import_rts = NULL;
9f049418 5737 bool uj = use_json(argc, argv);
ceb9a921
MK
5738
5739 if (uj) {
5740 json = json_object_new_object();
5741 json_vnis = json_object_new_array();
5742 json_export_rts = json_object_new_array();
5743 json_import_rts = json_object_new_array();
5744 }
c581d8b0
MK
5745
5746 name = argv[idx_vrf]->arg;
5747 bgp = bgp_lookup_by_name(name);
5748 if (!bgp) {
ceb9a921 5749 if (!uj)
996c9314 5750 vty_out(vty, "BGP instance for VRF %s not found", name);
ceb9a921
MK
5751 else {
5752 json_object_string_add(json, "warning",
5753 "BGP instance not found");
996c9314 5754 vty_out(vty, "%s\n", json_object_to_json_string(json));
ceb9a921
MK
5755 json_object_free(json);
5756 }
c581d8b0
MK
5757 return CMD_WARNING;
5758 }
5759
ceb9a921
MK
5760 if (!json) {
5761 vty_out(vty, "BGP VRF: %s\n", name);
23d0a753 5762 vty_out(vty, " Local-Ip: %pI4\n", &bgp->originator_ip);
ceb9a921
MK
5763 vty_out(vty, " L3-VNI: %u\n", bgp->l3vni);
5764 vty_out(vty, " Rmac: %s\n",
5765 prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
c48d9f5f
MK
5766 vty_out(vty, " VNI Filter: %s\n",
5767 CHECK_FLAG(bgp->vrf_flags,
996c9314
LB
5768 BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)
5769 ? "prefix-routes-only"
5770 : "none");
ceb9a921
MK
5771 vty_out(vty, " L2-VNI List:\n");
5772 vty_out(vty, " ");
5773 for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn))
5774 vty_out(vty, "%u ", vpn->vni);
5775 vty_out(vty, "\n");
5776 vty_out(vty, " Export-RTs:\n");
5777 vty_out(vty, " ");
5778 for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom))
5779 vty_out(vty, "%s ", ecommunity_str(ecom));
5780 vty_out(vty, "\n");
5781 vty_out(vty, " Import-RTs:\n");
5782 vty_out(vty, " ");
5783 for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom))
5784 vty_out(vty, "%s ", ecommunity_str(ecom));
5785 vty_out(vty, "\n");
676f83b9 5786 vty_out(vty, " RD: %s\n",
5787 prefix_rd2str(&bgp->vrf_prd, buf1, RD_ADDRSTRLEN));
ceb9a921
MK
5788 } else {
5789 json_object_string_add(json, "vrf", name);
c949c771
DA
5790 json_object_string_addf(json, "local-ip", "%pI4",
5791 &bgp->originator_ip);
ceb9a921 5792 json_object_int_add(json, "l3vni", bgp->l3vni);
996c9314
LB
5793 json_object_string_add(
5794 json, "rmac",
5795 prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
5796 json_object_string_add(
5797 json, "vniFilter",
5798 CHECK_FLAG(bgp->vrf_flags,
5799 BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)
5800 ? "prefix-routes-only"
5801 : "none");
ceb9a921
MK
5802 /* list of l2vnis */
5803 for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn))
5804 json_object_array_add(json_vnis,
5805 json_object_new_int(vpn->vni));
5806 json_object_object_add(json, "l2vnis", json_vnis);
5807
5808 /* export rts */
5809 for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom))
996c9314
LB
5810 json_object_array_add(
5811 json_export_rts,
5812 json_object_new_string(ecommunity_str(ecom)));
ceb9a921
MK
5813 json_object_object_add(json, "export-rts", json_export_rts);
5814
5815 /* import rts */
5816 for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom))
996c9314
LB
5817 json_object_array_add(
5818 json_import_rts,
5819 json_object_new_string(ecommunity_str(ecom)));
ceb9a921 5820 json_object_object_add(json, "import-rts", json_import_rts);
676f83b9 5821 json_object_string_add(
5822 json, "rd",
5823 prefix_rd2str(&bgp->vrf_prd, buf1, RD_ADDRSTRLEN));
ceb9a921 5824 }
c581d8b0 5825
c48349e3 5826 if (uj)
75eeda93 5827 vty_json(vty, json);
c581d8b0
MK
5828 return CMD_SUCCESS;
5829}
5830
5831/* import/export rt for l3vni-vrf */
5832DEFUN (bgp_evpn_vrf_rt,
5833 bgp_evpn_vrf_rt_cmd,
5834 "route-target <both|import|export> RT",
5835 "Route Target\n"
5836 "import and export\n"
5837 "import\n"
5838 "export\n"
5839 "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
5840{
5841 int rt_type;
5842 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5843 struct ecommunity *ecomadd = NULL;
5844
5845 if (!bgp)
5846 return CMD_WARNING;
5847
5848 if (!strcmp(argv[1]->arg, "import"))
5849 rt_type = RT_TYPE_IMPORT;
5850 else if (!strcmp(argv[1]->arg, "export"))
5851 rt_type = RT_TYPE_EXPORT;
5852 else if (!strcmp(argv[1]->arg, "both"))
5853 rt_type = RT_TYPE_BOTH;
5854 else {
5855 vty_out(vty, "%% Invalid Route Target type\n");
5856 return CMD_WARNING;
5857 }
5858
5859 /* Add/update the import route-target */
5860 if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) {
5861 ecomadd = ecommunity_str2com(argv[2]->arg,
5862 ECOMMUNITY_ROUTE_TARGET, 0);
5863 if (!ecomadd) {
5864 vty_out(vty, "%% Malformed Route Target list\n");
5865 return CMD_WARNING;
5866 }
5867 ecommunity_str(ecomadd);
5868
5869 /* Do nothing if we already have this import route-target */
996c9314 5870 if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl, ecomadd))
c581d8b0
MK
5871 bgp_evpn_configure_import_rt_for_vrf(bgp, ecomadd);
5872 }
5873
5874 /* Add/update the export route-target */
5875 if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) {
5876 ecomadd = ecommunity_str2com(argv[2]->arg,
5877 ECOMMUNITY_ROUTE_TARGET, 0);
5878 if (!ecomadd) {
5879 vty_out(vty, "%% Malformed Route Target list\n");
5880 return CMD_WARNING;
5881 }
5882 ecommunity_str(ecomadd);
5883
5884 /* Do nothing if we already have this export route-target */
996c9314 5885 if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl, ecomadd))
c581d8b0
MK
5886 bgp_evpn_configure_export_rt_for_vrf(bgp, ecomadd);
5887 }
5888
5889 return CMD_SUCCESS;
5890}
5891
5892DEFUN (no_bgp_evpn_vrf_rt,
5893 no_bgp_evpn_vrf_rt_cmd,
5894 "no route-target <both|import|export> RT",
5895 NO_STR
5896 "Route Target\n"
5897 "import and export\n"
5898 "import\n"
5899 "export\n"
f5dc0b1a 5900 EVPN_ASN_IP_HELP_STR)
c581d8b0
MK
5901{
5902 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
5903 int rt_type, found_ecomdel;
5904 struct ecommunity *ecomdel = NULL;
5905
5906 if (!bgp)
5907 return CMD_WARNING;
5908
5909 if (!strcmp(argv[2]->arg, "import"))
5910 rt_type = RT_TYPE_IMPORT;
5911 else if (!strcmp(argv[2]->arg, "export"))
5912 rt_type = RT_TYPE_EXPORT;
5913 else if (!strcmp(argv[2]->arg, "both"))
5914 rt_type = RT_TYPE_BOTH;
5915 else {
5916 vty_out(vty, "%% Invalid Route Target type\n");
5917 return CMD_WARNING;
5918 }
5919
5920 if (rt_type == RT_TYPE_IMPORT) {
5921 if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
5922 vty_out(vty,
5923 "%% Import RT is not configured for this VRF\n");
5924 return CMD_WARNING;
5925 }
5926 } else if (rt_type == RT_TYPE_EXPORT) {
5927 if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
5928 vty_out(vty,
5929 "%% Export RT is not configured for this VRF\n");
5930 return CMD_WARNING;
5931 }
5932 } else if (rt_type == RT_TYPE_BOTH) {
5933 if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)
5934 && !CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
5935 vty_out(vty,
5936 "%% Import/Export RT is not configured for this VRF\n");
5937 return CMD_WARNING;
5938 }
5939 }
5940
5941 ecomdel = ecommunity_str2com(argv[3]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
5942 if (!ecomdel) {
5943 vty_out(vty, "%% Malformed Route Target list\n");
5944 return CMD_WARNING;
5945 }
5946 ecommunity_str(ecomdel);
5947
5948 if (rt_type == RT_TYPE_IMPORT) {
5949 if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
5950 ecomdel)) {
736e6a45 5951 ecommunity_free(&ecomdel);
c581d8b0
MK
5952 vty_out(vty,
5953 "%% RT specified does not match configuration for this VRF\n");
5954 return CMD_WARNING;
5955 }
5956 bgp_evpn_unconfigure_import_rt_for_vrf(bgp, ecomdel);
5957 } else if (rt_type == RT_TYPE_EXPORT) {
5958 if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl,
5959 ecomdel)) {
736e6a45 5960 ecommunity_free(&ecomdel);
c581d8b0
MK
5961 vty_out(vty,
5962 "%% RT specified does not match configuration for this VRF\n");
5963 return CMD_WARNING;
5964 }
5965 bgp_evpn_unconfigure_export_rt_for_vrf(bgp, ecomdel);
5966 } else if (rt_type == RT_TYPE_BOTH) {
5967 found_ecomdel = 0;
5968
5969 if (bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
5970 ecomdel)) {
5971 bgp_evpn_unconfigure_import_rt_for_vrf(bgp, ecomdel);
5972 found_ecomdel = 1;
5973 }
5974
5975 if (bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl,
5976 ecomdel)) {
5977 bgp_evpn_unconfigure_export_rt_for_vrf(bgp, ecomdel);
5978 found_ecomdel = 1;
5979 }
5980
5981 if (!found_ecomdel) {
736e6a45 5982 ecommunity_free(&ecomdel);
c581d8b0
MK
5983 vty_out(vty,
5984 "%% RT specified does not match configuration for this VRF\n");
5985 return CMD_WARNING;
5986 }
5987 }
5988
736e6a45 5989 ecommunity_free(&ecomdel);
c581d8b0
MK
5990 return CMD_SUCCESS;
5991}
90e60aa7 5992
5993DEFUN (bgp_evpn_vni_rt,
5994 bgp_evpn_vni_rt_cmd,
5995 "route-target <both|import|export> RT",
5996 "Route Target\n"
5997 "import and export\n"
5998 "import\n"
5999 "export\n"
6000 "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
6001{
d62a17ae 6002 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
6003 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
6004 int rt_type;
6005 struct ecommunity *ecomadd = NULL;
6006
06fe25f4 6007 if (!bgp)
d62a17ae 6008 return CMD_WARNING;
6009
f920dd6d 6010 if (!EVPN_ENABLED(bgp)) {
a2a8153f 6011 vty_out(vty,
530db8dc 6012 "This command is only supported under EVPN VRF\n");
a2a8153f
CS
6013 return CMD_WARNING;
6014 }
6015
8034beff 6016 if (!strcmp(argv[1]->text, "import"))
d62a17ae 6017 rt_type = RT_TYPE_IMPORT;
8034beff 6018 else if (!strcmp(argv[1]->text, "export"))
d62a17ae 6019 rt_type = RT_TYPE_EXPORT;
8034beff 6020 else if (!strcmp(argv[1]->text, "both"))
d62a17ae 6021 rt_type = RT_TYPE_BOTH;
6022 else {
6023 vty_out(vty, "%% Invalid Route Target type\n");
6024 return CMD_WARNING;
6025 }
6026
6027 /* Add/update the import route-target */
6028 if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) {
6029 ecomadd = ecommunity_str2com(argv[2]->arg,
6030 ECOMMUNITY_ROUTE_TARGET, 0);
d62a17ae 6031 if (!ecomadd) {
6032 vty_out(vty, "%% Malformed Route Target list\n");
6033 return CMD_WARNING;
6034 }
5bc2ed52 6035 ecommunity_str(ecomadd);
d62a17ae 6036
6037 /* Do nothing if we already have this import route-target */
6038 if (!bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomadd))
6039 evpn_configure_import_rt(bgp, vpn, ecomadd);
6040 }
6041
6042 /* Add/update the export route-target */
6043 if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) {
6044 ecomadd = ecommunity_str2com(argv[2]->arg,
6045 ECOMMUNITY_ROUTE_TARGET, 0);
d62a17ae 6046 if (!ecomadd) {
6047 vty_out(vty, "%% Malformed Route Target list\n");
6048 return CMD_WARNING;
6049 }
5bc2ed52 6050 ecommunity_str(ecomadd);
d62a17ae 6051
6052 /* Do nothing if we already have this export route-target */
6053 if (!bgp_evpn_rt_matches_existing(vpn->export_rtl, ecomadd))
6054 evpn_configure_export_rt(bgp, vpn, ecomadd);
6055 }
6056
6057 return CMD_SUCCESS;
90e60aa7 6058}
6059
6060DEFUN (no_bgp_evpn_vni_rt,
6061 no_bgp_evpn_vni_rt_cmd,
6062 "no route-target <both|import|export> RT",
6063 NO_STR
6064 "Route Target\n"
6065 "import and export\n"
6066 "import\n"
6067 "export\n"
f5dc0b1a 6068 EVPN_ASN_IP_HELP_STR)
90e60aa7 6069{
d62a17ae 6070 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
6071 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
6072 int rt_type, found_ecomdel;
6073 struct ecommunity *ecomdel = NULL;
6074
06fe25f4 6075 if (!bgp)
d62a17ae 6076 return CMD_WARNING;
6077
f920dd6d 6078 if (!EVPN_ENABLED(bgp)) {
a2a8153f 6079 vty_out(vty,
530db8dc 6080 "This command is only supported under EVPN VRF\n");
a2a8153f
CS
6081 return CMD_WARNING;
6082 }
6083
8034beff 6084 if (!strcmp(argv[2]->text, "import"))
d62a17ae 6085 rt_type = RT_TYPE_IMPORT;
8034beff 6086 else if (!strcmp(argv[2]->text, "export"))
d62a17ae 6087 rt_type = RT_TYPE_EXPORT;
8034beff 6088 else if (!strcmp(argv[2]->text, "both"))
d62a17ae 6089 rt_type = RT_TYPE_BOTH;
6090 else {
6091 vty_out(vty, "%% Invalid Route Target type\n");
6092 return CMD_WARNING;
6093 }
6094
6095 /* The user did "no route-target import", check to see if there are any
6096 * import route-targets configured. */
6097 if (rt_type == RT_TYPE_IMPORT) {
6098 if (!is_import_rt_configured(vpn)) {
6099 vty_out(vty,
6100 "%% Import RT is not configured for this VNI\n");
6101 return CMD_WARNING;
6102 }
6103 } else if (rt_type == RT_TYPE_EXPORT) {
6104 if (!is_export_rt_configured(vpn)) {
6105 vty_out(vty,
6106 "%% Export RT is not configured for this VNI\n");
6107 return CMD_WARNING;
6108 }
6109 } else if (rt_type == RT_TYPE_BOTH) {
6110 if (!is_import_rt_configured(vpn)
6111 && !is_export_rt_configured(vpn)) {
6112 vty_out(vty,
6113 "%% Import/Export RT is not configured for this VNI\n");
6114 return CMD_WARNING;
6115 }
6116 }
6117
6118 ecomdel = ecommunity_str2com(argv[3]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
d62a17ae 6119 if (!ecomdel) {
6120 vty_out(vty, "%% Malformed Route Target list\n");
6121 return CMD_WARNING;
6122 }
5bc2ed52 6123 ecommunity_str(ecomdel);
d62a17ae 6124
6125 if (rt_type == RT_TYPE_IMPORT) {
6126 if (!bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomdel)) {
6127 vty_out(vty,
6128 "%% RT specified does not match configuration for this VNI\n");
6129 return CMD_WARNING;
6130 }
6131 evpn_unconfigure_import_rt(bgp, vpn, ecomdel);
6132 } else if (rt_type == RT_TYPE_EXPORT) {
6133 if (!bgp_evpn_rt_matches_existing(vpn->export_rtl, ecomdel)) {
6134 vty_out(vty,
6135 "%% RT specified does not match configuration for this VNI\n");
6136 return CMD_WARNING;
6137 }
6138 evpn_unconfigure_export_rt(bgp, vpn, ecomdel);
6139 } else if (rt_type == RT_TYPE_BOTH) {
6140 found_ecomdel = 0;
6141
6142 if (bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomdel)) {
6143 evpn_unconfigure_import_rt(bgp, vpn, ecomdel);
6144 found_ecomdel = 1;
6145 }
6146
6147 if (bgp_evpn_rt_matches_existing(vpn->export_rtl, ecomdel)) {
6148 evpn_unconfigure_export_rt(bgp, vpn, ecomdel);
6149 found_ecomdel = 1;
6150 }
6151
6152 if (!found_ecomdel) {
6153 vty_out(vty,
6154 "%% RT specified does not match configuration for this VNI\n");
6155 return CMD_WARNING;
6156 }
6157 }
6158
6159 return CMD_SUCCESS;
90e60aa7 6160}
6161
6162DEFUN (no_bgp_evpn_vni_rt_without_val,
6163 no_bgp_evpn_vni_rt_without_val_cmd,
6164 "no route-target <import|export>",
6165 NO_STR
6166 "Route Target\n"
6167 "import\n"
6168 "export\n")
6169{
d62a17ae 6170 struct bgp *bgp = VTY_GET_CONTEXT(bgp);
6171 VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
6172 int rt_type;
6173
06fe25f4 6174 if (!bgp)
d62a17ae 6175 return CMD_WARNING;
6176
f920dd6d 6177 if (!EVPN_ENABLED(bgp)) {
a2a8153f 6178 vty_out(vty,
530db8dc 6179 "This command is only supported under EVPN VRF\n");
a2a8153f
CS
6180 return CMD_WARNING;
6181 }
6182
8034beff 6183 if (!strcmp(argv[2]->text, "import")) {
d62a17ae 6184 rt_type = RT_TYPE_IMPORT;
8034beff 6185 } else if (!strcmp(argv[2]->text, "export")) {
d62a17ae 6186 rt_type = RT_TYPE_EXPORT;
6187 } else {
6188 vty_out(vty, "%% Invalid Route Target type\n");
6189 return CMD_WARNING;
6190 }
6191
6192 /* Check if we should disallow. */
6193 if (rt_type == RT_TYPE_IMPORT) {
6194 if (!is_import_rt_configured(vpn)) {
6195 vty_out(vty,
6196 "%% Import RT is not configured for this VNI\n");
6197 return CMD_WARNING;
6198 }
6199 } else {
6200 if (!is_export_rt_configured(vpn)) {
6201 vty_out(vty,
6202 "%% Export RT is not configured for this VNI\n");
6203 return CMD_WARNING;
6204 }
6205 }
6206
6207 /* Unconfigure the RT. */
6208 if (rt_type == RT_TYPE_IMPORT)
6209 evpn_unconfigure_import_rt(bgp, vpn, NULL);
6210 else
6211 evpn_unconfigure_export_rt(bgp, vpn, NULL);
6212 return CMD_SUCCESS;
90e60aa7 6213}
568b6b44
QY
6214
6215static int vni_cmp(const void **a, const void **b)
6216{
6217 const struct bgpevpn *first = *a;
6218 const struct bgpevpn *secnd = *b;
6219
6220 return secnd->vni - first->vni;
6221}
6222
90e60aa7 6223/*
6224 * Output EVPN configuration information.
6225 */
d62a17ae 6226void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
2b791107 6227 safi_t safi)
d62a17ae 6228{
a75c2553 6229 char buf1[RD_ADDRSTRLEN];
1c97c9fd 6230 char buf2[INET6_ADDRSTRLEN];
a75c2553 6231
e67df34d
CS
6232 if (bgp->advertise_all_vni)
6233 vty_out(vty, " advertise-all-vni\n");
6234
568b6b44
QY
6235 if (bgp->vnihash) {
6236 struct list *vnilist = hash_to_list(bgp->vnihash);
6237 struct listnode *ln;
6238 struct bgpevpn *data;
6239
6240 list_sort(vnilist, vni_cmp);
6241 for (ALL_LIST_ELEMENTS_RO(vnilist, ln, data))
6242 write_vni_config(vty, data);
6243
6a154c88 6244 list_delete(&vnilist);
568b6b44 6245 }
90e60aa7 6246
bf1061d8
VB
6247 if (bgp->advertise_autort_rfc8365)
6248 vty_out(vty, " autort rfc8365-compatible\n");
6249
2b791107 6250 if (bgp->advertise_gw_macip)
1a98c087 6251 vty_out(vty, " advertise-default-gw\n");
6ee86383 6252
24864e44
CS
6253 if (bgp->evpn_info->advertise_svi_macip)
6254 vty_out(vty, " advertise-svi-ip\n");
6255
dc6cef73
AD
6256 if (bgp->resolve_overlay_index)
6257 vty_out(vty, " enable-resolve-overlay-index\n");
6258
2867823e
AK
6259 if (bgp_mh_info->host_routes_use_l3nhg !=
6260 BGP_EVPN_MH_USE_ES_L3NHG_DEF) {
6261 if (bgp_mh_info->host_routes_use_l3nhg)
6262 vty_out(vty, " use-es-l3nhg\n");
6263 else
6264 vty_out(vty, " no use-es-l3nhg\n");
6265 }
6266
fe8293c3
AK
6267 if (bgp_mh_info->ead_evi_rx != BGP_EVPN_MH_EAD_EVI_RX_DEF) {
6268 if (bgp_mh_info->ead_evi_rx)
6269 vty_out(vty, " no disable-ead-evi-rx\n");
6270 else
6271 vty_out(vty, " disable-ead-evi-rx\n");
6272 }
6273
6274 if (bgp_mh_info->ead_evi_tx != BGP_EVPN_MH_EAD_EVI_TX_DEF) {
6275 if (bgp_mh_info->ead_evi_tx)
6276 vty_out(vty, " no disable-ead-evi-tx\n");
6277 else
6278 vty_out(vty, " disable-ead-evi-tx\n");
6279 }
6280
0b9d9cd0
CS
6281 if (!bgp->evpn_info->dup_addr_detect)
6282 vty_out(vty, " no dup-addr-detection\n");
6283
6284 if (bgp->evpn_info->dad_max_moves !=
6285 EVPN_DAD_DEFAULT_MAX_MOVES ||
6286 bgp->evpn_info->dad_time != EVPN_DAD_DEFAULT_TIME)
6287 vty_out(vty, " dup-addr-detection max-moves %u time %u\n",
6288 bgp->evpn_info->dad_max_moves,
6289 bgp->evpn_info->dad_time);
6290
6291 if (bgp->evpn_info->dad_freeze) {
6292 if (bgp->evpn_info->dad_freeze_time)
6293 vty_out(vty,
6294 " dup-addr-detection freeze %u\n",
6295 bgp->evpn_info->dad_freeze_time);
6296 else
6297 vty_out(vty,
6298 " dup-addr-detection freeze permanent\n");
6299 }
6300
fd069644
DS
6301 if (bgp->vxlan_flood_ctrl == VXLAN_FLOOD_DISABLED)
6302 vty_out(vty, " flooding disable\n");
6303
154faa50 6304 if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
d4a88de3 6305 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST)) {
d2a0075a
MK
6306 if (bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name)
6307 vty_out(vty, " advertise ipv4 unicast route-map %s\n",
6308 bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name);
6309 else
d4a88de3
AD
6310 vty_out(vty,
6311 " advertise ipv4 unicast\n");
6312 } else if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
6313 BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) {
6314 if (bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name)
6315 vty_out(vty,
6316 " advertise ipv4 unicast gateway-ip route-map %s\n",
6317 bgp->adv_cmd_rmap[AFI_IP][SAFI_UNICAST].name);
6318 else
6319 vty_out(vty, " advertise ipv4 unicast gateway-ip\n");
d2a0075a 6320 }
6ee86383 6321
154faa50 6322 if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
d4a88de3 6323 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST)) {
d2a0075a 6324 if (bgp->adv_cmd_rmap[AFI_IP6][SAFI_UNICAST].name)
d4a88de3
AD
6325 vty_out(vty,
6326 " advertise ipv6 unicast route-map %s\n",
6327 bgp->adv_cmd_rmap[AFI_IP6][SAFI_UNICAST].name);
6328 else
6329 vty_out(vty,
6330 " advertise ipv6 unicast\n");
6331 } else if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
6332 BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP)) {
6333 if (bgp->adv_cmd_rmap[AFI_IP6][SAFI_UNICAST].name)
6334 vty_out(vty,
6335 " advertise ipv6 unicast gateway-ip route-map %s\n",
d2a0075a
MK
6336 bgp->adv_cmd_rmap[AFI_IP6][SAFI_UNICAST].name);
6337 else
d4a88de3 6338 vty_out(vty, " advertise ipv6 unicast gateway-ip\n");
d2a0075a 6339 }
486456ca
MK
6340
6341 if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
6342 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
6343 vty_out(vty, " default-originate ipv4\n");
6344
6345 if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
6346 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
6347 vty_out(vty, " default-originate ipv6\n");
58f9e4d3 6348
5394a276
CS
6349 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
6350 if (!bgp->evpn_info->advertise_pip)
6351 vty_out(vty, " no advertise-pip\n");
6352 if (bgp->evpn_info->advertise_pip) {
0137a3d8
CS
6353 if (bgp->evpn_info->pip_ip_static.s_addr
6354 != INADDR_ANY) {
5394a276 6355 vty_out(vty, " advertise-pip ip %s",
1c97c9fd
CS
6356 inet_ntop(AF_INET,
6357 &bgp->evpn_info->pip_ip_static,
6358 buf2, INET_ADDRSTRLEN));
0137a3d8
CS
6359 if (!is_zero_mac(&(
6360 bgp->evpn_info->pip_rmac_static))) {
6361 char buf[ETHER_ADDR_STRLEN];
6362
6363 vty_out(vty, " mac %s",
6364 prefix_mac2str(
6365 &bgp->evpn_info
6366 ->pip_rmac,
6367 buf, sizeof(buf)));
6368 }
6369 vty_out(vty, "\n");
5394a276 6370 }
5394a276
CS
6371 }
6372 }
a75c2553 6373 if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
9e97ff03 6374 vty_out(vty, " rd %s\n",
a75c2553
MK
6375 prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
6376
db29a4a8
MK
6377 /* import route-target */
6378 if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
6379 char *ecom_str;
6380 struct listnode *node, *nnode;
6381 struct ecommunity *ecom;
6382
6383 for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode,
6384 ecom)) {
6385 ecom_str = ecommunity_ecom2str(
6386 ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
530e8a6e 6387 vty_out(vty, " route-target import %s\n", ecom_str);
db29a4a8
MK
6388 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
6389 }
6390 }
6391
6392 /* export route-target */
6393 if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
6394 char *ecom_str;
6395 struct listnode *node, *nnode;
6396 struct ecommunity *ecom;
6397
6398 for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode,
6399 ecom)) {
6400 ecom_str = ecommunity_ecom2str(
6401 ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
530e8a6e 6402 vty_out(vty, " route-target export %s\n", ecom_str);
db29a4a8
MK
6403 XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
6404 }
6405 }
90e60aa7 6406}
6407
4d0e6ece 6408void bgp_ethernetvpn_init(void)
784d3a42 6409{
d62a17ae 6410 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_cmd);
6411 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_cmd);
6412 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_tags_cmd);
6413 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd);
6414 install_element(VIEW_NODE,
dcc1615e 6415 &show_ip_bgp_l2vpn_evpn_neighbor_routes_cmd);
d62a17ae 6416 install_element(VIEW_NODE,
6417 &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd);
6418 install_element(
6419 VIEW_NODE,
dcc1615e 6420 &show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes_cmd);
d62a17ae 6421 install_element(
6422 VIEW_NODE,
6423 &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd);
6424 install_element(VIEW_NODE, &show_ip_bgp_evpn_rd_overlay_cmd);
6425 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_overlay_cmd);
6426 install_element(BGP_EVPN_NODE, &no_evpnrt5_network_cmd);
6427 install_element(BGP_EVPN_NODE, &evpnrt5_network_cmd);
d62a17ae 6428 install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_all_vni_cmd);
6429 install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
bf1061d8
VB
6430 install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_autort_rfc8365_cmd);
6431 install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_autort_rfc8365_cmd);
1a98c087
MK
6432 install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_default_gw_cmd);
6433 install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
24864e44 6434 install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_svi_ip_cmd);
342dd0c6 6435 install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
6436 install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
486456ca
MK
6437 install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
6438 install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
0b9d9cd0
CS
6439 install_element(BGP_EVPN_NODE, &dup_addr_detection_cmd);
6440 install_element(BGP_EVPN_NODE, &dup_addr_detection_auto_recovery_cmd);
6441 install_element(BGP_EVPN_NODE, &no_dup_addr_detection_cmd);
fd069644 6442 install_element(BGP_EVPN_NODE, &bgp_evpn_flood_control_cmd);
5394a276 6443 install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_pip_ip_mac_cmd);
2867823e 6444 install_element(BGP_EVPN_NODE, &bgp_evpn_use_es_l3nhg_cmd);
fe8293c3
AK
6445 install_element(BGP_EVPN_NODE, &bgp_evpn_ead_evi_rx_disable_cmd);
6446 install_element(BGP_EVPN_NODE, &bgp_evpn_ead_evi_tx_disable_cmd);
dc6cef73
AD
6447 install_element(BGP_EVPN_NODE,
6448 &bgp_evpn_enable_resolve_overlay_index_cmd);
d62a17ae 6449
50f74cf1 6450 /* test commands */
b5e140c8
AK
6451 install_element(BGP_EVPN_NODE, &test_es_add_cmd);
6452 install_element(BGP_EVPN_NODE, &test_es_vni_add_cmd);
50f74cf1 6453
f2d62262 6454 /* "show bgp l2vpn evpn" commands. */
50f74cf1 6455 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_es_cmd);
b5e140c8 6456 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_es_evi_cmd);
229587fb 6457 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_es_vrf_cmd);
090efa2f 6458 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_nh_cmd);
f2d62262 6459 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
021b6596
AD
6460 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_remote_ip_hash_cmd);
6461 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_svi_hash_cmd);
f2d62262 6462 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_summary_cmd);
6463 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_cmd);
6464 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_rd_cmd);
6465 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_rd_macip_cmd);
50f74cf1 6466 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_esi_cmd);
f2d62262 6467 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_cmd);
6468 install_element(VIEW_NODE,
6469 &show_bgp_l2vpn_evpn_route_vni_multicast_cmd);
6470 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_macip_cmd);
6471 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_route_vni_all_cmd);
d656e0ae
AK
6472 install_element(VIEW_NODE,
6473 &show_bgp_l2vpn_evpn_route_mac_ip_evi_es_cmd);
58bff4d1
AK
6474 install_element(VIEW_NODE,
6475 &show_bgp_l2vpn_evpn_route_mac_ip_global_es_cmd);
f2d62262 6476 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_import_rt_cmd);
10ebe1ab 6477 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vrf_import_rt_cmd);
d62a17ae 6478
5014d96f
DW
6479 /* "show bgp evpn" commands. */
6480 install_element(VIEW_NODE, &show_bgp_evpn_vni_cmd);
6481 install_element(VIEW_NODE, &show_bgp_evpn_summary_cmd);
6482 install_element(VIEW_NODE, &show_bgp_evpn_route_cmd);
6483 install_element(VIEW_NODE, &show_bgp_evpn_route_rd_cmd);
6484 install_element(VIEW_NODE, &show_bgp_evpn_route_rd_macip_cmd);
6485 install_element(VIEW_NODE, &show_bgp_evpn_route_vni_cmd);
6486 install_element(VIEW_NODE, &show_bgp_evpn_route_vni_multicast_cmd);
6487 install_element(VIEW_NODE, &show_bgp_evpn_route_vni_macip_cmd);
6488 install_element(VIEW_NODE, &show_bgp_evpn_route_vni_all_cmd);
6489 install_element(VIEW_NODE, &show_bgp_evpn_import_rt_cmd);
c581d8b0 6490 install_element(VIEW_NODE, &show_bgp_vrf_l3vni_info_cmd);
7f433a5e 6491 install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_com_cmd);
5014d96f 6492
d62a17ae 6493 install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd);
6494 install_element(BGP_EVPN_NODE, &no_bgp_evpn_vni_cmd);
6495 install_element(BGP_EVPN_VNI_NODE, &exit_vni_cmd);
6496 install_element(BGP_EVPN_VNI_NODE, &bgp_evpn_vni_rd_cmd);
6497 install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rd_cmd);
6498 install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rd_without_val_cmd);
6499 install_element(BGP_EVPN_VNI_NODE, &bgp_evpn_vni_rt_cmd);
6500 install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rt_cmd);
6501 install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rt_without_val_cmd);
bf48830b
MK
6502 install_element(BGP_EVPN_NODE, &bgp_evpn_vrf_rd_cmd);
6503 install_element(BGP_EVPN_NODE, &no_bgp_evpn_vrf_rd_cmd);
676f83b9 6504 install_element(BGP_NODE, &no_bgp_evpn_vrf_rd_without_val_cmd);
df399d1c
MK
6505 install_element(BGP_EVPN_NODE, &bgp_evpn_vrf_rt_cmd);
6506 install_element(BGP_EVPN_NODE, &no_bgp_evpn_vrf_rt_cmd);
24864e44 6507 install_element(BGP_EVPN_VNI_NODE, &bgp_evpn_advertise_svi_ip_vni_cmd);
1a98c087
MK
6508 install_element(BGP_EVPN_VNI_NODE,
6509 &bgp_evpn_advertise_default_gw_vni_cmd);
6510 install_element(BGP_EVPN_VNI_NODE,
6511 &no_bgp_evpn_advertise_default_gw_vni_cmd);
31310b25
MK
6512 install_element(BGP_EVPN_VNI_NODE, &bgp_evpn_advertise_vni_subnet_cmd);
6513 install_element(BGP_EVPN_VNI_NODE,
6514 &no_bgp_evpn_advertise_vni_subnet_cmd);
784d3a42 6515}