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