]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
zebra: Add ifp to zebra-side rib_add
[mirror_frr.git] / zebra / zebra_vty.c
1 /* Zebra VTY functions
2 * Copyright (C) 2002 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
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
23 #include "memory.h"
24 #include "zebra_memory.h"
25 #include "if.h"
26 #include "prefix.h"
27 #include "command.h"
28 #include "table.h"
29 #include "rib.h"
30 #include "nexthop.h"
31 #include "vrf.h"
32 #include "linklist.h"
33 #include "mpls.h"
34 #include "routemap.h"
35 #include "srcdest_table.h"
36 #include "vxlan.h"
37
38 #include "zebra/zebra_router.h"
39 #include "zebra/zserv.h"
40 #include "zebra/zebra_vrf.h"
41 #include "zebra/zebra_mpls.h"
42 #include "zebra/zebra_rnh.h"
43 #include "zebra/redistribute.h"
44 #include "zebra/zebra_routemap.h"
45 #include "lib/json.h"
46 #include "zebra/zebra_vxlan.h"
47 #ifndef VTYSH_EXTRACT_PL
48 #include "zebra/zebra_vty_clippy.c"
49 #endif
50 #include "zebra/zserv.h"
51 #include "zebra/router-id.h"
52 #include "zebra/ipforward.h"
53 #include "zebra/zebra_vxlan_private.h"
54 #include "zebra/zebra_pbr.h"
55 #include "zebra/zebra_nhg.h"
56
57 extern int allow_delete;
58
59 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
60 safi_t safi, bool use_fib, bool use_json,
61 route_tag_t tag,
62 const struct prefix *longer_prefix_p,
63 bool supernets_only, int type,
64 unsigned short ospf_instance_id);
65 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
66 int mcast, bool use_fib);
67 static void vty_show_ip_route_summary(struct vty *vty,
68 struct route_table *table);
69 static void vty_show_ip_route_summary_prefix(struct vty *vty,
70 struct route_table *table);
71
72 DEFUN (ip_multicast_mode,
73 ip_multicast_mode_cmd,
74 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
75 IP_STR
76 "Multicast options\n"
77 "RPF lookup behavior\n"
78 "Lookup in unicast RIB only\n"
79 "Lookup in multicast RIB only\n"
80 "Try multicast RIB first, fall back to unicast RIB\n"
81 "Lookup both, use entry with lower distance\n"
82 "Lookup both, use entry with longer prefix\n")
83 {
84 char *mode = argv[3]->text;
85
86 if (strmatch(mode, "urib-only"))
87 multicast_mode_ipv4_set(MCAST_URIB_ONLY);
88 else if (strmatch(mode, "mrib-only"))
89 multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
90 else if (strmatch(mode, "mrib-then-urib"))
91 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
92 else if (strmatch(mode, "lower-distance"))
93 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
94 else if (strmatch(mode, "longer-prefix"))
95 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
96 else {
97 vty_out(vty, "Invalid mode specified\n");
98 return CMD_WARNING_CONFIG_FAILED;
99 }
100
101 return CMD_SUCCESS;
102 }
103
104 DEFUN (no_ip_multicast_mode,
105 no_ip_multicast_mode_cmd,
106 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
107 NO_STR
108 IP_STR
109 "Multicast options\n"
110 "RPF lookup behavior\n"
111 "Lookup in unicast RIB only\n"
112 "Lookup in multicast RIB only\n"
113 "Try multicast RIB first, fall back to unicast RIB\n"
114 "Lookup both, use entry with lower distance\n"
115 "Lookup both, use entry with longer prefix\n")
116 {
117 multicast_mode_ipv4_set(MCAST_NO_CONFIG);
118 return CMD_SUCCESS;
119 }
120
121
122 DEFUN (show_ip_rpf,
123 show_ip_rpf_cmd,
124 "show ip rpf [json]",
125 SHOW_STR
126 IP_STR
127 "Display RPF information for multicast source\n"
128 JSON_STR)
129 {
130 bool uj = use_json(argc, argv);
131 return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
132 false, uj, 0, NULL, false, 0, 0);
133 }
134
135 DEFUN (show_ip_rpf_addr,
136 show_ip_rpf_addr_cmd,
137 "show ip rpf A.B.C.D",
138 SHOW_STR
139 IP_STR
140 "Display RPF information for multicast source\n"
141 "IP multicast source address (e.g. 10.0.0.0)\n")
142 {
143 int idx_ipv4 = 3;
144 struct in_addr addr;
145 struct route_node *rn;
146 struct route_entry *re;
147 int ret;
148
149 ret = inet_aton(argv[idx_ipv4]->arg, &addr);
150 if (ret == 0) {
151 vty_out(vty, "%% Malformed address\n");
152 return CMD_WARNING;
153 }
154
155 re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
156
157 if (re)
158 vty_show_ip_route_detail(vty, rn, 1, false);
159 else
160 vty_out(vty, "%% No match for RPF lookup\n");
161
162 return CMD_SUCCESS;
163 }
164
165 static char re_status_output_char(struct route_entry *re, struct nexthop *nhop)
166 {
167 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
168 if (!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_DUPLICATE) &&
169 !CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
170 return '*';
171 else
172 return ' ';
173 }
174
175 if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED)) {
176 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
177 return 'q';
178
179 return 'r';
180 }
181
182 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
183 return 'q';
184
185 return ' ';
186 }
187
188 /* New RIB. Detailed information for IPv4 route. */
189 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
190 int mcast, bool use_fib)
191 {
192 struct route_entry *re;
193 struct nexthop *nexthop;
194 char buf[SRCDEST2STR_BUFFER];
195 struct zebra_vrf *zvrf;
196 rib_dest_t *dest;
197
198 dest = rib_dest_from_rnode(rn);
199
200 RNODE_FOREACH_RE (rn, re) {
201 /*
202 * If re not selected for forwarding, skip re
203 * for "show ip/ipv6 fib <prefix>"
204 */
205 if (use_fib && re != dest->selected_fib)
206 continue;
207
208 const char *mcast_info = "";
209 if (mcast) {
210 rib_table_info_t *info = srcdest_rnode_table_info(rn);
211 mcast_info = (info->safi == SAFI_MULTICAST)
212 ? " using Multicast RIB"
213 : " using Unicast RIB";
214 }
215
216 vty_out(vty, "Routing entry for %s%s\n",
217 srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
218 vty_out(vty, " Known via \"%s", zebra_route_string(re->type));
219 if (re->instance)
220 vty_out(vty, "[%d]", re->instance);
221 vty_out(vty, "\"");
222 vty_out(vty, ", distance %u, metric %u", re->distance,
223 re->metric);
224 if (re->tag) {
225 vty_out(vty, ", tag %u", re->tag);
226 #if defined(SUPPORT_REALMS)
227 if (re->tag > 0 && re->tag <= 255)
228 vty_out(vty, "(realm)");
229 #endif
230 }
231 if (re->mtu)
232 vty_out(vty, ", mtu %u", re->mtu);
233 if (re->vrf_id != VRF_DEFAULT) {
234 zvrf = vrf_info_lookup(re->vrf_id);
235 vty_out(vty, ", vrf %s", zvrf_name(zvrf));
236 }
237 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
238 vty_out(vty, ", best");
239 vty_out(vty, "\n");
240
241 time_t uptime;
242 struct tm *tm;
243
244 uptime = monotime(NULL);
245 uptime -= re->uptime;
246 tm = gmtime(&uptime);
247
248 vty_out(vty, " Last update ");
249
250 if (uptime < ONE_DAY_SECOND)
251 vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
252 tm->tm_sec);
253 else if (uptime < ONE_WEEK_SECOND)
254 vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
255 tm->tm_min);
256 else
257 vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
258 tm->tm_yday - ((tm->tm_yday / 7) * 7),
259 tm->tm_hour);
260 vty_out(vty, " ago\n");
261
262 for (ALL_NEXTHOPS_PTR(re->ng, nexthop)) {
263 char addrstr[32];
264
265 vty_out(vty, " %c%s",
266 re_status_output_char(re, nexthop),
267 nexthop->rparent ? " " : "");
268
269 switch (nexthop->type) {
270 case NEXTHOP_TYPE_IPV4:
271 case NEXTHOP_TYPE_IPV4_IFINDEX:
272 vty_out(vty, " %s",
273 inet_ntoa(nexthop->gate.ipv4));
274 if (nexthop->ifindex)
275 vty_out(vty, ", via %s",
276 ifindex2ifname(
277 nexthop->ifindex,
278 nexthop->vrf_id));
279 break;
280 case NEXTHOP_TYPE_IPV6:
281 case NEXTHOP_TYPE_IPV6_IFINDEX:
282 vty_out(vty, " %s",
283 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
284 buf, sizeof buf));
285 if (nexthop->ifindex)
286 vty_out(vty, ", via %s",
287 ifindex2ifname(
288 nexthop->ifindex,
289 nexthop->vrf_id));
290 break;
291 case NEXTHOP_TYPE_IFINDEX:
292 vty_out(vty, " directly connected, %s",
293 ifindex2ifname(nexthop->ifindex,
294 nexthop->vrf_id));
295 break;
296 case NEXTHOP_TYPE_BLACKHOLE:
297 vty_out(vty, " unreachable");
298 switch (nexthop->bh_type) {
299 case BLACKHOLE_REJECT:
300 vty_out(vty, " (ICMP unreachable)");
301 break;
302 case BLACKHOLE_ADMINPROHIB:
303 vty_out(vty,
304 " (ICMP admin-prohibited)");
305 break;
306 case BLACKHOLE_NULL:
307 vty_out(vty, " (blackhole)");
308 break;
309 case BLACKHOLE_UNSPEC:
310 break;
311 }
312 break;
313 default:
314 break;
315 }
316
317 if ((re->vrf_id != nexthop->vrf_id)
318 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
319 struct vrf *vrf =
320 vrf_lookup_by_id(nexthop->vrf_id);
321
322 if (vrf)
323 vty_out(vty, "(vrf %s)", vrf->name);
324 else
325 vty_out(vty, "(vrf UNKNOWN)");
326 }
327
328 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
329 vty_out(vty, " (duplicate nexthop removed)");
330
331 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
332 vty_out(vty, " inactive");
333
334 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
335 vty_out(vty, " onlink");
336
337 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
338 vty_out(vty, " (recursive)");
339
340 switch (nexthop->type) {
341 case NEXTHOP_TYPE_IPV4:
342 case NEXTHOP_TYPE_IPV4_IFINDEX:
343 if (nexthop->src.ipv4.s_addr) {
344 if (inet_ntop(AF_INET,
345 &nexthop->src.ipv4,
346 addrstr, sizeof addrstr))
347 vty_out(vty, ", src %s",
348 addrstr);
349 }
350 break;
351 case NEXTHOP_TYPE_IPV6:
352 case NEXTHOP_TYPE_IPV6_IFINDEX:
353 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
354 &in6addr_any)) {
355 if (inet_ntop(AF_INET6,
356 &nexthop->src.ipv6,
357 addrstr, sizeof addrstr))
358 vty_out(vty, ", src %s",
359 addrstr);
360 }
361 break;
362 default:
363 break;
364 }
365
366 if (re->nexthop_mtu)
367 vty_out(vty, ", mtu %u", re->nexthop_mtu);
368
369 /* Label information */
370 if (nexthop->nh_label
371 && nexthop->nh_label->num_labels) {
372 vty_out(vty, ", label %s",
373 mpls_label2str(
374 nexthop->nh_label->num_labels,
375 nexthop->nh_label->label, buf,
376 sizeof buf, 1));
377 }
378
379 vty_out(vty, "\n");
380 }
381 vty_out(vty, "\n");
382 }
383 }
384
385 static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
386 struct route_entry *re, json_object *json,
387 bool is_fib)
388 {
389 struct nexthop *nexthop;
390 int len = 0;
391 char buf[SRCDEST2STR_BUFFER];
392 json_object *json_nexthops = NULL;
393 json_object *json_nexthop = NULL;
394 json_object *json_route = NULL;
395 json_object *json_labels = NULL;
396 time_t uptime;
397 struct tm *tm;
398 struct vrf *vrf = NULL;
399 rib_dest_t *dest = rib_dest_from_rnode(rn);
400 struct nexthop_group *nhg;
401
402 uptime = monotime(NULL);
403 uptime -= re->uptime;
404 tm = gmtime(&uptime);
405
406 /* If showing fib information, use the fib view of the
407 * nexthops.
408 */
409 if (is_fib)
410 nhg = rib_active_nhg(re);
411 else
412 nhg = re->ng;
413
414 if (json) {
415 json_route = json_object_new_object();
416 json_nexthops = json_object_new_array();
417
418 json_object_string_add(json_route, "prefix",
419 srcdest_rnode2str(rn, buf, sizeof buf));
420 json_object_string_add(json_route, "protocol",
421 zebra_route_string(re->type));
422
423 if (re->instance)
424 json_object_int_add(json_route, "instance",
425 re->instance);
426
427 if (re->vrf_id) {
428 json_object_int_add(json_route, "vrfId", re->vrf_id);
429 vrf = vrf_lookup_by_id(re->vrf_id);
430 json_object_string_add(json_route, "vrfName",
431 vrf->name);
432
433 }
434 if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
435 json_object_boolean_true_add(json_route, "selected");
436
437 if (dest->selected_fib == re)
438 json_object_boolean_true_add(json_route,
439 "destSelected");
440
441 json_object_int_add(json_route, "distance",
442 re->distance);
443 json_object_int_add(json_route, "metric", re->metric);
444
445 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
446 json_object_boolean_true_add(json_route, "installed");
447
448 if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
449 json_object_boolean_true_add(json_route, "failed");
450
451 if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
452 json_object_boolean_true_add(json_route, "queued");
453
454 if (re->tag)
455 json_object_int_add(json_route, "tag", re->tag);
456
457 if (re->table)
458 json_object_int_add(json_route, "table", re->table);
459
460 json_object_int_add(json_route, "internalStatus",
461 re->status);
462 json_object_int_add(json_route, "internalFlags",
463 re->flags);
464 json_object_int_add(json_route, "internalNextHopNum",
465 re->nexthop_num);
466 json_object_int_add(json_route, "internalNextHopActiveNum",
467 re->nexthop_active_num);
468 if (uptime < ONE_DAY_SECOND)
469 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
470 tm->tm_sec);
471 else if (uptime < ONE_WEEK_SECOND)
472 sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
473 tm->tm_min);
474 else
475 sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
476 tm->tm_yday - ((tm->tm_yday / 7) * 7),
477 tm->tm_hour);
478
479 json_object_string_add(json_route, "uptime", buf);
480
481 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
482 json_nexthop = json_object_new_object();
483
484 json_object_int_add(json_nexthop, "flags",
485 nexthop->flags);
486
487 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
488 json_object_boolean_true_add(json_nexthop,
489 "duplicate");
490
491 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
492 json_object_boolean_true_add(json_nexthop,
493 "fib");
494
495 switch (nexthop->type) {
496 case NEXTHOP_TYPE_IPV4:
497 case NEXTHOP_TYPE_IPV4_IFINDEX:
498 json_object_string_add(
499 json_nexthop, "ip",
500 inet_ntoa(nexthop->gate.ipv4));
501 json_object_string_add(json_nexthop, "afi",
502 "ipv4");
503
504 if (nexthop->ifindex) {
505 json_object_int_add(json_nexthop,
506 "interfaceIndex",
507 nexthop->ifindex);
508 json_object_string_add(
509 json_nexthop, "interfaceName",
510 ifindex2ifname(
511 nexthop->ifindex,
512 nexthop->vrf_id));
513 }
514 break;
515 case NEXTHOP_TYPE_IPV6:
516 case NEXTHOP_TYPE_IPV6_IFINDEX:
517 json_object_string_add(
518 json_nexthop, "ip",
519 inet_ntop(AF_INET6, &nexthop->gate.ipv6,
520 buf, sizeof buf));
521 json_object_string_add(json_nexthop, "afi",
522 "ipv6");
523
524 if (nexthop->ifindex) {
525 json_object_int_add(json_nexthop,
526 "interfaceIndex",
527 nexthop->ifindex);
528 json_object_string_add(
529 json_nexthop, "interfaceName",
530 ifindex2ifname(
531 nexthop->ifindex,
532 nexthop->vrf_id));
533 }
534 break;
535
536 case NEXTHOP_TYPE_IFINDEX:
537 json_object_boolean_true_add(
538 json_nexthop, "directlyConnected");
539 json_object_int_add(json_nexthop,
540 "interfaceIndex",
541 nexthop->ifindex);
542 json_object_string_add(
543 json_nexthop, "interfaceName",
544 ifindex2ifname(nexthop->ifindex,
545 nexthop->vrf_id));
546 break;
547 case NEXTHOP_TYPE_BLACKHOLE:
548 json_object_boolean_true_add(json_nexthop,
549 "unreachable");
550 switch (nexthop->bh_type) {
551 case BLACKHOLE_REJECT:
552 json_object_boolean_true_add(
553 json_nexthop, "reject");
554 break;
555 case BLACKHOLE_ADMINPROHIB:
556 json_object_boolean_true_add(
557 json_nexthop,
558 "admin-prohibited");
559 break;
560 case BLACKHOLE_NULL:
561 json_object_boolean_true_add(
562 json_nexthop, "blackhole");
563 break;
564 case BLACKHOLE_UNSPEC:
565 break;
566 }
567 break;
568 default:
569 break;
570 }
571
572 if ((nexthop->vrf_id != re->vrf_id)
573 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
574 vrf = vrf_lookup_by_id(nexthop->vrf_id);
575 json_object_string_add(json_nexthop, "vrf",
576 vrf->name);
577 }
578 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
579 json_object_boolean_true_add(json_nexthop,
580 "duplicate");
581
582 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
583 json_object_boolean_true_add(json_nexthop,
584 "active");
585
586 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
587 json_object_boolean_true_add(json_nexthop,
588 "onLink");
589
590 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
591 json_object_boolean_true_add(json_nexthop,
592 "recursive");
593
594 switch (nexthop->type) {
595 case NEXTHOP_TYPE_IPV4:
596 case NEXTHOP_TYPE_IPV4_IFINDEX:
597 if (nexthop->src.ipv4.s_addr) {
598 if (inet_ntop(AF_INET,
599 &nexthop->src.ipv4, buf,
600 sizeof buf))
601 json_object_string_add(
602 json_nexthop, "source",
603 buf);
604 }
605 break;
606 case NEXTHOP_TYPE_IPV6:
607 case NEXTHOP_TYPE_IPV6_IFINDEX:
608 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6,
609 &in6addr_any)) {
610 if (inet_ntop(AF_INET6,
611 &nexthop->src.ipv6, buf,
612 sizeof buf))
613 json_object_string_add(
614 json_nexthop, "source",
615 buf);
616 }
617 break;
618 default:
619 break;
620 }
621
622 if (nexthop->nh_label
623 && nexthop->nh_label->num_labels) {
624 json_labels = json_object_new_array();
625
626 for (int label_index = 0;
627 label_index
628 < nexthop->nh_label->num_labels;
629 label_index++)
630 json_object_array_add(
631 json_labels,
632 json_object_new_int(
633 nexthop->nh_label->label
634 [label_index]));
635
636 json_object_object_add(json_nexthop, "labels",
637 json_labels);
638 }
639
640 json_object_array_add(json_nexthops, json_nexthop);
641 }
642
643 json_object_object_add(json_route, "nexthops", json_nexthops);
644 json_object_array_add(json, json_route);
645 return;
646 }
647
648 /* Nexthop information. */
649 for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
650 if (nexthop == nhg->nexthop) {
651 /* Prefix information. */
652 len = vty_out(vty, "%c", zebra_route_char(re->type));
653 if (re->instance)
654 len += vty_out(vty, "[%d]", re->instance);
655 len += vty_out(
656 vty, "%c%c %s",
657 CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
658 ? '>'
659 : ' ',
660 re_status_output_char(re, nexthop),
661 srcdest_rnode2str(rn, buf, sizeof buf));
662
663 /* Distance and metric display. */
664 if (((re->type == ZEBRA_ROUTE_CONNECT) &&
665 (re->distance || re->metric)) ||
666 (re->type != ZEBRA_ROUTE_CONNECT))
667 len += vty_out(vty, " [%u/%u]", re->distance,
668 re->metric);
669 } else {
670 vty_out(vty, " %c%*c",
671 re_status_output_char(re, nexthop),
672 len - 3 + (2 * nexthop_level(nexthop)), ' ');
673 }
674
675 switch (nexthop->type) {
676 case NEXTHOP_TYPE_IPV4:
677 case NEXTHOP_TYPE_IPV4_IFINDEX:
678 vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
679 if (nexthop->ifindex)
680 vty_out(vty, ", %s",
681 ifindex2ifname(nexthop->ifindex,
682 nexthop->vrf_id));
683 break;
684 case NEXTHOP_TYPE_IPV6:
685 case NEXTHOP_TYPE_IPV6_IFINDEX:
686 vty_out(vty, " via %s",
687 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
688 sizeof buf));
689 if (nexthop->ifindex)
690 vty_out(vty, ", %s",
691 ifindex2ifname(nexthop->ifindex,
692 nexthop->vrf_id));
693 break;
694
695 case NEXTHOP_TYPE_IFINDEX:
696 vty_out(vty, " is directly connected, %s",
697 ifindex2ifname(nexthop->ifindex,
698 nexthop->vrf_id));
699 break;
700 case NEXTHOP_TYPE_BLACKHOLE:
701 vty_out(vty, " unreachable");
702 switch (nexthop->bh_type) {
703 case BLACKHOLE_REJECT:
704 vty_out(vty, " (ICMP unreachable)");
705 break;
706 case BLACKHOLE_ADMINPROHIB:
707 vty_out(vty, " (ICMP admin-prohibited)");
708 break;
709 case BLACKHOLE_NULL:
710 vty_out(vty, " (blackhole)");
711 break;
712 case BLACKHOLE_UNSPEC:
713 break;
714 }
715 break;
716 default:
717 break;
718 }
719
720 if ((nexthop->vrf_id != re->vrf_id)
721 && (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
722 struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
723
724 if (vrf)
725 vty_out(vty, "(vrf %s)", vrf->name);
726 else
727 vty_out(vty, "(vrf UNKNOWN)");
728 }
729
730 if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
731 vty_out(vty, " inactive");
732
733 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
734 vty_out(vty, " onlink");
735
736 if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
737 vty_out(vty, " (recursive)");
738
739 switch (nexthop->type) {
740 case NEXTHOP_TYPE_IPV4:
741 case NEXTHOP_TYPE_IPV4_IFINDEX:
742 if (nexthop->src.ipv4.s_addr) {
743 if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf,
744 sizeof buf))
745 vty_out(vty, ", src %s", buf);
746 }
747 break;
748 case NEXTHOP_TYPE_IPV6:
749 case NEXTHOP_TYPE_IPV6_IFINDEX:
750 if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) {
751 if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf,
752 sizeof buf))
753 vty_out(vty, ", src %s", buf);
754 }
755 break;
756 default:
757 break;
758 }
759
760 /* Label information */
761 if (nexthop->nh_label && nexthop->nh_label->num_labels) {
762 vty_out(vty, ", label %s",
763 mpls_label2str(nexthop->nh_label->num_labels,
764 nexthop->nh_label->label, buf,
765 sizeof buf, 1));
766 }
767
768 if (uptime < ONE_DAY_SECOND)
769 vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
770 tm->tm_min, tm->tm_sec);
771 else if (uptime < ONE_WEEK_SECOND)
772 vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
773 tm->tm_hour, tm->tm_min);
774 else
775 vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
776 tm->tm_yday - ((tm->tm_yday / 7) * 7),
777 tm->tm_hour);
778 vty_out(vty, "\n");
779 }
780 }
781
782 static void vty_show_ip_route_detail_json(struct vty *vty,
783 struct route_node *rn, bool use_fib)
784 {
785 json_object *json = NULL;
786 json_object *json_prefix = NULL;
787 struct route_entry *re;
788 char buf[BUFSIZ];
789 rib_dest_t *dest;
790
791 dest = rib_dest_from_rnode(rn);
792
793 json = json_object_new_object();
794 json_prefix = json_object_new_array();
795
796 RNODE_FOREACH_RE (rn, re) {
797 /*
798 * If re not selected for forwarding, skip re
799 * for "show ip/ipv6 fib <prefix> json"
800 */
801 if (use_fib && re != dest->selected_fib)
802 continue;
803 vty_show_ip_route(vty, rn, re, json_prefix, use_fib);
804 }
805
806 prefix2str(&rn->p, buf, sizeof(buf));
807 json_object_object_add(json, buf, json_prefix);
808 vty_out(vty, "%s\n", json_object_to_json_string_ext(
809 json, JSON_C_TO_STRING_PRETTY));
810 json_object_free(json);
811 }
812
813 static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
814 struct route_table *table, afi_t afi,
815 bool use_fib, route_tag_t tag,
816 const struct prefix *longer_prefix_p,
817 bool supernets_only, int type,
818 unsigned short ospf_instance_id, bool use_json,
819 uint32_t tableid)
820 {
821 struct route_node *rn;
822 struct route_entry *re;
823 int first = 1;
824 rib_dest_t *dest;
825 json_object *json = NULL;
826 json_object *json_prefix = NULL;
827 uint32_t addr;
828 char buf[BUFSIZ];
829
830 if (use_json)
831 json = json_object_new_object();
832
833 /* Show all routes. */
834 for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
835 dest = rib_dest_from_rnode(rn);
836
837 RNODE_FOREACH_RE (rn, re) {
838 if (use_fib && re != dest->selected_fib)
839 continue;
840
841 if (tag && re->tag != tag)
842 continue;
843
844 if (longer_prefix_p
845 && !prefix_match(longer_prefix_p, &rn->p))
846 continue;
847
848 /* This can only be true when the afi is IPv4 */
849 if (supernets_only) {
850 addr = ntohl(rn->p.u.prefix4.s_addr);
851
852 if (IN_CLASSC(addr) && rn->p.prefixlen >= 24)
853 continue;
854
855 if (IN_CLASSB(addr) && rn->p.prefixlen >= 16)
856 continue;
857
858 if (IN_CLASSA(addr) && rn->p.prefixlen >= 8)
859 continue;
860 }
861
862 if (type && re->type != type)
863 continue;
864
865 if (ospf_instance_id
866 && (re->type != ZEBRA_ROUTE_OSPF
867 || re->instance != ospf_instance_id))
868 continue;
869
870 if (use_json) {
871 if (!json_prefix)
872 json_prefix = json_object_new_array();
873 } else {
874 if (first) {
875 if (afi == AFI_IP)
876 vty_out(vty,
877 SHOW_ROUTE_V4_HEADER);
878 else
879 vty_out(vty,
880 SHOW_ROUTE_V6_HEADER);
881
882 if (tableid && tableid != RT_TABLE_MAIN)
883 vty_out(vty, "\nVRF %s table %u:\n",
884 zvrf_name(zvrf), tableid);
885 else if (zvrf_id(zvrf) != VRF_DEFAULT)
886 vty_out(vty, "\nVRF %s:\n",
887 zvrf_name(zvrf));
888 first = 0;
889 }
890 }
891
892 vty_show_ip_route(vty, rn, re, json_prefix, use_fib);
893 }
894
895 if (json_prefix) {
896 prefix2str(&rn->p, buf, sizeof(buf));
897 json_object_object_add(json, buf, json_prefix);
898 json_prefix = NULL;
899 }
900 }
901
902 if (use_json) {
903 vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
904 JSON_C_TO_STRING_PRETTY));
905 json_object_free(json);
906 }
907 }
908
909 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
910 safi_t safi, bool use_fib, bool use_json,
911 route_tag_t tag,
912 const struct prefix *longer_prefix_p,
913 bool supernets_only, int type,
914 unsigned short ospf_instance_id)
915 {
916 struct route_table *table;
917 struct zebra_vrf *zvrf = NULL;
918
919 if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
920 if (use_json)
921 vty_out(vty, "{}\n");
922 else
923 vty_out(vty, "vrf %s not defined\n", vrf_name);
924 return CMD_SUCCESS;
925 }
926
927 if (zvrf_id(zvrf) == VRF_UNKNOWN) {
928 if (use_json)
929 vty_out(vty, "{}\n");
930 else
931 vty_out(vty, "vrf %s inactive\n", vrf_name);
932 return CMD_SUCCESS;
933 }
934
935 table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
936 if (!table) {
937 if (use_json)
938 vty_out(vty, "{}\n");
939 return CMD_SUCCESS;
940 }
941
942 do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
943 longer_prefix_p, supernets_only, type,
944 ospf_instance_id, use_json, 0);
945
946 return CMD_SUCCESS;
947 }
948
949 DEFPY (show_route_table,
950 show_route_table_cmd,
951 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
952 SHOW_STR
953 IP_STR
954 IP6_STR
955 "IP routing table\n"
956 "Table to display\n"
957 "The table number to display, if available\n"
958 JSON_STR)
959 {
960 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
961 struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
962 struct route_table *t;
963
964 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
965 if (t)
966 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
967 0, 0, !!json, table);
968
969 return CMD_SUCCESS;
970 }
971
972 DEFPY (show_route_table_vrf,
973 show_route_table_vrf_cmd,
974 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
975 SHOW_STR
976 IP_STR
977 IP6_STR
978 "IP routing table\n"
979 "Table to display\n"
980 "The table number to display, if available\n"
981 VRF_CMD_HELP_STR
982 JSON_STR)
983 {
984 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
985 struct zebra_vrf *zvrf;
986 struct route_table *t;
987 vrf_id_t vrf_id = VRF_DEFAULT;
988
989 if (vrf_name)
990 VRF_GET_ID(vrf_id, vrf_name, !!json);
991 zvrf = zebra_vrf_lookup_by_id(vrf_id);
992
993 t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
994 if (t)
995 do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
996 0, 0, !!json, table);
997
998 return CMD_SUCCESS;
999 }
1000
1001 DEFPY (show_route_all_table_vrf,
1002 show_route_all_table_vrf_cmd,
1003 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1004 SHOW_STR
1005 IP_STR
1006 IP6_STR
1007 "IP routing table\n"
1008 "Display all tables\n"
1009 VRF_FULL_CMD_HELP_STR
1010 JSON_STR)
1011 {
1012 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1013 struct zebra_vrf *zvrf = NULL;
1014 vrf_id_t vrf_id = VRF_UNKNOWN;
1015 struct zebra_router_table *zrt;
1016
1017 if (vrf_name) {
1018 VRF_GET_ID(vrf_id, vrf_name, !!json);
1019 zvrf = zebra_vrf_lookup_by_id(vrf_id);
1020 }
1021
1022 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
1023 rib_table_info_t *info = route_table_get_info(zrt->table);
1024
1025 if (zvrf && zvrf != info->zvrf)
1026 continue;
1027 if (zrt->afi != afi || zrt->safi != SAFI_UNICAST)
1028 continue;
1029
1030 do_show_route_helper(vty, info->zvrf, zrt->table, afi, false, 0,
1031 false, false, 0, 0, !!json, zrt->tableid);
1032 }
1033 return CMD_SUCCESS;
1034 }
1035
1036 DEFPY (show_ip_nht,
1037 show_ip_nht_cmd,
1038 "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name [<A.B.C.D|X:X::X:X>$addr]|vrf all$vrf_all]",
1039 SHOW_STR
1040 IP_STR
1041 IP6_STR
1042 "IP nexthop tracking table\n"
1043 "IP import check tracking table\n"
1044 "IPv4 Address\n"
1045 "IPv6 Address\n"
1046 VRF_CMD_HELP_STR
1047 "IPv4 Address\n"
1048 "IPv6 Address\n"
1049 VRF_ALL_CMD_HELP_STR)
1050 {
1051 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1052 vrf_id_t vrf_id = VRF_DEFAULT;
1053 struct prefix prefix, *p = NULL;
1054 rnh_type_t rtype;
1055
1056 if (strcmp(type, "nht") == 0)
1057 rtype = RNH_NEXTHOP_TYPE;
1058 else
1059 rtype = RNH_IMPORT_CHECK_TYPE;
1060
1061 if (vrf_all) {
1062 struct vrf *vrf;
1063 struct zebra_vrf *zvrf;
1064
1065 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1066 if ((zvrf = vrf->info) != NULL) {
1067 vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
1068 zebra_print_rnh_table(zvrf_id(zvrf), afi, vty,
1069 rtype, NULL);
1070 }
1071 return CMD_SUCCESS;
1072 }
1073 if (vrf_name)
1074 VRF_GET_ID(vrf_id, vrf_name, false);
1075
1076 memset(&prefix, 0, sizeof(prefix));
1077 if (addr)
1078 p = sockunion2hostprefix(addr, &prefix);
1079
1080 zebra_print_rnh_table(vrf_id, afi, vty, rtype, p);
1081 return CMD_SUCCESS;
1082 }
1083
1084 DEFUN (ip_nht_default_route,
1085 ip_nht_default_route_cmd,
1086 "ip nht resolve-via-default",
1087 IP_STR
1088 "Filter Next Hop tracking route resolution\n"
1089 "Resolve via default route\n")
1090 {
1091 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1092
1093 if (!zvrf)
1094 return CMD_WARNING;
1095
1096 if (zvrf->zebra_rnh_ip_default_route)
1097 return CMD_SUCCESS;
1098
1099 zvrf->zebra_rnh_ip_default_route = 1;
1100
1101 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
1102 return CMD_SUCCESS;
1103 }
1104
1105 static void show_nexthop_group_cmd_helper(struct vty *vty,
1106 struct zebra_vrf *zvrf)
1107 {
1108 struct list *list = hash_to_list(zrouter.nhgs);
1109 struct nhg_hash_entry *nhe;
1110 struct listnode *node;
1111
1112 for (ALL_LIST_ELEMENTS_RO(list, node, nhe)) {
1113 struct nexthop *nhop;
1114
1115 if (nhe->vrf_id != zvrf->vrf->vrf_id)
1116 continue;
1117
1118 vty_out(vty, "Group: %u ID: %u\n", nhe->dplane_ref, nhe->id);
1119 vty_out(vty, "\tRefCnt: %d\n", nhe->refcnt);
1120 vty_out(vty, "\tValid: %d, Installed %d\n",
1121 nhe->flags & NEXTHOP_GROUP_VALID,
1122 nhe->flags & NEXTHOP_GROUP_INSTALLED);
1123 if (nhe->ifp)
1124 vty_out(vty, "\tInterface Index: %d\n",
1125 nhe->ifp->ifindex);
1126 for (ALL_NEXTHOPS(nhe->nhg, nhop)) {
1127 vty_out(vty, "\t");
1128 nexthop_group_write_nexthop(vty, nhop);
1129 }
1130 }
1131
1132 list_delete(&list);
1133 }
1134
1135 DEFPY (show_nexthop_group,
1136 show_nexthop_group_cmd,
1137 "show nexthop-group [vrf <NAME$vrf_name|all$vrf_all>]",
1138 SHOW_STR
1139 "Show Nexthop Groups\n"
1140 VRF_FULL_CMD_HELP_STR)
1141 {
1142 struct zebra_vrf *zvrf;
1143
1144 if (vrf_all) {
1145 struct vrf *vrf;
1146
1147 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1148 struct zebra_vrf *zvrf;
1149
1150 zvrf = vrf->info;
1151 if (!zvrf)
1152 continue;
1153
1154 vty_out(vty, "VRF: %s\n", vrf->name);
1155 show_nexthop_group_cmd_helper(vty, zvrf);
1156 }
1157
1158 return CMD_SUCCESS;
1159 }
1160
1161 if (vrf_name)
1162 zvrf = zebra_vrf_lookup_by_name(vrf_name);
1163 else
1164 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
1165
1166 if (!zvrf) {
1167 vty_out(vty, "VRF %s specified does not exist", vrf_name);
1168 return CMD_SUCCESS;
1169 }
1170
1171 show_nexthop_group_cmd_helper(vty, zvrf);
1172
1173 return CMD_SUCCESS;
1174 }
1175
1176 DEFUN (no_ip_nht_default_route,
1177 no_ip_nht_default_route_cmd,
1178 "no ip nht resolve-via-default",
1179 NO_STR
1180 IP_STR
1181 "Filter Next Hop tracking route resolution\n"
1182 "Resolve via default route\n")
1183 {
1184 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1185
1186 if (!zvrf)
1187 return CMD_WARNING;
1188
1189 if (!zvrf->zebra_rnh_ip_default_route)
1190 return CMD_SUCCESS;
1191
1192 zvrf->zebra_rnh_ip_default_route = 0;
1193 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
1194 return CMD_SUCCESS;
1195 }
1196
1197 DEFUN (ipv6_nht_default_route,
1198 ipv6_nht_default_route_cmd,
1199 "ipv6 nht resolve-via-default",
1200 IP6_STR
1201 "Filter Next Hop tracking route resolution\n"
1202 "Resolve via default route\n")
1203 {
1204 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1205
1206 if (!zvrf)
1207 return CMD_WARNING;
1208
1209 if (zvrf->zebra_rnh_ipv6_default_route)
1210 return CMD_SUCCESS;
1211
1212 zvrf->zebra_rnh_ipv6_default_route = 1;
1213 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
1214 return CMD_SUCCESS;
1215 }
1216
1217 DEFUN (no_ipv6_nht_default_route,
1218 no_ipv6_nht_default_route_cmd,
1219 "no ipv6 nht resolve-via-default",
1220 NO_STR
1221 IP6_STR
1222 "Filter Next Hop tracking route resolution\n"
1223 "Resolve via default route\n")
1224 {
1225
1226 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1227
1228 if (!zvrf)
1229 return CMD_WARNING;
1230
1231 if (!zvrf->zebra_rnh_ipv6_default_route)
1232 return CMD_SUCCESS;
1233
1234 zvrf->zebra_rnh_ipv6_default_route = 0;
1235 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
1236 return CMD_SUCCESS;
1237 }
1238
1239 DEFPY (show_route,
1240 show_route_cmd,
1241 "show\
1242 <\
1243 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1244 [{\
1245 tag (1-4294967295)\
1246 |A.B.C.D/M$prefix longer-prefixes\
1247 |supernets-only$supernets_only\
1248 }]\
1249 [<\
1250 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
1251 |ospf$type_str (1-65535)$ospf_instance_id\
1252 >]\
1253 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1254 [{\
1255 tag (1-4294967295)\
1256 |X:X::X:X/M$prefix longer-prefixes\
1257 }]\
1258 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
1259 >\
1260 [json$json]",
1261 SHOW_STR
1262 IP_STR
1263 "IP forwarding table\n"
1264 "IP routing table\n"
1265 VRF_FULL_CMD_HELP_STR
1266 "Show only routes with tag\n"
1267 "Tag value\n"
1268 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1269 "Show route matching the specified Network/Mask pair only\n"
1270 "Show supernet entries only\n"
1271 FRR_IP_REDIST_HELP_STR_ZEBRA
1272 "Open Shortest Path First (OSPFv2)\n"
1273 "Instance ID\n"
1274 IPV6_STR
1275 "IP forwarding table\n"
1276 "IP routing table\n"
1277 VRF_FULL_CMD_HELP_STR
1278 "Show only routes with tag\n"
1279 "Tag value\n"
1280 "IPv6 prefix\n"
1281 "Show route matching the specified Network/Mask pair only\n"
1282 FRR_IP6_REDIST_HELP_STR_ZEBRA
1283 JSON_STR)
1284 {
1285 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1286 struct vrf *vrf;
1287 int type = 0;
1288
1289 if (type_str) {
1290 type = proto_redistnum(afi, type_str);
1291 if (type < 0) {
1292 vty_out(vty, "Unknown route type\n");
1293 return CMD_WARNING;
1294 }
1295 }
1296
1297 if (vrf_all) {
1298 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1299 struct zebra_vrf *zvrf;
1300 struct route_table *table;
1301
1302 if ((zvrf = vrf->info) == NULL
1303 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1304 continue;
1305
1306 do_show_ip_route(
1307 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1308 !!json, tag, prefix_str ? prefix : NULL,
1309 !!supernets_only, type, ospf_instance_id);
1310 }
1311 } else {
1312 vrf_id_t vrf_id = VRF_DEFAULT;
1313
1314 if (vrf_name)
1315 VRF_GET_ID(vrf_id, vrf_name, !!json);
1316 vrf = vrf_lookup_by_id(vrf_id);
1317 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1318 !!json, tag, prefix_str ? prefix : NULL,
1319 !!supernets_only, type, ospf_instance_id);
1320 }
1321
1322 return CMD_SUCCESS;
1323 }
1324
1325 DEFPY (show_route_detail,
1326 show_route_detail_cmd,
1327 "show\
1328 <\
1329 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1330 <\
1331 A.B.C.D$address\
1332 |A.B.C.D/M$prefix\
1333 >\
1334 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1335 <\
1336 X:X::X:X$address\
1337 |X:X::X:X/M$prefix\
1338 >\
1339 >\
1340 [json$json]",
1341 SHOW_STR
1342 IP_STR
1343 "IPv6 forwarding table\n"
1344 "IP routing table\n"
1345 VRF_FULL_CMD_HELP_STR
1346 "Network in the IP routing table to display\n"
1347 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1348 IP6_STR
1349 "IPv6 forwarding table\n"
1350 "IPv6 routing table\n"
1351 VRF_FULL_CMD_HELP_STR
1352 "IPv6 Address\n"
1353 "IPv6 prefix\n"
1354 JSON_STR)
1355 {
1356 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1357 struct route_table *table;
1358 struct prefix p;
1359 struct route_node *rn;
1360 bool use_fib = !!fib;
1361 rib_dest_t *dest;
1362 bool network_found = false;
1363
1364 if (address_str)
1365 prefix_str = address_str;
1366 if (str2prefix(prefix_str, &p) < 0) {
1367 vty_out(vty, "%% Malformed address\n");
1368 return CMD_WARNING;
1369 }
1370
1371 if (vrf_all) {
1372 struct vrf *vrf;
1373 struct zebra_vrf *zvrf;
1374
1375 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1376 if ((zvrf = vrf->info) == NULL
1377 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1378 continue;
1379
1380 rn = route_node_match(table, &p);
1381 if (!rn)
1382 continue;
1383 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1384 route_unlock_node(rn);
1385 continue;
1386 }
1387
1388 dest = rib_dest_from_rnode(rn);
1389 if (use_fib && !dest->selected_fib) {
1390 route_unlock_node(rn);
1391 continue;
1392 }
1393
1394 network_found = true;
1395 if (json)
1396 vty_show_ip_route_detail_json(vty, rn,
1397 use_fib);
1398 else
1399 vty_show_ip_route_detail(vty, rn, 0, use_fib);
1400
1401 route_unlock_node(rn);
1402 }
1403
1404 if (!network_found) {
1405 if (json)
1406 vty_out(vty, "{}\n");
1407 else {
1408 if (use_fib)
1409 vty_out(vty,
1410 "%% Network not in FIB\n");
1411 else
1412 vty_out(vty,
1413 "%% Network not in RIB\n");
1414 }
1415 return CMD_WARNING;
1416 }
1417 } else {
1418 vrf_id_t vrf_id = VRF_DEFAULT;
1419
1420 if (vrf_name)
1421 VRF_GET_ID(vrf_id, vrf_name, false);
1422
1423 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1424 if (!table)
1425 return CMD_SUCCESS;
1426
1427 rn = route_node_match(table, &p);
1428 if (rn)
1429 dest = rib_dest_from_rnode(rn);
1430
1431 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
1432 (use_fib && dest && !dest->selected_fib)) {
1433 if (json)
1434 vty_out(vty, "{}\n");
1435 else {
1436 if (use_fib)
1437 vty_out(vty,
1438 "%% Network not in FIB\n");
1439 else
1440 vty_out(vty,
1441 "%% Network not in table\n");
1442 }
1443 if (rn)
1444 route_unlock_node(rn);
1445 return CMD_WARNING;
1446 }
1447
1448 if (json)
1449 vty_show_ip_route_detail_json(vty, rn, use_fib);
1450 else
1451 vty_show_ip_route_detail(vty, rn, 0, use_fib);
1452
1453 route_unlock_node(rn);
1454 }
1455
1456 return CMD_SUCCESS;
1457 }
1458
1459 DEFPY (show_route_summary,
1460 show_route_summary_cmd,
1461 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1462 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1463 SHOW_STR
1464 IP_STR
1465 IP6_STR
1466 "IP routing table\n"
1467 VRF_FULL_CMD_HELP_STR
1468 "Summary of all routes\n"
1469 "Table to display summary for\n"
1470 "The table number\n"
1471 "Prefix routes\n")
1472 {
1473 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1474 struct route_table *table;
1475
1476 if (table_id == 0)
1477 table_id = RT_TABLE_MAIN;
1478
1479 if (vrf_all) {
1480 struct vrf *vrf;
1481 struct zebra_vrf *zvrf;
1482
1483 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1484 if ((zvrf = vrf->info) == NULL)
1485 continue;
1486
1487 table = zebra_vrf_table_with_table_id(afi,
1488 SAFI_UNICAST,
1489 zvrf->vrf->vrf_id,
1490 table_id);
1491 if (!table)
1492 continue;
1493
1494 if (prefix)
1495 vty_show_ip_route_summary_prefix(vty, table);
1496 else
1497 vty_show_ip_route_summary(vty, table);
1498 }
1499 } else {
1500 vrf_id_t vrf_id = VRF_DEFAULT;
1501
1502 if (vrf_name)
1503 VRF_GET_ID(vrf_id, vrf_name, false);
1504
1505 table = zebra_vrf_table_with_table_id(afi,
1506 SAFI_UNICAST,
1507 vrf_id, table_id);
1508 if (!table)
1509 return CMD_SUCCESS;
1510
1511 if (prefix)
1512 vty_show_ip_route_summary_prefix(vty, table);
1513 else
1514 vty_show_ip_route_summary(vty, table);
1515 }
1516
1517 return CMD_SUCCESS;
1518 }
1519
1520 static void vty_show_ip_route_summary(struct vty *vty,
1521 struct route_table *table)
1522 {
1523 struct route_node *rn;
1524 struct route_entry *re;
1525 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1526 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1527 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1528 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1529 uint32_t i;
1530 uint32_t is_ibgp;
1531
1532 memset(&rib_cnt, 0, sizeof(rib_cnt));
1533 memset(&fib_cnt, 0, sizeof(fib_cnt));
1534 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1535 RNODE_FOREACH_RE (rn, re) {
1536 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1537 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1538
1539 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1540 if (is_ibgp)
1541 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1542 else
1543 rib_cnt[re->type]++;
1544
1545 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1546 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1547
1548 if (is_ibgp)
1549 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1550 else
1551 fib_cnt[re->type]++;
1552 }
1553 }
1554
1555 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1556 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1557
1558 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1559 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1560 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1561 if (i == ZEBRA_ROUTE_BGP) {
1562 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1563 rib_cnt[ZEBRA_ROUTE_BGP],
1564 fib_cnt[ZEBRA_ROUTE_BGP]);
1565 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1566 rib_cnt[ZEBRA_ROUTE_IBGP],
1567 fib_cnt[ZEBRA_ROUTE_IBGP]);
1568 } else
1569 vty_out(vty, "%-20s %-20d %-20d \n",
1570 zebra_route_string(i), rib_cnt[i],
1571 fib_cnt[i]);
1572 }
1573 }
1574
1575 vty_out(vty, "------\n");
1576 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1577 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1578 vty_out(vty, "\n");
1579 }
1580
1581 /*
1582 * Implementation of the ip route summary prefix command.
1583 *
1584 * This command prints the primary prefixes that have been installed by various
1585 * protocols on the box.
1586 *
1587 */
1588 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1589 struct route_table *table)
1590 {
1591 struct route_node *rn;
1592 struct route_entry *re;
1593 struct nexthop *nexthop;
1594 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1595 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1596 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1597 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1598 uint32_t i;
1599 int cnt;
1600
1601 memset(&rib_cnt, 0, sizeof(rib_cnt));
1602 memset(&fib_cnt, 0, sizeof(fib_cnt));
1603 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1604 RNODE_FOREACH_RE (rn, re) {
1605
1606 /*
1607 * In case of ECMP, count only once.
1608 */
1609 cnt = 0;
1610 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1611 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1612 fib_cnt[re->type]++;
1613 }
1614 for (nexthop = re->ng->nexthop; (!cnt && nexthop);
1615 nexthop = nexthop->next) {
1616 cnt++;
1617 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1618 rib_cnt[re->type]++;
1619 if (re->type == ZEBRA_ROUTE_BGP
1620 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1621 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1622 if (CHECK_FLAG(re->status,
1623 ROUTE_ENTRY_INSTALLED))
1624 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1625 }
1626 }
1627 }
1628
1629 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1630 "Prefix Routes", "FIB",
1631 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1632
1633 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1634 if (rib_cnt[i] > 0) {
1635 if (i == ZEBRA_ROUTE_BGP) {
1636 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1637 rib_cnt[ZEBRA_ROUTE_BGP]
1638 - rib_cnt[ZEBRA_ROUTE_IBGP],
1639 fib_cnt[ZEBRA_ROUTE_BGP]
1640 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1641 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1642 rib_cnt[ZEBRA_ROUTE_IBGP],
1643 fib_cnt[ZEBRA_ROUTE_IBGP]);
1644 } else
1645 vty_out(vty, "%-20s %-20d %-20d \n",
1646 zebra_route_string(i), rib_cnt[i],
1647 fib_cnt[i]);
1648 }
1649 }
1650
1651 vty_out(vty, "------\n");
1652 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1653 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1654 vty_out(vty, "\n");
1655 }
1656
1657 /*
1658 * Show IPv6 mroute command.Used to dump
1659 * the Multicast routing table.
1660 */
1661 DEFUN (show_ipv6_mroute,
1662 show_ipv6_mroute_cmd,
1663 "show ipv6 mroute [vrf NAME]",
1664 SHOW_STR
1665 IP_STR
1666 "IPv6 Multicast routing table\n"
1667 VRF_CMD_HELP_STR)
1668 {
1669 struct route_table *table;
1670 struct route_node *rn;
1671 struct route_entry *re;
1672 int first = 1;
1673 vrf_id_t vrf_id = VRF_DEFAULT;
1674
1675 if (argc == 5)
1676 VRF_GET_ID(vrf_id, argv[4]->arg, false);
1677
1678 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1679 if (!table)
1680 return CMD_SUCCESS;
1681
1682 /* Show all IPv6 route. */
1683 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1684 RNODE_FOREACH_RE (rn, re) {
1685 if (first) {
1686 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1687 first = 0;
1688 }
1689 vty_show_ip_route(vty, rn, re, NULL, false);
1690 }
1691 return CMD_SUCCESS;
1692 }
1693
1694 DEFUN (show_ipv6_mroute_vrf_all,
1695 show_ipv6_mroute_vrf_all_cmd,
1696 "show ipv6 mroute vrf all",
1697 SHOW_STR
1698 IP_STR
1699 "IPv6 Multicast routing table\n"
1700 VRF_ALL_CMD_HELP_STR)
1701 {
1702 struct route_table *table;
1703 struct route_node *rn;
1704 struct route_entry *re;
1705 struct vrf *vrf;
1706 struct zebra_vrf *zvrf;
1707 int first = 1;
1708
1709 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1710 if ((zvrf = vrf->info) == NULL
1711 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1712 continue;
1713
1714 /* Show all IPv6 route. */
1715 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1716 RNODE_FOREACH_RE (rn, re) {
1717 if (first) {
1718 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1719 first = 0;
1720 }
1721 vty_show_ip_route(vty, rn, re, NULL, false);
1722 }
1723 }
1724 return CMD_SUCCESS;
1725 }
1726
1727 DEFUN (allow_external_route_update,
1728 allow_external_route_update_cmd,
1729 "allow-external-route-update",
1730 "Allow FRR routes to be overwritten by external processes\n")
1731 {
1732 allow_delete = 1;
1733
1734 return CMD_SUCCESS;
1735 }
1736
1737 DEFUN (no_allow_external_route_update,
1738 no_allow_external_route_update_cmd,
1739 "no allow-external-route-update",
1740 NO_STR
1741 "Allow FRR routes to be overwritten by external processes\n")
1742 {
1743 allow_delete = 0;
1744
1745 return CMD_SUCCESS;
1746 }
1747
1748 /* show vrf */
1749 DEFUN (show_vrf,
1750 show_vrf_cmd,
1751 "show vrf",
1752 SHOW_STR
1753 "VRF\n")
1754 {
1755 struct vrf *vrf;
1756 struct zebra_vrf *zvrf;
1757
1758 if (vrf_is_backend_netns())
1759 vty_out(vty, "netns-based vrfs\n");
1760
1761 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1762 if (!(zvrf = vrf->info))
1763 continue;
1764 if (zvrf_id(zvrf) == VRF_DEFAULT)
1765 continue;
1766
1767 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
1768 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
1769 vty_out(vty, "inactive");
1770 else if (zvrf_ns_name(zvrf))
1771 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1772 zvrf_ns_name(zvrf));
1773 else
1774 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1775 zvrf->table_id);
1776 if (vrf_is_user_cfged(vrf))
1777 vty_out(vty, " (configured)");
1778 vty_out(vty, "\n");
1779 }
1780
1781 return CMD_SUCCESS;
1782 }
1783
1784 DEFUN (default_vrf_vni_mapping,
1785 default_vrf_vni_mapping_cmd,
1786 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1787 "VNI corresponding to the DEFAULT VRF\n"
1788 "VNI-ID\n"
1789 "Prefix routes only \n")
1790 {
1791 int ret = 0;
1792 char err[ERR_STR_SZ];
1793 struct zebra_vrf *zvrf = NULL;
1794 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1795 int filter = 0;
1796
1797 zvrf = vrf_info_lookup(VRF_DEFAULT);
1798 if (!zvrf)
1799 return CMD_WARNING;
1800
1801 if (argc == 3)
1802 filter = 1;
1803
1804 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1805 filter, 1);
1806 if (ret != 0) {
1807 vty_out(vty, "%s\n", err);
1808 return CMD_WARNING;
1809 }
1810
1811 return CMD_SUCCESS;
1812 }
1813
1814 DEFUN (no_default_vrf_vni_mapping,
1815 no_default_vrf_vni_mapping_cmd,
1816 "no vni " CMD_VNI_RANGE,
1817 NO_STR
1818 "VNI corresponding to DEFAULT VRF\n"
1819 "VNI-ID")
1820 {
1821 int ret = 0;
1822 char err[ERR_STR_SZ];
1823 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1824 struct zebra_vrf *zvrf = NULL;
1825
1826 zvrf = vrf_info_lookup(VRF_DEFAULT);
1827 if (!zvrf)
1828 return CMD_WARNING;
1829
1830 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
1831 if (ret != 0) {
1832 vty_out(vty, "%s\n", err);
1833 return CMD_WARNING;
1834 }
1835
1836 return CMD_SUCCESS;
1837 }
1838
1839 DEFUN (vrf_vni_mapping,
1840 vrf_vni_mapping_cmd,
1841 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1842 "VNI corresponding to tenant VRF\n"
1843 "VNI-ID\n"
1844 "prefix-routes-only\n")
1845 {
1846 int ret = 0;
1847 int filter = 0;
1848
1849 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1850 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1851 char err[ERR_STR_SZ];
1852
1853 assert(vrf);
1854 assert(zvrf);
1855
1856 if (argc == 3)
1857 filter = 1;
1858
1859 /* Mark as having FRR configuration */
1860 vrf_set_user_cfged(vrf);
1861 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1862 filter, 1);
1863 if (ret != 0) {
1864 vty_out(vty, "%s\n", err);
1865 return CMD_WARNING;
1866 }
1867
1868 return CMD_SUCCESS;
1869 }
1870
1871 DEFUN (no_vrf_vni_mapping,
1872 no_vrf_vni_mapping_cmd,
1873 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
1874 NO_STR
1875 "VNI corresponding to tenant VRF\n"
1876 "VNI-ID\n"
1877 "prefix-routes-only\n")
1878 {
1879 int ret = 0;
1880 int filter = 0;
1881 char err[ERR_STR_SZ];
1882 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1883
1884 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1885
1886 assert(vrf);
1887 assert(zvrf);
1888
1889 if (argc == 4)
1890 filter = 1;
1891
1892 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1893 ERR_STR_SZ, filter, 0);
1894 if (ret != 0) {
1895 vty_out(vty, "%s\n", err);
1896 return CMD_WARNING;
1897 }
1898
1899 /* If no other FRR config for this VRF, mark accordingly. */
1900 if (!zebra_vrf_has_config(zvrf))
1901 vrf_reset_user_cfged(vrf);
1902
1903 return CMD_SUCCESS;
1904 }
1905
1906 /* show vrf */
1907 DEFUN (show_vrf_vni,
1908 show_vrf_vni_cmd,
1909 "show vrf vni [json]",
1910 SHOW_STR
1911 "VRF\n"
1912 "VNI\n"
1913 JSON_STR)
1914 {
1915 struct vrf *vrf;
1916 struct zebra_vrf *zvrf;
1917 json_object *json = NULL;
1918 json_object *json_vrfs = NULL;
1919 bool uj = use_json(argc, argv);
1920
1921 if (uj) {
1922 json = json_object_new_object();
1923 json_vrfs = json_object_new_array();
1924 }
1925
1926 if (!uj)
1927 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1928 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1929
1930 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1931 zvrf = vrf->info;
1932 if (!zvrf)
1933 continue;
1934
1935 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
1936 }
1937
1938 if (uj) {
1939 json_object_object_add(json, "vrfs", json_vrfs);
1940 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1941 json, JSON_C_TO_STRING_PRETTY));
1942 json_object_free(json);
1943 }
1944
1945 return CMD_SUCCESS;
1946 }
1947
1948 DEFUN (show_evpn_global,
1949 show_evpn_global_cmd,
1950 "show evpn [json]",
1951 SHOW_STR
1952 "EVPN\n"
1953 JSON_STR)
1954 {
1955 bool uj = use_json(argc, argv);
1956
1957 zebra_vxlan_print_evpn(vty, uj);
1958 return CMD_SUCCESS;
1959 }
1960
1961 DEFUN (show_evpn_vni,
1962 show_evpn_vni_cmd,
1963 "show evpn vni [json]",
1964 SHOW_STR
1965 "EVPN\n"
1966 "VxLAN Network Identifier\n"
1967 JSON_STR)
1968 {
1969 struct zebra_vrf *zvrf;
1970 bool uj = use_json(argc, argv);
1971
1972 zvrf = zebra_vrf_get_evpn();
1973 zebra_vxlan_print_vnis(vty, zvrf, uj);
1974 return CMD_SUCCESS;
1975 }
1976
1977 DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
1978 "show evpn vni detail [json]",
1979 SHOW_STR
1980 "EVPN\n"
1981 "VxLAN Network Identifier\n"
1982 "Detailed Information On Each VNI\n"
1983 JSON_STR)
1984 {
1985 struct zebra_vrf *zvrf;
1986 bool uj = use_json(argc, argv);
1987
1988 zvrf = zebra_vrf_get_evpn();
1989 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
1990 return CMD_SUCCESS;
1991 }
1992
1993 DEFUN (show_evpn_vni_vni,
1994 show_evpn_vni_vni_cmd,
1995 "show evpn vni " CMD_VNI_RANGE "[json]",
1996 SHOW_STR
1997 "EVPN\n"
1998 "VxLAN Network Identifier\n"
1999 "VNI number\n"
2000 JSON_STR)
2001 {
2002 struct zebra_vrf *zvrf;
2003 vni_t vni;
2004 bool uj = use_json(argc, argv);
2005
2006 vni = strtoul(argv[3]->arg, NULL, 10);
2007 zvrf = zebra_vrf_get_evpn();
2008 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
2009 return CMD_SUCCESS;
2010 }
2011
2012 DEFUN (show_evpn_rmac_vni_mac,
2013 show_evpn_rmac_vni_mac_cmd,
2014 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
2015 SHOW_STR
2016 "EVPN\n"
2017 "RMAC\n"
2018 "L3 VNI\n"
2019 "VNI number\n"
2020 "MAC\n"
2021 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2022 JSON_STR)
2023 {
2024 vni_t l3vni = 0;
2025 struct ethaddr mac;
2026 bool uj = use_json(argc, argv);
2027
2028 l3vni = strtoul(argv[4]->arg, NULL, 10);
2029 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2030 vty_out(vty, "%% Malformed MAC address\n");
2031 return CMD_WARNING;
2032 }
2033 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
2034 return CMD_SUCCESS;
2035 }
2036
2037 DEFUN (show_evpn_rmac_vni,
2038 show_evpn_rmac_vni_cmd,
2039 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
2040 SHOW_STR
2041 "EVPN\n"
2042 "RMAC\n"
2043 "L3 VNI\n"
2044 "VNI number\n"
2045 JSON_STR)
2046 {
2047 vni_t l3vni = 0;
2048 bool uj = use_json(argc, argv);
2049
2050 l3vni = strtoul(argv[4]->arg, NULL, 10);
2051 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2052
2053 return CMD_SUCCESS;
2054 }
2055
2056 DEFUN (show_evpn_rmac_vni_all,
2057 show_evpn_rmac_vni_all_cmd,
2058 "show evpn rmac vni all [json]",
2059 SHOW_STR
2060 "EVPN\n"
2061 "RMAC addresses\n"
2062 "L3 VNI\n"
2063 "All VNIs\n"
2064 JSON_STR)
2065 {
2066 bool uj = use_json(argc, argv);
2067
2068 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2069
2070 return CMD_SUCCESS;
2071 }
2072
2073 DEFUN (show_evpn_nh_vni_ip,
2074 show_evpn_nh_vni_ip_cmd,
2075 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
2076 SHOW_STR
2077 "EVPN\n"
2078 "Remote Vteps\n"
2079 "L3 VNI\n"
2080 "VNI number\n"
2081 "Ip address\n"
2082 "Host address (ipv4 or ipv6)\n"
2083 JSON_STR)
2084 {
2085 vni_t l3vni;
2086 struct ipaddr ip;
2087 bool uj = use_json(argc, argv);
2088
2089 l3vni = strtoul(argv[4]->arg, NULL, 10);
2090 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2091 if (!uj)
2092 vty_out(vty, "%% Malformed Neighbor address\n");
2093 return CMD_WARNING;
2094 }
2095 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
2096
2097 return CMD_SUCCESS;
2098 }
2099
2100 DEFUN (show_evpn_nh_vni,
2101 show_evpn_nh_vni_cmd,
2102 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
2103 SHOW_STR
2104 "EVPN\n"
2105 "Remote Vteps\n"
2106 "L3 VNI\n"
2107 "VNI number\n"
2108 JSON_STR)
2109 {
2110 vni_t l3vni;
2111 bool uj = use_json(argc, argv);
2112
2113 l3vni = strtoul(argv[4]->arg, NULL, 10);
2114 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2115
2116 return CMD_SUCCESS;
2117 }
2118
2119 DEFUN (show_evpn_nh_vni_all,
2120 show_evpn_nh_vni_all_cmd,
2121 "show evpn next-hops vni all [json]",
2122 SHOW_STR
2123 "EVPN\n"
2124 "Remote VTEPs\n"
2125 "L3 VNI\n"
2126 "All VNIs\n"
2127 JSON_STR)
2128 {
2129 bool uj = use_json(argc, argv);
2130
2131 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2132
2133 return CMD_SUCCESS;
2134 }
2135
2136 DEFUN (show_evpn_mac_vni,
2137 show_evpn_mac_vni_cmd,
2138 "show evpn mac vni " CMD_VNI_RANGE "[json]",
2139 SHOW_STR
2140 "EVPN\n"
2141 "MAC addresses\n"
2142 "VxLAN Network Identifier\n"
2143 "VNI number\n"
2144 JSON_STR)
2145 {
2146 struct zebra_vrf *zvrf;
2147 vni_t vni;
2148 bool uj = use_json(argc, argv);
2149
2150 vni = strtoul(argv[4]->arg, NULL, 10);
2151 zvrf = zebra_vrf_get_evpn();
2152 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
2153 return CMD_SUCCESS;
2154 }
2155
2156 DEFUN (show_evpn_mac_vni_all,
2157 show_evpn_mac_vni_all_cmd,
2158 "show evpn mac vni all [json]",
2159 SHOW_STR
2160 "EVPN\n"
2161 "MAC addresses\n"
2162 "VxLAN Network Identifier\n"
2163 "All VNIs\n"
2164 JSON_STR)
2165 {
2166 struct zebra_vrf *zvrf;
2167 bool uj = use_json(argc, argv);
2168
2169 zvrf = zebra_vrf_get_evpn();
2170 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
2171 return CMD_SUCCESS;
2172 }
2173
2174 DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
2175 "show evpn mac vni all detail [json]",
2176 SHOW_STR
2177 "EVPN\n"
2178 "MAC addresses\n"
2179 "VxLAN Network Identifier\n"
2180 "All VNIs\n"
2181 "Detailed Information On Each VNI MAC\n"
2182 JSON_STR)
2183 {
2184 struct zebra_vrf *zvrf;
2185 bool uj = use_json(argc, argv);
2186
2187 zvrf = zebra_vrf_get_evpn();
2188 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
2189 return CMD_SUCCESS;
2190 }
2191
2192 DEFUN (show_evpn_mac_vni_all_vtep,
2193 show_evpn_mac_vni_all_vtep_cmd,
2194 "show evpn mac vni all vtep A.B.C.D [json]",
2195 SHOW_STR
2196 "EVPN\n"
2197 "MAC addresses\n"
2198 "VxLAN Network Identifier\n"
2199 "All VNIs\n"
2200 "Remote VTEP\n"
2201 "Remote VTEP IP address\n"
2202 JSON_STR)
2203 {
2204 struct zebra_vrf *zvrf;
2205 struct in_addr vtep_ip;
2206 bool uj = use_json(argc, argv);
2207
2208 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2209 if (!uj)
2210 vty_out(vty, "%% Malformed VTEP IP address\n");
2211 return CMD_WARNING;
2212 }
2213 zvrf = zebra_vrf_get_evpn();
2214 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2215
2216 return CMD_SUCCESS;
2217 }
2218
2219
2220 DEFUN (show_evpn_mac_vni_mac,
2221 show_evpn_mac_vni_mac_cmd,
2222 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
2223 SHOW_STR
2224 "EVPN\n"
2225 "MAC addresses\n"
2226 "VxLAN Network Identifier\n"
2227 "VNI number\n"
2228 "MAC\n"
2229 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2230 JSON_STR)
2231
2232 {
2233 struct zebra_vrf *zvrf;
2234 vni_t vni;
2235 struct ethaddr mac;
2236 bool uj = use_json(argc, argv);
2237
2238 vni = strtoul(argv[4]->arg, NULL, 10);
2239 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2240 vty_out(vty, "%% Malformed MAC address");
2241 return CMD_WARNING;
2242 }
2243 zvrf = zebra_vrf_get_evpn();
2244 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
2245 return CMD_SUCCESS;
2246 }
2247
2248 DEFUN (show_evpn_mac_vni_vtep,
2249 show_evpn_mac_vni_vtep_cmd,
2250 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
2251 SHOW_STR
2252 "EVPN\n"
2253 "MAC addresses\n"
2254 "VxLAN Network Identifier\n"
2255 "VNI number\n"
2256 "Remote VTEP\n"
2257 "Remote VTEP IP address\n"
2258 JSON_STR)
2259 {
2260 struct zebra_vrf *zvrf;
2261 vni_t vni;
2262 struct in_addr vtep_ip;
2263 bool uj = use_json(argc, argv);
2264
2265 vni = strtoul(argv[4]->arg, NULL, 10);
2266 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2267 if (!uj)
2268 vty_out(vty, "%% Malformed VTEP IP address\n");
2269 return CMD_WARNING;
2270 }
2271
2272 zvrf = zebra_vrf_get_evpn();
2273 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2274 return CMD_SUCCESS;
2275 }
2276
2277 DEFPY (show_evpn_mac_vni_all_dad,
2278 show_evpn_mac_vni_all_dad_cmd,
2279 "show evpn mac vni all duplicate [json]",
2280 SHOW_STR
2281 "EVPN\n"
2282 "MAC addresses\n"
2283 "VxLAN Network Identifier\n"
2284 "All VNIs\n"
2285 "Duplicate address list\n"
2286 JSON_STR)
2287 {
2288 struct zebra_vrf *zvrf;
2289 bool uj = use_json(argc, argv);
2290
2291 zvrf = zebra_vrf_get_evpn();
2292 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2293 return CMD_SUCCESS;
2294 }
2295
2296
2297 DEFPY (show_evpn_mac_vni_dad,
2298 show_evpn_mac_vni_dad_cmd,
2299 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
2300 SHOW_STR
2301 "EVPN\n"
2302 "MAC addresses\n"
2303 "VxLAN Network Identifier\n"
2304 "VNI number\n"
2305 "Duplicate address list\n"
2306 JSON_STR)
2307 {
2308 struct zebra_vrf *zvrf;
2309 bool uj = use_json(argc, argv);
2310
2311 zvrf = zebra_vrf_get_evpn();
2312
2313 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2314
2315 return CMD_SUCCESS;
2316 }
2317
2318 DEFPY (show_evpn_neigh_vni_dad,
2319 show_evpn_neigh_vni_dad_cmd,
2320 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
2321 SHOW_STR
2322 "EVPN\n"
2323 "ARP and ND cache\n"
2324 "VxLAN Network Identifier\n"
2325 "VNI number\n"
2326 "Duplicate address list\n"
2327 JSON_STR)
2328 {
2329 struct zebra_vrf *zvrf;
2330 bool uj = use_json(argc, argv);
2331
2332 zvrf = zebra_vrf_get_evpn();
2333 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2334 return CMD_SUCCESS;
2335 }
2336
2337 DEFPY (show_evpn_neigh_vni_all_dad,
2338 show_evpn_neigh_vni_all_dad_cmd,
2339 "show evpn arp-cache vni all duplicate [json]",
2340 SHOW_STR
2341 "EVPN\n"
2342 "ARP and ND cache\n"
2343 "VxLAN Network Identifier\n"
2344 "All VNIs\n"
2345 "Duplicate address list\n"
2346 JSON_STR)
2347 {
2348 struct zebra_vrf *zvrf;
2349 bool uj = use_json(argc, argv);
2350
2351 zvrf = zebra_vrf_get_evpn();
2352 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2353 return CMD_SUCCESS;
2354 }
2355
2356
2357 DEFUN (show_evpn_neigh_vni,
2358 show_evpn_neigh_vni_cmd,
2359 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2360 SHOW_STR
2361 "EVPN\n"
2362 "ARP and ND cache\n"
2363 "VxLAN Network Identifier\n"
2364 "VNI number\n"
2365 JSON_STR)
2366 {
2367 struct zebra_vrf *zvrf;
2368 vni_t vni;
2369 bool uj = use_json(argc, argv);
2370
2371 vni = strtoul(argv[4]->arg, NULL, 10);
2372 zvrf = zebra_vrf_get_evpn();
2373 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2374 return CMD_SUCCESS;
2375 }
2376
2377 DEFUN (show_evpn_neigh_vni_all,
2378 show_evpn_neigh_vni_all_cmd,
2379 "show evpn arp-cache vni all [json]",
2380 SHOW_STR
2381 "EVPN\n"
2382 "ARP and ND cache\n"
2383 "VxLAN Network Identifier\n"
2384 "All VNIs\n"
2385 JSON_STR)
2386 {
2387 struct zebra_vrf *zvrf;
2388 bool uj = use_json(argc, argv);
2389
2390 zvrf = zebra_vrf_get_evpn();
2391 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
2392 return CMD_SUCCESS;
2393 }
2394
2395 DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
2396 "show evpn arp-cache vni all detail [json]",
2397 SHOW_STR
2398 "EVPN\n"
2399 "ARP and ND cache\n"
2400 "VxLAN Network Identifier\n"
2401 "All VNIs\n"
2402 "Neighbor details for all vnis in detail\n" JSON_STR)
2403 {
2404 struct zebra_vrf *zvrf;
2405 bool uj = use_json(argc, argv);
2406
2407 zvrf = zebra_vrf_get_evpn();
2408 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
2409 return CMD_SUCCESS;
2410 }
2411
2412 DEFUN (show_evpn_neigh_vni_neigh,
2413 show_evpn_neigh_vni_neigh_cmd,
2414 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2415 SHOW_STR
2416 "EVPN\n"
2417 "ARP and ND cache\n"
2418 "VxLAN Network Identifier\n"
2419 "VNI number\n"
2420 "Neighbor\n"
2421 "Neighbor address (IPv4 or IPv6 address)\n"
2422 JSON_STR)
2423 {
2424 struct zebra_vrf *zvrf;
2425 vni_t vni;
2426 struct ipaddr ip;
2427 bool uj = use_json(argc, argv);
2428
2429 vni = strtoul(argv[4]->arg, NULL, 10);
2430 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2431 if (!uj)
2432 vty_out(vty, "%% Malformed Neighbor address\n");
2433 return CMD_WARNING;
2434 }
2435 zvrf = zebra_vrf_get_evpn();
2436 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2437 return CMD_SUCCESS;
2438 }
2439
2440 DEFUN (show_evpn_neigh_vni_vtep,
2441 show_evpn_neigh_vni_vtep_cmd,
2442 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2443 SHOW_STR
2444 "EVPN\n"
2445 "ARP and ND cache\n"
2446 "VxLAN Network Identifier\n"
2447 "VNI number\n"
2448 "Remote VTEP\n"
2449 "Remote VTEP IP address\n"
2450 JSON_STR)
2451 {
2452 struct zebra_vrf *zvrf;
2453 vni_t vni;
2454 struct in_addr vtep_ip;
2455 bool uj = use_json(argc, argv);
2456
2457 vni = strtoul(argv[4]->arg, NULL, 10);
2458 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2459 if (!uj)
2460 vty_out(vty, "%% Malformed VTEP IP address\n");
2461 return CMD_WARNING;
2462 }
2463
2464 zvrf = zebra_vrf_get_evpn();
2465 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2466 return CMD_SUCCESS;
2467 }
2468
2469 /* policy routing contexts */
2470 DEFUN (show_pbr_ipset,
2471 show_pbr_ipset_cmd,
2472 "show pbr ipset [WORD]",
2473 SHOW_STR
2474 "Policy-Based Routing\n"
2475 "IPset Context information\n"
2476 "IPset Name information\n")
2477 {
2478 int idx = 0;
2479 int found = 0;
2480 found = argv_find(argv, argc, "WORD", &idx);
2481 if (!found)
2482 zebra_pbr_show_ipset_list(vty, NULL);
2483 else
2484 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2485 return CMD_SUCCESS;
2486 }
2487
2488 /* policy routing contexts */
2489 DEFUN (show_pbr_iptable,
2490 show_pbr_iptable_cmd,
2491 "show pbr iptable [WORD]",
2492 SHOW_STR
2493 "Policy-Based Routing\n"
2494 "IPtable Context information\n"
2495 "IPtable Name information\n")
2496 {
2497 int idx = 0;
2498 int found = 0;
2499
2500 found = argv_find(argv, argc, "WORD", &idx);
2501 if (!found)
2502 zebra_pbr_show_iptable(vty, NULL);
2503 else
2504 zebra_pbr_show_iptable(vty, argv[idx]->arg);
2505 return CMD_SUCCESS;
2506 }
2507
2508 DEFPY (clear_evpn_dup_addr,
2509 clear_evpn_dup_addr_cmd,
2510 "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni [mac X:X:X:X:X:X | ip <A.B.C.D|X:X::X:X>]>",
2511 CLEAR_STR
2512 "EVPN\n"
2513 "Duplicate address \n"
2514 "VxLAN Network Identifier\n"
2515 "VNI number\n"
2516 "All VNIs\n"
2517 "MAC\n"
2518 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2519 "IP\n"
2520 "IPv4 address\n"
2521 "IPv6 address\n")
2522 {
2523 struct zebra_vrf *zvrf;
2524 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
2525 int ret = CMD_SUCCESS;
2526
2527 zvrf = zebra_vrf_get_evpn();
2528 if (vni_str) {
2529 if (!is_zero_mac(&mac->eth_addr)) {
2530 ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
2531 vni,
2532 &mac->eth_addr);
2533 } else if (ip) {
2534 if (sockunion_family(ip) == AF_INET) {
2535 host_ip.ipa_type = IPADDR_V4;
2536 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2537 } else {
2538 host_ip.ipa_type = IPADDR_V6;
2539 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2540 sizeof(struct in6_addr));
2541 }
2542 ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
2543 vni,
2544 &host_ip);
2545 } else
2546 ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
2547
2548 } else {
2549 ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
2550 }
2551
2552 return ret;
2553 }
2554
2555 /* Static ip route configuration write function. */
2556 static int zebra_ip_config(struct vty *vty)
2557 {
2558 int write = 0;
2559
2560 write += zebra_import_table_config(vty, VRF_DEFAULT);
2561
2562 return write;
2563 }
2564
2565 DEFUN (ip_zebra_import_table_distance,
2566 ip_zebra_import_table_distance_cmd,
2567 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2568 IP_STR
2569 "import routes from non-main kernel table\n"
2570 "kernel routing table id\n"
2571 "Distance for imported routes\n"
2572 "Default distance value\n"
2573 "route-map for filtering\n"
2574 "route-map name\n")
2575 {
2576 uint32_t table_id = 0;
2577
2578 table_id = strtoul(argv[2]->arg, NULL, 10);
2579 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2580 char *rmap =
2581 strmatch(argv[argc - 2]->text, "route-map")
2582 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2583 : NULL;
2584 int ret;
2585
2586 if (argc == 7 || (argc == 5 && !rmap))
2587 distance = strtoul(argv[4]->arg, NULL, 10);
2588
2589 if (!is_zebra_valid_kernel_table(table_id)) {
2590 vty_out(vty,
2591 "Invalid routing table ID, %d. Must be in range 1-252\n",
2592 table_id);
2593 if (rmap)
2594 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2595 return CMD_WARNING;
2596 }
2597
2598 if (is_zebra_main_routing_table(table_id)) {
2599 vty_out(vty,
2600 "Invalid routing table ID, %d. Must be non-default table\n",
2601 table_id);
2602 if (rmap)
2603 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2604 return CMD_WARNING;
2605 }
2606
2607 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
2608 distance, rmap, 1);
2609 if (rmap)
2610 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2611
2612 return ret;
2613 }
2614
2615 DEFUN_HIDDEN (zebra_packet_process,
2616 zebra_packet_process_cmd,
2617 "zebra zapi-packets (1-10000)",
2618 ZEBRA_STR
2619 "Zapi Protocol\n"
2620 "Number of packets to process before relinquishing thread\n")
2621 {
2622 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2623
2624 atomic_store_explicit(&zrouter.packets_to_process, packets,
2625 memory_order_relaxed);
2626
2627 return CMD_SUCCESS;
2628 }
2629
2630 DEFUN_HIDDEN (no_zebra_packet_process,
2631 no_zebra_packet_process_cmd,
2632 "no zebra zapi-packets [(1-10000)]",
2633 NO_STR
2634 ZEBRA_STR
2635 "Zapi Protocol\n"
2636 "Number of packets to process before relinquishing thread\n")
2637 {
2638 atomic_store_explicit(&zrouter.packets_to_process,
2639 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2640 memory_order_relaxed);
2641
2642 return CMD_SUCCESS;
2643 }
2644
2645 DEFUN_HIDDEN (zebra_workqueue_timer,
2646 zebra_workqueue_timer_cmd,
2647 "zebra work-queue (0-10000)",
2648 ZEBRA_STR
2649 "Work Queue\n"
2650 "Time in milliseconds\n")
2651 {
2652 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2653 zrouter.ribq->spec.hold = timer;
2654
2655 return CMD_SUCCESS;
2656 }
2657
2658 DEFUN_HIDDEN (no_zebra_workqueue_timer,
2659 no_zebra_workqueue_timer_cmd,
2660 "no zebra work-queue [(0-10000)]",
2661 NO_STR
2662 ZEBRA_STR
2663 "Work Queue\n"
2664 "Time in milliseconds\n")
2665 {
2666 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
2667
2668 return CMD_SUCCESS;
2669 }
2670
2671 DEFUN (no_ip_zebra_import_table,
2672 no_ip_zebra_import_table_cmd,
2673 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2674 NO_STR
2675 IP_STR
2676 "import routes from non-main kernel table\n"
2677 "kernel routing table id\n"
2678 "Distance for imported routes\n"
2679 "Default distance value\n"
2680 "route-map for filtering\n"
2681 "route-map name\n")
2682 {
2683 uint32_t table_id = 0;
2684 table_id = strtoul(argv[3]->arg, NULL, 10);
2685
2686 if (!is_zebra_valid_kernel_table(table_id)) {
2687 vty_out(vty,
2688 "Invalid routing table ID. Must be in range 1-252\n");
2689 return CMD_WARNING;
2690 }
2691
2692 if (is_zebra_main_routing_table(table_id)) {
2693 vty_out(vty,
2694 "Invalid routing table ID, %d. Must be non-default table\n",
2695 table_id);
2696 return CMD_WARNING;
2697 }
2698
2699 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
2700 return CMD_SUCCESS;
2701
2702 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
2703 }
2704
2705 static int config_write_protocol(struct vty *vty)
2706 {
2707 if (allow_delete)
2708 vty_out(vty, "allow-external-route-update\n");
2709
2710 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2711 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
2712
2713 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
2714 vty_out(vty, "zebra zapi-packets %u\n",
2715 zrouter.packets_to_process);
2716
2717 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2718
2719 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2720 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2721 ipv4_multicast_mode == MCAST_URIB_ONLY
2722 ? "urib-only"
2723 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2724 ? "mrib-only"
2725 : ipv4_multicast_mode
2726 == MCAST_MIX_MRIB_FIRST
2727 ? "mrib-then-urib"
2728 : ipv4_multicast_mode
2729 == MCAST_MIX_DISTANCE
2730 ? "lower-distance"
2731 : "longer-prefix");
2732
2733 /* Include dataplane info */
2734 dplane_config_write_helper(vty);
2735
2736 return 1;
2737 }
2738
2739 DEFUN (show_zebra,
2740 show_zebra_cmd,
2741 "show zebra",
2742 SHOW_STR
2743 ZEBRA_STR)
2744 {
2745 struct vrf *vrf;
2746
2747 vty_out(vty,
2748 " Route Route Neighbor LSP LSP\n");
2749 vty_out(vty,
2750 "VRF Installs Removals Updates Installs Removals\n");
2751
2752 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2753 struct zebra_vrf *zvrf = vrf->info;
2754
2755 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2756 " %10" PRIu64 " %10" PRIu64 "\n",
2757 vrf->name, zvrf->installs, zvrf->removals,
2758 zvrf->neigh_updates, zvrf->lsp_installs,
2759 zvrf->lsp_removals);
2760 }
2761
2762 return CMD_SUCCESS;
2763 }
2764
2765 DEFUN (ip_forwarding,
2766 ip_forwarding_cmd,
2767 "ip forwarding",
2768 IP_STR
2769 "Turn on IP forwarding\n")
2770 {
2771 int ret;
2772
2773 ret = ipforward();
2774 if (ret == 0)
2775 ret = ipforward_on();
2776
2777 if (ret == 0) {
2778 vty_out(vty, "Can't turn on IP forwarding\n");
2779 return CMD_WARNING_CONFIG_FAILED;
2780 }
2781
2782 return CMD_SUCCESS;
2783 }
2784
2785 DEFUN (no_ip_forwarding,
2786 no_ip_forwarding_cmd,
2787 "no ip forwarding",
2788 NO_STR
2789 IP_STR
2790 "Turn off IP forwarding\n")
2791 {
2792 int ret;
2793
2794 ret = ipforward();
2795 if (ret != 0)
2796 ret = ipforward_off();
2797
2798 if (ret != 0) {
2799 vty_out(vty, "Can't turn off IP forwarding\n");
2800 return CMD_WARNING_CONFIG_FAILED;
2801 }
2802
2803 return CMD_SUCCESS;
2804 }
2805
2806 /* Only display ip forwarding is enabled or not. */
2807 DEFUN (show_ip_forwarding,
2808 show_ip_forwarding_cmd,
2809 "show ip forwarding",
2810 SHOW_STR
2811 IP_STR
2812 "IP forwarding status\n")
2813 {
2814 int ret;
2815
2816 ret = ipforward();
2817
2818 if (ret == 0)
2819 vty_out(vty, "IP forwarding is off\n");
2820 else
2821 vty_out(vty, "IP forwarding is on\n");
2822 return CMD_SUCCESS;
2823 }
2824
2825 /* Only display ipv6 forwarding is enabled or not. */
2826 DEFUN (show_ipv6_forwarding,
2827 show_ipv6_forwarding_cmd,
2828 "show ipv6 forwarding",
2829 SHOW_STR
2830 "IPv6 information\n"
2831 "Forwarding status\n")
2832 {
2833 int ret;
2834
2835 ret = ipforward_ipv6();
2836
2837 switch (ret) {
2838 case -1:
2839 vty_out(vty, "ipv6 forwarding is unknown\n");
2840 break;
2841 case 0:
2842 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2843 break;
2844 case 1:
2845 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2846 break;
2847 default:
2848 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2849 break;
2850 }
2851 return CMD_SUCCESS;
2852 }
2853
2854 DEFUN (ipv6_forwarding,
2855 ipv6_forwarding_cmd,
2856 "ipv6 forwarding",
2857 IPV6_STR
2858 "Turn on IPv6 forwarding\n")
2859 {
2860 int ret;
2861
2862 ret = ipforward_ipv6();
2863 if (ret == 0)
2864 ret = ipforward_ipv6_on();
2865
2866 if (ret == 0) {
2867 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2868 return CMD_WARNING_CONFIG_FAILED;
2869 }
2870
2871 return CMD_SUCCESS;
2872 }
2873
2874 DEFUN (no_ipv6_forwarding,
2875 no_ipv6_forwarding_cmd,
2876 "no ipv6 forwarding",
2877 NO_STR
2878 IPV6_STR
2879 "Turn off IPv6 forwarding\n")
2880 {
2881 int ret;
2882
2883 ret = ipforward_ipv6();
2884 if (ret != 0)
2885 ret = ipforward_ipv6_off();
2886
2887 if (ret != 0) {
2888 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2889 return CMD_WARNING_CONFIG_FAILED;
2890 }
2891
2892 return CMD_SUCCESS;
2893 }
2894
2895 /* Display dataplane info */
2896 DEFUN (show_dataplane,
2897 show_dataplane_cmd,
2898 "show zebra dplane [detailed]",
2899 SHOW_STR
2900 ZEBRA_STR
2901 "Zebra dataplane information\n"
2902 "Detailed output\n")
2903 {
2904 int idx = 0;
2905 bool detailed = false;
2906
2907 if (argv_find(argv, argc, "detailed", &idx))
2908 detailed = true;
2909
2910 return dplane_show_helper(vty, detailed);
2911 }
2912
2913 /* Display dataplane providers info */
2914 DEFUN (show_dataplane_providers,
2915 show_dataplane_providers_cmd,
2916 "show zebra dplane providers [detailed]",
2917 SHOW_STR
2918 ZEBRA_STR
2919 "Zebra dataplane information\n"
2920 "Zebra dataplane provider information\n"
2921 "Detailed output\n")
2922 {
2923 int idx = 0;
2924 bool detailed = false;
2925
2926 if (argv_find(argv, argc, "detailed", &idx))
2927 detailed = true;
2928
2929 return dplane_show_provs_helper(vty, detailed);
2930 }
2931
2932 /* Configure dataplane incoming queue limit */
2933 DEFUN (zebra_dplane_queue_limit,
2934 zebra_dplane_queue_limit_cmd,
2935 "zebra dplane limit (0-10000)",
2936 ZEBRA_STR
2937 "Zebra dataplane\n"
2938 "Limit incoming queued updates\n"
2939 "Number of queued updates\n")
2940 {
2941 uint32_t limit = 0;
2942
2943 limit = strtoul(argv[3]->arg, NULL, 10);
2944
2945 dplane_set_in_queue_limit(limit, true);
2946
2947 return CMD_SUCCESS;
2948 }
2949
2950 /* Reset dataplane queue limit to default value */
2951 DEFUN (no_zebra_dplane_queue_limit,
2952 no_zebra_dplane_queue_limit_cmd,
2953 "no zebra dplane limit [(0-10000)]",
2954 NO_STR
2955 ZEBRA_STR
2956 "Zebra dataplane\n"
2957 "Limit incoming queued updates\n"
2958 "Number of queued updates\n")
2959 {
2960 dplane_set_in_queue_limit(0, false);
2961
2962 return CMD_SUCCESS;
2963 }
2964
2965 DEFUN (zebra_show_routing_tables_summary,
2966 zebra_show_routing_tables_summary_cmd,
2967 "show zebra router table summary",
2968 SHOW_STR
2969 ZEBRA_STR
2970 "The Zebra Router Information\n"
2971 "Table Information about this Zebra Router\n"
2972 "Summary Information\n")
2973 {
2974 zebra_router_show_table_summary(vty);
2975
2976 return CMD_SUCCESS;
2977 }
2978
2979 /* Table configuration write function. */
2980 static int config_write_table(struct vty *vty)
2981 {
2982 return 0;
2983 }
2984
2985 /* IPForwarding configuration write function. */
2986 static int config_write_forwarding(struct vty *vty)
2987 {
2988 /* FIXME: Find better place for that. */
2989 router_id_write(vty);
2990
2991 if (!ipforward())
2992 vty_out(vty, "no ip forwarding\n");
2993 if (!ipforward_ipv6())
2994 vty_out(vty, "no ipv6 forwarding\n");
2995 vty_out(vty, "!\n");
2996 return 0;
2997 }
2998
2999 DEFUN_HIDDEN (show_frr,
3000 show_frr_cmd,
3001 "show frr",
3002 SHOW_STR
3003 "FRR\n")
3004 {
3005 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
3006 vty_out(vty, ".............................7777:..............................................\n");
3007 vty_out(vty, ".............................777777,............................................\n");
3008 vty_out(vty, "... .........................77777777,..........................................\n");
3009 vty_out(vty, "............................=7777777777:........................................\n");
3010 vty_out(vty, "........................:7777777777777777,......................................\n");
3011 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
3012 vty_out(vty, "...................I7777777777+.................................................\n");
3013 vty_out(vty, "................,777777777?............ .......................................\n");
3014 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
3015 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
3016 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
3017 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
3018 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
3019 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3020 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3021 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3022 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3023 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3024 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3025 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3026 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3027 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3028 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3029 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3030 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3031 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3032 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3033 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3034 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3035 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3036 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3037 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
3038 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3039 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3040 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3041 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3042 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3043 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3044 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3045 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
3046 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
3047 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
3048 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
3049 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
3050 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
3051 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
3052 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
3053 vty_out(vty, "............................~777777777777..............+777777..................\n");
3054 vty_out(vty, "................................~77777777...............=777777.................\n");
3055 vty_out(vty, ".....................................:=?I................~777777................\n");
3056 vty_out(vty, "..........................................................:777777,..............\n");
3057 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3058
3059 return CMD_SUCCESS;
3060 }
3061
3062 /* IP node for static routes. */
3063 static struct cmd_node ip_node = {IP_NODE, "", 1};
3064 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
3065 /* table node for routing tables. */
3066 static struct cmd_node table_node = {TABLE_NODE,
3067 "", /* This node has no interface. */
3068 1};
3069 static struct cmd_node forwarding_node = {FORWARDING_NODE,
3070 "", /* This node has no interface. */
3071 1};
3072
3073 /* Route VTY. */
3074 void zebra_vty_init(void)
3075 {
3076 /* Install configuration write function. */
3077 install_node(&table_node, config_write_table);
3078 install_node(&forwarding_node, config_write_forwarding);
3079
3080 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3081 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3082 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3083 install_element(ENABLE_NODE, &show_zebra_cmd);
3084
3085 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3086 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3087 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3088
3089 /* Route-map */
3090 zebra_route_map_init();
3091
3092 install_node(&ip_node, zebra_ip_config);
3093 install_node(&protocol_node, config_write_protocol);
3094
3095 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3096 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
3097
3098 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3099 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
3100
3101 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3102 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3103 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3104 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
3105 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3106 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
3107
3108 install_element(VIEW_NODE, &show_nexthop_group_cmd);
3109
3110 install_element(VIEW_NODE, &show_vrf_cmd);
3111 install_element(VIEW_NODE, &show_vrf_vni_cmd);
3112 install_element(VIEW_NODE, &show_route_cmd);
3113 install_element(VIEW_NODE, &show_route_table_cmd);
3114 if (vrf_is_backend_netns())
3115 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
3116 install_element(VIEW_NODE, &show_route_all_table_vrf_cmd);
3117 install_element(VIEW_NODE, &show_route_detail_cmd);
3118 install_element(VIEW_NODE, &show_route_summary_cmd);
3119 install_element(VIEW_NODE, &show_ip_nht_cmd);
3120
3121 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3122 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3123
3124 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3125 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3126 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3127 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
3128 install_element(VRF_NODE, &ip_nht_default_route_cmd);
3129 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
3130 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
3131 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
3132 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3133
3134 /* Commands for VRF */
3135 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3136
3137 install_element(VIEW_NODE, &show_frr_cmd);
3138 install_element(VIEW_NODE, &show_evpn_global_cmd);
3139 install_element(VIEW_NODE, &show_evpn_vni_cmd);
3140 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
3141 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
3142 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3143 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3144 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3145 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3146 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3147 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
3148 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3149 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
3150 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
3151 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3152 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3153 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
3154 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
3155 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
3156 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3157 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
3158 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
3159 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3160 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
3161 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
3162 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
3163 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
3164
3165 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3166 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3167
3168 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3169 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
3170 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3171 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
3172
3173 install_element(VIEW_NODE, &show_dataplane_cmd);
3174 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
3175 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
3176 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
3177
3178 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
3179 }