]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
zebra: Abstract the RB nodes/add dependents tree
[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, afi_t afi)
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 struct nhg_connected *rb_node_dep = NULL;
1115
1116 if (afi && nhe->afi != afi)
1117 continue;
1118
1119 if (nhe->vrf_id != zvrf->vrf->vrf_id)
1120 continue;
1121
1122 vty_out(vty, "Group: %u ID: %u\n", nhe->dplane_ref, nhe->id);
1123 vty_out(vty, "\tRefCnt: %d\n", nhe->refcnt);
1124 vty_out(vty, "\tValid: %d, Installed %d\n",
1125 nhe->flags & NEXTHOP_GROUP_VALID,
1126 nhe->flags & NEXTHOP_GROUP_INSTALLED);
1127 if (nhe->ifp)
1128 vty_out(vty, "\tInterface Index: %d\n",
1129 nhe->ifp->ifindex);
1130
1131 if (!zebra_nhg_depends_is_empty(nhe)) {
1132
1133 vty_out(vty, "\tDepends:");
1134 RB_FOREACH (rb_node_dep, nhg_connected_head,
1135 &nhe->nhg_depends) {
1136 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
1137 }
1138 vty_out(vty, "\n");
1139
1140 } else {
1141 vty_out(vty, "\tDependents:");
1142 RB_FOREACH (rb_node_dep, nhg_connected_head,
1143 &nhe->nhg_dependents) {
1144 vty_out(vty, " (%u)", rb_node_dep->nhe->id);
1145 }
1146 vty_out(vty, "\n");
1147 }
1148
1149 for (ALL_NEXTHOPS_PTR(nhe->nhg, nhop)) {
1150 vty_out(vty, "\t");
1151 nexthop_group_write_nexthop(vty, nhop);
1152 }
1153 }
1154
1155 list_delete(&list);
1156 }
1157
1158 DEFPY (show_nexthop_group,
1159 show_nexthop_group_cmd,
1160 "show nexthop-group [<ipv4$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]",
1161 SHOW_STR
1162 IP_STR
1163 IP6_STR
1164 "Show Nexthop Groups\n"
1165 VRF_FULL_CMD_HELP_STR)
1166 {
1167
1168 afi_t afi = 0;
1169 if (v4)
1170 afi = AFI_IP;
1171 else if (v6)
1172 afi = AFI_IP6;
1173
1174 struct zebra_vrf *zvrf;
1175
1176 if (vrf_all) {
1177 struct vrf *vrf;
1178
1179 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1180 struct zebra_vrf *zvrf;
1181
1182 zvrf = vrf->info;
1183 if (!zvrf)
1184 continue;
1185
1186 vty_out(vty, "VRF: %s\n", vrf->name);
1187 show_nexthop_group_cmd_helper(vty, zvrf, afi);
1188 }
1189
1190 return CMD_SUCCESS;
1191 }
1192
1193 if (vrf_name)
1194 zvrf = zebra_vrf_lookup_by_name(vrf_name);
1195 else
1196 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
1197
1198 if (!zvrf) {
1199 vty_out(vty, "VRF %s specified does not exist", vrf_name);
1200 return CMD_SUCCESS;
1201 }
1202
1203 show_nexthop_group_cmd_helper(vty, zvrf, afi);
1204
1205 return CMD_SUCCESS;
1206 }
1207
1208 DEFUN (no_ip_nht_default_route,
1209 no_ip_nht_default_route_cmd,
1210 "no ip nht resolve-via-default",
1211 NO_STR
1212 IP_STR
1213 "Filter Next Hop tracking route resolution\n"
1214 "Resolve via default route\n")
1215 {
1216 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1217
1218 if (!zvrf)
1219 return CMD_WARNING;
1220
1221 if (!zvrf->zebra_rnh_ip_default_route)
1222 return CMD_SUCCESS;
1223
1224 zvrf->zebra_rnh_ip_default_route = 0;
1225 zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
1226 return CMD_SUCCESS;
1227 }
1228
1229 DEFUN (ipv6_nht_default_route,
1230 ipv6_nht_default_route_cmd,
1231 "ipv6 nht resolve-via-default",
1232 IP6_STR
1233 "Filter Next Hop tracking route resolution\n"
1234 "Resolve via default route\n")
1235 {
1236 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1237
1238 if (!zvrf)
1239 return CMD_WARNING;
1240
1241 if (zvrf->zebra_rnh_ipv6_default_route)
1242 return CMD_SUCCESS;
1243
1244 zvrf->zebra_rnh_ipv6_default_route = 1;
1245 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
1246 return CMD_SUCCESS;
1247 }
1248
1249 DEFUN (no_ipv6_nht_default_route,
1250 no_ipv6_nht_default_route_cmd,
1251 "no ipv6 nht resolve-via-default",
1252 NO_STR
1253 IP6_STR
1254 "Filter Next Hop tracking route resolution\n"
1255 "Resolve via default route\n")
1256 {
1257
1258 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1259
1260 if (!zvrf)
1261 return CMD_WARNING;
1262
1263 if (!zvrf->zebra_rnh_ipv6_default_route)
1264 return CMD_SUCCESS;
1265
1266 zvrf->zebra_rnh_ipv6_default_route = 0;
1267 zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
1268 return CMD_SUCCESS;
1269 }
1270
1271 DEFPY (show_route,
1272 show_route_cmd,
1273 "show\
1274 <\
1275 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1276 [{\
1277 tag (1-4294967295)\
1278 |A.B.C.D/M$prefix longer-prefixes\
1279 |supernets-only$supernets_only\
1280 }]\
1281 [<\
1282 " FRR_IP_REDIST_STR_ZEBRA "$type_str\
1283 |ospf$type_str (1-65535)$ospf_instance_id\
1284 >]\
1285 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1286 [{\
1287 tag (1-4294967295)\
1288 |X:X::X:X/M$prefix longer-prefixes\
1289 }]\
1290 [" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
1291 >\
1292 [json$json]",
1293 SHOW_STR
1294 IP_STR
1295 "IP forwarding table\n"
1296 "IP routing table\n"
1297 VRF_FULL_CMD_HELP_STR
1298 "Show only routes with tag\n"
1299 "Tag value\n"
1300 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1301 "Show route matching the specified Network/Mask pair only\n"
1302 "Show supernet entries only\n"
1303 FRR_IP_REDIST_HELP_STR_ZEBRA
1304 "Open Shortest Path First (OSPFv2)\n"
1305 "Instance ID\n"
1306 IPV6_STR
1307 "IP forwarding table\n"
1308 "IP routing table\n"
1309 VRF_FULL_CMD_HELP_STR
1310 "Show only routes with tag\n"
1311 "Tag value\n"
1312 "IPv6 prefix\n"
1313 "Show route matching the specified Network/Mask pair only\n"
1314 FRR_IP6_REDIST_HELP_STR_ZEBRA
1315 JSON_STR)
1316 {
1317 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1318 struct vrf *vrf;
1319 int type = 0;
1320
1321 if (type_str) {
1322 type = proto_redistnum(afi, type_str);
1323 if (type < 0) {
1324 vty_out(vty, "Unknown route type\n");
1325 return CMD_WARNING;
1326 }
1327 }
1328
1329 if (vrf_all) {
1330 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1331 struct zebra_vrf *zvrf;
1332 struct route_table *table;
1333
1334 if ((zvrf = vrf->info) == NULL
1335 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1336 continue;
1337
1338 do_show_ip_route(
1339 vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
1340 !!json, tag, prefix_str ? prefix : NULL,
1341 !!supernets_only, type, ospf_instance_id);
1342 }
1343 } else {
1344 vrf_id_t vrf_id = VRF_DEFAULT;
1345
1346 if (vrf_name)
1347 VRF_GET_ID(vrf_id, vrf_name, !!json);
1348 vrf = vrf_lookup_by_id(vrf_id);
1349 do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
1350 !!json, tag, prefix_str ? prefix : NULL,
1351 !!supernets_only, type, ospf_instance_id);
1352 }
1353
1354 return CMD_SUCCESS;
1355 }
1356
1357 DEFPY (show_route_detail,
1358 show_route_detail_cmd,
1359 "show\
1360 <\
1361 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1362 <\
1363 A.B.C.D$address\
1364 |A.B.C.D/M$prefix\
1365 >\
1366 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1367 <\
1368 X:X::X:X$address\
1369 |X:X::X:X/M$prefix\
1370 >\
1371 >\
1372 [json$json]",
1373 SHOW_STR
1374 IP_STR
1375 "IPv6 forwarding table\n"
1376 "IP routing table\n"
1377 VRF_FULL_CMD_HELP_STR
1378 "Network in the IP routing table to display\n"
1379 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1380 IP6_STR
1381 "IPv6 forwarding table\n"
1382 "IPv6 routing table\n"
1383 VRF_FULL_CMD_HELP_STR
1384 "IPv6 Address\n"
1385 "IPv6 prefix\n"
1386 JSON_STR)
1387 {
1388 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1389 struct route_table *table;
1390 struct prefix p;
1391 struct route_node *rn;
1392 bool use_fib = !!fib;
1393 rib_dest_t *dest;
1394 bool network_found = false;
1395
1396 if (address_str)
1397 prefix_str = address_str;
1398 if (str2prefix(prefix_str, &p) < 0) {
1399 vty_out(vty, "%% Malformed address\n");
1400 return CMD_WARNING;
1401 }
1402
1403 if (vrf_all) {
1404 struct vrf *vrf;
1405 struct zebra_vrf *zvrf;
1406
1407 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1408 if ((zvrf = vrf->info) == NULL
1409 || (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
1410 continue;
1411
1412 rn = route_node_match(table, &p);
1413 if (!rn)
1414 continue;
1415 if (!address_str && rn->p.prefixlen != p.prefixlen) {
1416 route_unlock_node(rn);
1417 continue;
1418 }
1419
1420 dest = rib_dest_from_rnode(rn);
1421 if (use_fib && !dest->selected_fib) {
1422 route_unlock_node(rn);
1423 continue;
1424 }
1425
1426 network_found = true;
1427 if (json)
1428 vty_show_ip_route_detail_json(vty, rn,
1429 use_fib);
1430 else
1431 vty_show_ip_route_detail(vty, rn, 0, use_fib);
1432
1433 route_unlock_node(rn);
1434 }
1435
1436 if (!network_found) {
1437 if (json)
1438 vty_out(vty, "{}\n");
1439 else {
1440 if (use_fib)
1441 vty_out(vty,
1442 "%% Network not in FIB\n");
1443 else
1444 vty_out(vty,
1445 "%% Network not in RIB\n");
1446 }
1447 return CMD_WARNING;
1448 }
1449 } else {
1450 vrf_id_t vrf_id = VRF_DEFAULT;
1451
1452 if (vrf_name)
1453 VRF_GET_ID(vrf_id, vrf_name, false);
1454
1455 table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
1456 if (!table)
1457 return CMD_SUCCESS;
1458
1459 rn = route_node_match(table, &p);
1460 if (rn)
1461 dest = rib_dest_from_rnode(rn);
1462
1463 if (!rn || (!address_str && rn->p.prefixlen != p.prefixlen) ||
1464 (use_fib && dest && !dest->selected_fib)) {
1465 if (json)
1466 vty_out(vty, "{}\n");
1467 else {
1468 if (use_fib)
1469 vty_out(vty,
1470 "%% Network not in FIB\n");
1471 else
1472 vty_out(vty,
1473 "%% Network not in table\n");
1474 }
1475 if (rn)
1476 route_unlock_node(rn);
1477 return CMD_WARNING;
1478 }
1479
1480 if (json)
1481 vty_show_ip_route_detail_json(vty, rn, use_fib);
1482 else
1483 vty_show_ip_route_detail(vty, rn, 0, use_fib);
1484
1485 route_unlock_node(rn);
1486 }
1487
1488 return CMD_SUCCESS;
1489 }
1490
1491 DEFPY (show_route_summary,
1492 show_route_summary_cmd,
1493 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1494 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1495 SHOW_STR
1496 IP_STR
1497 IP6_STR
1498 "IP routing table\n"
1499 VRF_FULL_CMD_HELP_STR
1500 "Summary of all routes\n"
1501 "Table to display summary for\n"
1502 "The table number\n"
1503 "Prefix routes\n")
1504 {
1505 afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
1506 struct route_table *table;
1507
1508 if (table_id == 0)
1509 table_id = RT_TABLE_MAIN;
1510
1511 if (vrf_all) {
1512 struct vrf *vrf;
1513 struct zebra_vrf *zvrf;
1514
1515 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1516 if ((zvrf = vrf->info) == NULL)
1517 continue;
1518
1519 table = zebra_vrf_table_with_table_id(afi,
1520 SAFI_UNICAST,
1521 zvrf->vrf->vrf_id,
1522 table_id);
1523 if (!table)
1524 continue;
1525
1526 if (prefix)
1527 vty_show_ip_route_summary_prefix(vty, table);
1528 else
1529 vty_show_ip_route_summary(vty, table);
1530 }
1531 } else {
1532 vrf_id_t vrf_id = VRF_DEFAULT;
1533
1534 if (vrf_name)
1535 VRF_GET_ID(vrf_id, vrf_name, false);
1536
1537 table = zebra_vrf_table_with_table_id(afi,
1538 SAFI_UNICAST,
1539 vrf_id, table_id);
1540 if (!table)
1541 return CMD_SUCCESS;
1542
1543 if (prefix)
1544 vty_show_ip_route_summary_prefix(vty, table);
1545 else
1546 vty_show_ip_route_summary(vty, table);
1547 }
1548
1549 return CMD_SUCCESS;
1550 }
1551
1552 static void vty_show_ip_route_summary(struct vty *vty,
1553 struct route_table *table)
1554 {
1555 struct route_node *rn;
1556 struct route_entry *re;
1557 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1558 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1559 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1560 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1561 uint32_t i;
1562 uint32_t is_ibgp;
1563
1564 memset(&rib_cnt, 0, sizeof(rib_cnt));
1565 memset(&fib_cnt, 0, sizeof(fib_cnt));
1566 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1567 RNODE_FOREACH_RE (rn, re) {
1568 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1569 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1570
1571 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1572 if (is_ibgp)
1573 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1574 else
1575 rib_cnt[re->type]++;
1576
1577 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1578 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1579
1580 if (is_ibgp)
1581 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1582 else
1583 fib_cnt[re->type]++;
1584 }
1585 }
1586
1587 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1588 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1589
1590 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1591 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1592 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1593 if (i == ZEBRA_ROUTE_BGP) {
1594 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1595 rib_cnt[ZEBRA_ROUTE_BGP],
1596 fib_cnt[ZEBRA_ROUTE_BGP]);
1597 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1598 rib_cnt[ZEBRA_ROUTE_IBGP],
1599 fib_cnt[ZEBRA_ROUTE_IBGP]);
1600 } else
1601 vty_out(vty, "%-20s %-20d %-20d \n",
1602 zebra_route_string(i), rib_cnt[i],
1603 fib_cnt[i]);
1604 }
1605 }
1606
1607 vty_out(vty, "------\n");
1608 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1609 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1610 vty_out(vty, "\n");
1611 }
1612
1613 /*
1614 * Implementation of the ip route summary prefix command.
1615 *
1616 * This command prints the primary prefixes that have been installed by various
1617 * protocols on the box.
1618 *
1619 */
1620 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1621 struct route_table *table)
1622 {
1623 struct route_node *rn;
1624 struct route_entry *re;
1625 struct nexthop *nexthop;
1626 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1627 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1628 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1629 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1630 uint32_t i;
1631 int cnt;
1632
1633 memset(&rib_cnt, 0, sizeof(rib_cnt));
1634 memset(&fib_cnt, 0, sizeof(fib_cnt));
1635 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1636 RNODE_FOREACH_RE (rn, re) {
1637
1638 /*
1639 * In case of ECMP, count only once.
1640 */
1641 cnt = 0;
1642 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1643 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1644 fib_cnt[re->type]++;
1645 }
1646 for (nexthop = re->ng->nexthop; (!cnt && nexthop);
1647 nexthop = nexthop->next) {
1648 cnt++;
1649 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1650 rib_cnt[re->type]++;
1651 if (re->type == ZEBRA_ROUTE_BGP
1652 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1653 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1654 if (CHECK_FLAG(re->status,
1655 ROUTE_ENTRY_INSTALLED))
1656 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1657 }
1658 }
1659 }
1660
1661 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1662 "Prefix Routes", "FIB",
1663 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1664
1665 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1666 if (rib_cnt[i] > 0) {
1667 if (i == ZEBRA_ROUTE_BGP) {
1668 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1669 rib_cnt[ZEBRA_ROUTE_BGP]
1670 - rib_cnt[ZEBRA_ROUTE_IBGP],
1671 fib_cnt[ZEBRA_ROUTE_BGP]
1672 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1673 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1674 rib_cnt[ZEBRA_ROUTE_IBGP],
1675 fib_cnt[ZEBRA_ROUTE_IBGP]);
1676 } else
1677 vty_out(vty, "%-20s %-20d %-20d \n",
1678 zebra_route_string(i), rib_cnt[i],
1679 fib_cnt[i]);
1680 }
1681 }
1682
1683 vty_out(vty, "------\n");
1684 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1685 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1686 vty_out(vty, "\n");
1687 }
1688
1689 /*
1690 * Show IPv6 mroute command.Used to dump
1691 * the Multicast routing table.
1692 */
1693 DEFUN (show_ipv6_mroute,
1694 show_ipv6_mroute_cmd,
1695 "show ipv6 mroute [vrf NAME]",
1696 SHOW_STR
1697 IP_STR
1698 "IPv6 Multicast routing table\n"
1699 VRF_CMD_HELP_STR)
1700 {
1701 struct route_table *table;
1702 struct route_node *rn;
1703 struct route_entry *re;
1704 int first = 1;
1705 vrf_id_t vrf_id = VRF_DEFAULT;
1706
1707 if (argc == 5)
1708 VRF_GET_ID(vrf_id, argv[4]->arg, false);
1709
1710 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1711 if (!table)
1712 return CMD_SUCCESS;
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 return CMD_SUCCESS;
1724 }
1725
1726 DEFUN (show_ipv6_mroute_vrf_all,
1727 show_ipv6_mroute_vrf_all_cmd,
1728 "show ipv6 mroute vrf all",
1729 SHOW_STR
1730 IP_STR
1731 "IPv6 Multicast routing table\n"
1732 VRF_ALL_CMD_HELP_STR)
1733 {
1734 struct route_table *table;
1735 struct route_node *rn;
1736 struct route_entry *re;
1737 struct vrf *vrf;
1738 struct zebra_vrf *zvrf;
1739 int first = 1;
1740
1741 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1742 if ((zvrf = vrf->info) == NULL
1743 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1744 continue;
1745
1746 /* Show all IPv6 route. */
1747 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1748 RNODE_FOREACH_RE (rn, re) {
1749 if (first) {
1750 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1751 first = 0;
1752 }
1753 vty_show_ip_route(vty, rn, re, NULL, false);
1754 }
1755 }
1756 return CMD_SUCCESS;
1757 }
1758
1759 DEFUN (allow_external_route_update,
1760 allow_external_route_update_cmd,
1761 "allow-external-route-update",
1762 "Allow FRR routes to be overwritten by external processes\n")
1763 {
1764 allow_delete = 1;
1765
1766 return CMD_SUCCESS;
1767 }
1768
1769 DEFUN (no_allow_external_route_update,
1770 no_allow_external_route_update_cmd,
1771 "no allow-external-route-update",
1772 NO_STR
1773 "Allow FRR routes to be overwritten by external processes\n")
1774 {
1775 allow_delete = 0;
1776
1777 return CMD_SUCCESS;
1778 }
1779
1780 /* show vrf */
1781 DEFUN (show_vrf,
1782 show_vrf_cmd,
1783 "show vrf",
1784 SHOW_STR
1785 "VRF\n")
1786 {
1787 struct vrf *vrf;
1788 struct zebra_vrf *zvrf;
1789
1790 if (vrf_is_backend_netns())
1791 vty_out(vty, "netns-based vrfs\n");
1792
1793 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1794 if (!(zvrf = vrf->info))
1795 continue;
1796 if (zvrf_id(zvrf) == VRF_DEFAULT)
1797 continue;
1798
1799 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
1800 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
1801 vty_out(vty, "inactive");
1802 else if (zvrf_ns_name(zvrf))
1803 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1804 zvrf_ns_name(zvrf));
1805 else
1806 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1807 zvrf->table_id);
1808 if (vrf_is_user_cfged(vrf))
1809 vty_out(vty, " (configured)");
1810 vty_out(vty, "\n");
1811 }
1812
1813 return CMD_SUCCESS;
1814 }
1815
1816 DEFUN (default_vrf_vni_mapping,
1817 default_vrf_vni_mapping_cmd,
1818 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1819 "VNI corresponding to the DEFAULT VRF\n"
1820 "VNI-ID\n"
1821 "Prefix routes only \n")
1822 {
1823 int ret = 0;
1824 char err[ERR_STR_SZ];
1825 struct zebra_vrf *zvrf = NULL;
1826 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1827 int filter = 0;
1828
1829 zvrf = vrf_info_lookup(VRF_DEFAULT);
1830 if (!zvrf)
1831 return CMD_WARNING;
1832
1833 if (argc == 3)
1834 filter = 1;
1835
1836 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1837 filter, 1);
1838 if (ret != 0) {
1839 vty_out(vty, "%s\n", err);
1840 return CMD_WARNING;
1841 }
1842
1843 return CMD_SUCCESS;
1844 }
1845
1846 DEFUN (no_default_vrf_vni_mapping,
1847 no_default_vrf_vni_mapping_cmd,
1848 "no vni " CMD_VNI_RANGE,
1849 NO_STR
1850 "VNI corresponding to DEFAULT VRF\n"
1851 "VNI-ID")
1852 {
1853 int ret = 0;
1854 char err[ERR_STR_SZ];
1855 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1856 struct zebra_vrf *zvrf = NULL;
1857
1858 zvrf = vrf_info_lookup(VRF_DEFAULT);
1859 if (!zvrf)
1860 return CMD_WARNING;
1861
1862 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
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 (vrf_vni_mapping,
1872 vrf_vni_mapping_cmd,
1873 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
1874 "VNI corresponding to tenant VRF\n"
1875 "VNI-ID\n"
1876 "prefix-routes-only\n")
1877 {
1878 int ret = 0;
1879 int filter = 0;
1880
1881 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1882 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
1883 char err[ERR_STR_SZ];
1884
1885 assert(vrf);
1886 assert(zvrf);
1887
1888 if (argc == 3)
1889 filter = 1;
1890
1891 /* Mark as having FRR configuration */
1892 vrf_set_user_cfged(vrf);
1893 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
1894 filter, 1);
1895 if (ret != 0) {
1896 vty_out(vty, "%s\n", err);
1897 return CMD_WARNING;
1898 }
1899
1900 return CMD_SUCCESS;
1901 }
1902
1903 DEFUN (no_vrf_vni_mapping,
1904 no_vrf_vni_mapping_cmd,
1905 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
1906 NO_STR
1907 "VNI corresponding to tenant VRF\n"
1908 "VNI-ID\n"
1909 "prefix-routes-only\n")
1910 {
1911 int ret = 0;
1912 int filter = 0;
1913 char err[ERR_STR_SZ];
1914 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
1915
1916 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
1917
1918 assert(vrf);
1919 assert(zvrf);
1920
1921 if (argc == 4)
1922 filter = 1;
1923
1924 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
1925 ERR_STR_SZ, filter, 0);
1926 if (ret != 0) {
1927 vty_out(vty, "%s\n", err);
1928 return CMD_WARNING;
1929 }
1930
1931 /* If no other FRR config for this VRF, mark accordingly. */
1932 if (!zebra_vrf_has_config(zvrf))
1933 vrf_reset_user_cfged(vrf);
1934
1935 return CMD_SUCCESS;
1936 }
1937
1938 /* show vrf */
1939 DEFUN (show_vrf_vni,
1940 show_vrf_vni_cmd,
1941 "show vrf vni [json]",
1942 SHOW_STR
1943 "VRF\n"
1944 "VNI\n"
1945 JSON_STR)
1946 {
1947 struct vrf *vrf;
1948 struct zebra_vrf *zvrf;
1949 json_object *json = NULL;
1950 json_object *json_vrfs = NULL;
1951 bool uj = use_json(argc, argv);
1952
1953 if (uj) {
1954 json = json_object_new_object();
1955 json_vrfs = json_object_new_array();
1956 }
1957
1958 if (!uj)
1959 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1960 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1961
1962 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1963 zvrf = vrf->info;
1964 if (!zvrf)
1965 continue;
1966
1967 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
1968 }
1969
1970 if (uj) {
1971 json_object_object_add(json, "vrfs", json_vrfs);
1972 vty_out(vty, "%s\n", json_object_to_json_string_ext(
1973 json, JSON_C_TO_STRING_PRETTY));
1974 json_object_free(json);
1975 }
1976
1977 return CMD_SUCCESS;
1978 }
1979
1980 DEFUN (show_evpn_global,
1981 show_evpn_global_cmd,
1982 "show evpn [json]",
1983 SHOW_STR
1984 "EVPN\n"
1985 JSON_STR)
1986 {
1987 bool uj = use_json(argc, argv);
1988
1989 zebra_vxlan_print_evpn(vty, uj);
1990 return CMD_SUCCESS;
1991 }
1992
1993 DEFUN (show_evpn_vni,
1994 show_evpn_vni_cmd,
1995 "show evpn vni [json]",
1996 SHOW_STR
1997 "EVPN\n"
1998 "VxLAN Network Identifier\n"
1999 JSON_STR)
2000 {
2001 struct zebra_vrf *zvrf;
2002 bool uj = use_json(argc, argv);
2003
2004 zvrf = zebra_vrf_get_evpn();
2005 zebra_vxlan_print_vnis(vty, zvrf, uj);
2006 return CMD_SUCCESS;
2007 }
2008
2009 DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
2010 "show evpn vni detail [json]",
2011 SHOW_STR
2012 "EVPN\n"
2013 "VxLAN Network Identifier\n"
2014 "Detailed Information On Each VNI\n"
2015 JSON_STR)
2016 {
2017 struct zebra_vrf *zvrf;
2018 bool uj = use_json(argc, argv);
2019
2020 zvrf = zebra_vrf_get_evpn();
2021 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
2022 return CMD_SUCCESS;
2023 }
2024
2025 DEFUN (show_evpn_vni_vni,
2026 show_evpn_vni_vni_cmd,
2027 "show evpn vni " CMD_VNI_RANGE "[json]",
2028 SHOW_STR
2029 "EVPN\n"
2030 "VxLAN Network Identifier\n"
2031 "VNI number\n"
2032 JSON_STR)
2033 {
2034 struct zebra_vrf *zvrf;
2035 vni_t vni;
2036 bool uj = use_json(argc, argv);
2037
2038 vni = strtoul(argv[3]->arg, NULL, 10);
2039 zvrf = zebra_vrf_get_evpn();
2040 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
2041 return CMD_SUCCESS;
2042 }
2043
2044 DEFUN (show_evpn_rmac_vni_mac,
2045 show_evpn_rmac_vni_mac_cmd,
2046 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
2047 SHOW_STR
2048 "EVPN\n"
2049 "RMAC\n"
2050 "L3 VNI\n"
2051 "VNI number\n"
2052 "MAC\n"
2053 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2054 JSON_STR)
2055 {
2056 vni_t l3vni = 0;
2057 struct ethaddr mac;
2058 bool uj = use_json(argc, argv);
2059
2060 l3vni = strtoul(argv[4]->arg, NULL, 10);
2061 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2062 vty_out(vty, "%% Malformed MAC address\n");
2063 return CMD_WARNING;
2064 }
2065 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
2066 return CMD_SUCCESS;
2067 }
2068
2069 DEFUN (show_evpn_rmac_vni,
2070 show_evpn_rmac_vni_cmd,
2071 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
2072 SHOW_STR
2073 "EVPN\n"
2074 "RMAC\n"
2075 "L3 VNI\n"
2076 "VNI number\n"
2077 JSON_STR)
2078 {
2079 vni_t l3vni = 0;
2080 bool uj = use_json(argc, argv);
2081
2082 l3vni = strtoul(argv[4]->arg, NULL, 10);
2083 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2084
2085 return CMD_SUCCESS;
2086 }
2087
2088 DEFUN (show_evpn_rmac_vni_all,
2089 show_evpn_rmac_vni_all_cmd,
2090 "show evpn rmac vni all [json]",
2091 SHOW_STR
2092 "EVPN\n"
2093 "RMAC addresses\n"
2094 "L3 VNI\n"
2095 "All VNIs\n"
2096 JSON_STR)
2097 {
2098 bool uj = use_json(argc, argv);
2099
2100 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2101
2102 return CMD_SUCCESS;
2103 }
2104
2105 DEFUN (show_evpn_nh_vni_ip,
2106 show_evpn_nh_vni_ip_cmd,
2107 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
2108 SHOW_STR
2109 "EVPN\n"
2110 "Remote Vteps\n"
2111 "L3 VNI\n"
2112 "VNI number\n"
2113 "Ip address\n"
2114 "Host address (ipv4 or ipv6)\n"
2115 JSON_STR)
2116 {
2117 vni_t l3vni;
2118 struct ipaddr ip;
2119 bool uj = use_json(argc, argv);
2120
2121 l3vni = strtoul(argv[4]->arg, NULL, 10);
2122 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2123 if (!uj)
2124 vty_out(vty, "%% Malformed Neighbor address\n");
2125 return CMD_WARNING;
2126 }
2127 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
2128
2129 return CMD_SUCCESS;
2130 }
2131
2132 DEFUN (show_evpn_nh_vni,
2133 show_evpn_nh_vni_cmd,
2134 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
2135 SHOW_STR
2136 "EVPN\n"
2137 "Remote Vteps\n"
2138 "L3 VNI\n"
2139 "VNI number\n"
2140 JSON_STR)
2141 {
2142 vni_t l3vni;
2143 bool uj = use_json(argc, argv);
2144
2145 l3vni = strtoul(argv[4]->arg, NULL, 10);
2146 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2147
2148 return CMD_SUCCESS;
2149 }
2150
2151 DEFUN (show_evpn_nh_vni_all,
2152 show_evpn_nh_vni_all_cmd,
2153 "show evpn next-hops vni all [json]",
2154 SHOW_STR
2155 "EVPN\n"
2156 "Remote VTEPs\n"
2157 "L3 VNI\n"
2158 "All VNIs\n"
2159 JSON_STR)
2160 {
2161 bool uj = use_json(argc, argv);
2162
2163 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2164
2165 return CMD_SUCCESS;
2166 }
2167
2168 DEFUN (show_evpn_mac_vni,
2169 show_evpn_mac_vni_cmd,
2170 "show evpn mac vni " CMD_VNI_RANGE "[json]",
2171 SHOW_STR
2172 "EVPN\n"
2173 "MAC addresses\n"
2174 "VxLAN Network Identifier\n"
2175 "VNI number\n"
2176 JSON_STR)
2177 {
2178 struct zebra_vrf *zvrf;
2179 vni_t vni;
2180 bool uj = use_json(argc, argv);
2181
2182 vni = strtoul(argv[4]->arg, NULL, 10);
2183 zvrf = zebra_vrf_get_evpn();
2184 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
2185 return CMD_SUCCESS;
2186 }
2187
2188 DEFUN (show_evpn_mac_vni_all,
2189 show_evpn_mac_vni_all_cmd,
2190 "show evpn mac vni all [json]",
2191 SHOW_STR
2192 "EVPN\n"
2193 "MAC addresses\n"
2194 "VxLAN Network Identifier\n"
2195 "All VNIs\n"
2196 JSON_STR)
2197 {
2198 struct zebra_vrf *zvrf;
2199 bool uj = use_json(argc, argv);
2200
2201 zvrf = zebra_vrf_get_evpn();
2202 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
2203 return CMD_SUCCESS;
2204 }
2205
2206 DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
2207 "show evpn mac vni all detail [json]",
2208 SHOW_STR
2209 "EVPN\n"
2210 "MAC addresses\n"
2211 "VxLAN Network Identifier\n"
2212 "All VNIs\n"
2213 "Detailed Information On Each VNI MAC\n"
2214 JSON_STR)
2215 {
2216 struct zebra_vrf *zvrf;
2217 bool uj = use_json(argc, argv);
2218
2219 zvrf = zebra_vrf_get_evpn();
2220 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
2221 return CMD_SUCCESS;
2222 }
2223
2224 DEFUN (show_evpn_mac_vni_all_vtep,
2225 show_evpn_mac_vni_all_vtep_cmd,
2226 "show evpn mac vni all vtep A.B.C.D [json]",
2227 SHOW_STR
2228 "EVPN\n"
2229 "MAC addresses\n"
2230 "VxLAN Network Identifier\n"
2231 "All VNIs\n"
2232 "Remote VTEP\n"
2233 "Remote VTEP IP address\n"
2234 JSON_STR)
2235 {
2236 struct zebra_vrf *zvrf;
2237 struct in_addr vtep_ip;
2238 bool uj = use_json(argc, argv);
2239
2240 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2241 if (!uj)
2242 vty_out(vty, "%% Malformed VTEP IP address\n");
2243 return CMD_WARNING;
2244 }
2245 zvrf = zebra_vrf_get_evpn();
2246 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2247
2248 return CMD_SUCCESS;
2249 }
2250
2251
2252 DEFUN (show_evpn_mac_vni_mac,
2253 show_evpn_mac_vni_mac_cmd,
2254 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
2255 SHOW_STR
2256 "EVPN\n"
2257 "MAC addresses\n"
2258 "VxLAN Network Identifier\n"
2259 "VNI number\n"
2260 "MAC\n"
2261 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2262 JSON_STR)
2263
2264 {
2265 struct zebra_vrf *zvrf;
2266 vni_t vni;
2267 struct ethaddr mac;
2268 bool uj = use_json(argc, argv);
2269
2270 vni = strtoul(argv[4]->arg, NULL, 10);
2271 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2272 vty_out(vty, "%% Malformed MAC address");
2273 return CMD_WARNING;
2274 }
2275 zvrf = zebra_vrf_get_evpn();
2276 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
2277 return CMD_SUCCESS;
2278 }
2279
2280 DEFUN (show_evpn_mac_vni_vtep,
2281 show_evpn_mac_vni_vtep_cmd,
2282 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
2283 SHOW_STR
2284 "EVPN\n"
2285 "MAC addresses\n"
2286 "VxLAN Network Identifier\n"
2287 "VNI number\n"
2288 "Remote VTEP\n"
2289 "Remote VTEP IP address\n"
2290 JSON_STR)
2291 {
2292 struct zebra_vrf *zvrf;
2293 vni_t vni;
2294 struct in_addr vtep_ip;
2295 bool uj = use_json(argc, argv);
2296
2297 vni = strtoul(argv[4]->arg, NULL, 10);
2298 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2299 if (!uj)
2300 vty_out(vty, "%% Malformed VTEP IP address\n");
2301 return CMD_WARNING;
2302 }
2303
2304 zvrf = zebra_vrf_get_evpn();
2305 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2306 return CMD_SUCCESS;
2307 }
2308
2309 DEFPY (show_evpn_mac_vni_all_dad,
2310 show_evpn_mac_vni_all_dad_cmd,
2311 "show evpn mac vni all duplicate [json]",
2312 SHOW_STR
2313 "EVPN\n"
2314 "MAC addresses\n"
2315 "VxLAN Network Identifier\n"
2316 "All VNIs\n"
2317 "Duplicate address list\n"
2318 JSON_STR)
2319 {
2320 struct zebra_vrf *zvrf;
2321 bool uj = use_json(argc, argv);
2322
2323 zvrf = zebra_vrf_get_evpn();
2324 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2325 return CMD_SUCCESS;
2326 }
2327
2328
2329 DEFPY (show_evpn_mac_vni_dad,
2330 show_evpn_mac_vni_dad_cmd,
2331 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
2332 SHOW_STR
2333 "EVPN\n"
2334 "MAC addresses\n"
2335 "VxLAN Network Identifier\n"
2336 "VNI number\n"
2337 "Duplicate address list\n"
2338 JSON_STR)
2339 {
2340 struct zebra_vrf *zvrf;
2341 bool uj = use_json(argc, argv);
2342
2343 zvrf = zebra_vrf_get_evpn();
2344
2345 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2346
2347 return CMD_SUCCESS;
2348 }
2349
2350 DEFPY (show_evpn_neigh_vni_dad,
2351 show_evpn_neigh_vni_dad_cmd,
2352 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
2353 SHOW_STR
2354 "EVPN\n"
2355 "ARP and ND cache\n"
2356 "VxLAN Network Identifier\n"
2357 "VNI number\n"
2358 "Duplicate address list\n"
2359 JSON_STR)
2360 {
2361 struct zebra_vrf *zvrf;
2362 bool uj = use_json(argc, argv);
2363
2364 zvrf = zebra_vrf_get_evpn();
2365 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2366 return CMD_SUCCESS;
2367 }
2368
2369 DEFPY (show_evpn_neigh_vni_all_dad,
2370 show_evpn_neigh_vni_all_dad_cmd,
2371 "show evpn arp-cache vni all duplicate [json]",
2372 SHOW_STR
2373 "EVPN\n"
2374 "ARP and ND cache\n"
2375 "VxLAN Network Identifier\n"
2376 "All VNIs\n"
2377 "Duplicate address list\n"
2378 JSON_STR)
2379 {
2380 struct zebra_vrf *zvrf;
2381 bool uj = use_json(argc, argv);
2382
2383 zvrf = zebra_vrf_get_evpn();
2384 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2385 return CMD_SUCCESS;
2386 }
2387
2388
2389 DEFUN (show_evpn_neigh_vni,
2390 show_evpn_neigh_vni_cmd,
2391 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2392 SHOW_STR
2393 "EVPN\n"
2394 "ARP and ND cache\n"
2395 "VxLAN Network Identifier\n"
2396 "VNI number\n"
2397 JSON_STR)
2398 {
2399 struct zebra_vrf *zvrf;
2400 vni_t vni;
2401 bool uj = use_json(argc, argv);
2402
2403 vni = strtoul(argv[4]->arg, NULL, 10);
2404 zvrf = zebra_vrf_get_evpn();
2405 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2406 return CMD_SUCCESS;
2407 }
2408
2409 DEFUN (show_evpn_neigh_vni_all,
2410 show_evpn_neigh_vni_all_cmd,
2411 "show evpn arp-cache vni all [json]",
2412 SHOW_STR
2413 "EVPN\n"
2414 "ARP and ND cache\n"
2415 "VxLAN Network Identifier\n"
2416 "All VNIs\n"
2417 JSON_STR)
2418 {
2419 struct zebra_vrf *zvrf;
2420 bool uj = use_json(argc, argv);
2421
2422 zvrf = zebra_vrf_get_evpn();
2423 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
2424 return CMD_SUCCESS;
2425 }
2426
2427 DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
2428 "show evpn arp-cache vni all detail [json]",
2429 SHOW_STR
2430 "EVPN\n"
2431 "ARP and ND cache\n"
2432 "VxLAN Network Identifier\n"
2433 "All VNIs\n"
2434 "Neighbor details for all vnis in detail\n" JSON_STR)
2435 {
2436 struct zebra_vrf *zvrf;
2437 bool uj = use_json(argc, argv);
2438
2439 zvrf = zebra_vrf_get_evpn();
2440 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
2441 return CMD_SUCCESS;
2442 }
2443
2444 DEFUN (show_evpn_neigh_vni_neigh,
2445 show_evpn_neigh_vni_neigh_cmd,
2446 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2447 SHOW_STR
2448 "EVPN\n"
2449 "ARP and ND cache\n"
2450 "VxLAN Network Identifier\n"
2451 "VNI number\n"
2452 "Neighbor\n"
2453 "Neighbor address (IPv4 or IPv6 address)\n"
2454 JSON_STR)
2455 {
2456 struct zebra_vrf *zvrf;
2457 vni_t vni;
2458 struct ipaddr ip;
2459 bool uj = use_json(argc, argv);
2460
2461 vni = strtoul(argv[4]->arg, NULL, 10);
2462 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2463 if (!uj)
2464 vty_out(vty, "%% Malformed Neighbor address\n");
2465 return CMD_WARNING;
2466 }
2467 zvrf = zebra_vrf_get_evpn();
2468 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2469 return CMD_SUCCESS;
2470 }
2471
2472 DEFUN (show_evpn_neigh_vni_vtep,
2473 show_evpn_neigh_vni_vtep_cmd,
2474 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2475 SHOW_STR
2476 "EVPN\n"
2477 "ARP and ND cache\n"
2478 "VxLAN Network Identifier\n"
2479 "VNI number\n"
2480 "Remote VTEP\n"
2481 "Remote VTEP IP address\n"
2482 JSON_STR)
2483 {
2484 struct zebra_vrf *zvrf;
2485 vni_t vni;
2486 struct in_addr vtep_ip;
2487 bool uj = use_json(argc, argv);
2488
2489 vni = strtoul(argv[4]->arg, NULL, 10);
2490 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2491 if (!uj)
2492 vty_out(vty, "%% Malformed VTEP IP address\n");
2493 return CMD_WARNING;
2494 }
2495
2496 zvrf = zebra_vrf_get_evpn();
2497 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2498 return CMD_SUCCESS;
2499 }
2500
2501 /* policy routing contexts */
2502 DEFUN (show_pbr_ipset,
2503 show_pbr_ipset_cmd,
2504 "show pbr ipset [WORD]",
2505 SHOW_STR
2506 "Policy-Based Routing\n"
2507 "IPset Context information\n"
2508 "IPset Name information\n")
2509 {
2510 int idx = 0;
2511 int found = 0;
2512 found = argv_find(argv, argc, "WORD", &idx);
2513 if (!found)
2514 zebra_pbr_show_ipset_list(vty, NULL);
2515 else
2516 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2517 return CMD_SUCCESS;
2518 }
2519
2520 /* policy routing contexts */
2521 DEFUN (show_pbr_iptable,
2522 show_pbr_iptable_cmd,
2523 "show pbr iptable [WORD]",
2524 SHOW_STR
2525 "Policy-Based Routing\n"
2526 "IPtable Context information\n"
2527 "IPtable Name information\n")
2528 {
2529 int idx = 0;
2530 int found = 0;
2531
2532 found = argv_find(argv, argc, "WORD", &idx);
2533 if (!found)
2534 zebra_pbr_show_iptable(vty, NULL);
2535 else
2536 zebra_pbr_show_iptable(vty, argv[idx]->arg);
2537 return CMD_SUCCESS;
2538 }
2539
2540 DEFPY (clear_evpn_dup_addr,
2541 clear_evpn_dup_addr_cmd,
2542 "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>]>",
2543 CLEAR_STR
2544 "EVPN\n"
2545 "Duplicate address \n"
2546 "VxLAN Network Identifier\n"
2547 "VNI number\n"
2548 "All VNIs\n"
2549 "MAC\n"
2550 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2551 "IP\n"
2552 "IPv4 address\n"
2553 "IPv6 address\n")
2554 {
2555 struct zebra_vrf *zvrf;
2556 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
2557 int ret = CMD_SUCCESS;
2558
2559 zvrf = zebra_vrf_get_evpn();
2560 if (vni_str) {
2561 if (!is_zero_mac(&mac->eth_addr)) {
2562 ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
2563 vni,
2564 &mac->eth_addr);
2565 } else if (ip) {
2566 if (sockunion_family(ip) == AF_INET) {
2567 host_ip.ipa_type = IPADDR_V4;
2568 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2569 } else {
2570 host_ip.ipa_type = IPADDR_V6;
2571 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2572 sizeof(struct in6_addr));
2573 }
2574 ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
2575 vni,
2576 &host_ip);
2577 } else
2578 ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
2579
2580 } else {
2581 ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
2582 }
2583
2584 return ret;
2585 }
2586
2587 /* Static ip route configuration write function. */
2588 static int zebra_ip_config(struct vty *vty)
2589 {
2590 int write = 0;
2591
2592 write += zebra_import_table_config(vty, VRF_DEFAULT);
2593
2594 return write;
2595 }
2596
2597 DEFUN (ip_zebra_import_table_distance,
2598 ip_zebra_import_table_distance_cmd,
2599 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2600 IP_STR
2601 "import routes from non-main kernel table\n"
2602 "kernel routing table id\n"
2603 "Distance for imported routes\n"
2604 "Default distance value\n"
2605 "route-map for filtering\n"
2606 "route-map name\n")
2607 {
2608 uint32_t table_id = 0;
2609
2610 table_id = strtoul(argv[2]->arg, NULL, 10);
2611 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2612 char *rmap =
2613 strmatch(argv[argc - 2]->text, "route-map")
2614 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2615 : NULL;
2616 int ret;
2617
2618 if (argc == 7 || (argc == 5 && !rmap))
2619 distance = strtoul(argv[4]->arg, NULL, 10);
2620
2621 if (!is_zebra_valid_kernel_table(table_id)) {
2622 vty_out(vty,
2623 "Invalid routing table ID, %d. Must be in range 1-252\n",
2624 table_id);
2625 if (rmap)
2626 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2627 return CMD_WARNING;
2628 }
2629
2630 if (is_zebra_main_routing_table(table_id)) {
2631 vty_out(vty,
2632 "Invalid routing table ID, %d. Must be non-default table\n",
2633 table_id);
2634 if (rmap)
2635 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2636 return CMD_WARNING;
2637 }
2638
2639 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
2640 distance, rmap, 1);
2641 if (rmap)
2642 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2643
2644 return ret;
2645 }
2646
2647 DEFUN_HIDDEN (zebra_packet_process,
2648 zebra_packet_process_cmd,
2649 "zebra zapi-packets (1-10000)",
2650 ZEBRA_STR
2651 "Zapi Protocol\n"
2652 "Number of packets to process before relinquishing thread\n")
2653 {
2654 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2655
2656 atomic_store_explicit(&zrouter.packets_to_process, packets,
2657 memory_order_relaxed);
2658
2659 return CMD_SUCCESS;
2660 }
2661
2662 DEFUN_HIDDEN (no_zebra_packet_process,
2663 no_zebra_packet_process_cmd,
2664 "no zebra zapi-packets [(1-10000)]",
2665 NO_STR
2666 ZEBRA_STR
2667 "Zapi Protocol\n"
2668 "Number of packets to process before relinquishing thread\n")
2669 {
2670 atomic_store_explicit(&zrouter.packets_to_process,
2671 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2672 memory_order_relaxed);
2673
2674 return CMD_SUCCESS;
2675 }
2676
2677 DEFUN_HIDDEN (zebra_workqueue_timer,
2678 zebra_workqueue_timer_cmd,
2679 "zebra work-queue (0-10000)",
2680 ZEBRA_STR
2681 "Work Queue\n"
2682 "Time in milliseconds\n")
2683 {
2684 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2685 zrouter.ribq->spec.hold = timer;
2686
2687 return CMD_SUCCESS;
2688 }
2689
2690 DEFUN_HIDDEN (no_zebra_workqueue_timer,
2691 no_zebra_workqueue_timer_cmd,
2692 "no zebra work-queue [(0-10000)]",
2693 NO_STR
2694 ZEBRA_STR
2695 "Work Queue\n"
2696 "Time in milliseconds\n")
2697 {
2698 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
2699
2700 return CMD_SUCCESS;
2701 }
2702
2703 DEFUN (no_ip_zebra_import_table,
2704 no_ip_zebra_import_table_cmd,
2705 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2706 NO_STR
2707 IP_STR
2708 "import routes from non-main kernel table\n"
2709 "kernel routing table id\n"
2710 "Distance for imported routes\n"
2711 "Default distance value\n"
2712 "route-map for filtering\n"
2713 "route-map name\n")
2714 {
2715 uint32_t table_id = 0;
2716 table_id = strtoul(argv[3]->arg, NULL, 10);
2717
2718 if (!is_zebra_valid_kernel_table(table_id)) {
2719 vty_out(vty,
2720 "Invalid routing table ID. Must be in range 1-252\n");
2721 return CMD_WARNING;
2722 }
2723
2724 if (is_zebra_main_routing_table(table_id)) {
2725 vty_out(vty,
2726 "Invalid routing table ID, %d. Must be non-default table\n",
2727 table_id);
2728 return CMD_WARNING;
2729 }
2730
2731 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
2732 return CMD_SUCCESS;
2733
2734 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
2735 }
2736
2737 static int config_write_protocol(struct vty *vty)
2738 {
2739 if (allow_delete)
2740 vty_out(vty, "allow-external-route-update\n");
2741
2742 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2743 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
2744
2745 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
2746 vty_out(vty, "zebra zapi-packets %u\n",
2747 zrouter.packets_to_process);
2748
2749 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2750
2751 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2752 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2753 ipv4_multicast_mode == MCAST_URIB_ONLY
2754 ? "urib-only"
2755 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2756 ? "mrib-only"
2757 : ipv4_multicast_mode
2758 == MCAST_MIX_MRIB_FIRST
2759 ? "mrib-then-urib"
2760 : ipv4_multicast_mode
2761 == MCAST_MIX_DISTANCE
2762 ? "lower-distance"
2763 : "longer-prefix");
2764
2765 /* Include dataplane info */
2766 dplane_config_write_helper(vty);
2767
2768 return 1;
2769 }
2770
2771 DEFUN (show_zebra,
2772 show_zebra_cmd,
2773 "show zebra",
2774 SHOW_STR
2775 ZEBRA_STR)
2776 {
2777 struct vrf *vrf;
2778
2779 vty_out(vty,
2780 " Route Route Neighbor LSP LSP\n");
2781 vty_out(vty,
2782 "VRF Installs Removals Updates Installs Removals\n");
2783
2784 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2785 struct zebra_vrf *zvrf = vrf->info;
2786
2787 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2788 " %10" PRIu64 " %10" PRIu64 "\n",
2789 vrf->name, zvrf->installs, zvrf->removals,
2790 zvrf->neigh_updates, zvrf->lsp_installs,
2791 zvrf->lsp_removals);
2792 }
2793
2794 return CMD_SUCCESS;
2795 }
2796
2797 DEFUN (ip_forwarding,
2798 ip_forwarding_cmd,
2799 "ip forwarding",
2800 IP_STR
2801 "Turn on IP forwarding\n")
2802 {
2803 int ret;
2804
2805 ret = ipforward();
2806 if (ret == 0)
2807 ret = ipforward_on();
2808
2809 if (ret == 0) {
2810 vty_out(vty, "Can't turn on IP forwarding\n");
2811 return CMD_WARNING_CONFIG_FAILED;
2812 }
2813
2814 return CMD_SUCCESS;
2815 }
2816
2817 DEFUN (no_ip_forwarding,
2818 no_ip_forwarding_cmd,
2819 "no ip forwarding",
2820 NO_STR
2821 IP_STR
2822 "Turn off IP forwarding\n")
2823 {
2824 int ret;
2825
2826 ret = ipforward();
2827 if (ret != 0)
2828 ret = ipforward_off();
2829
2830 if (ret != 0) {
2831 vty_out(vty, "Can't turn off IP forwarding\n");
2832 return CMD_WARNING_CONFIG_FAILED;
2833 }
2834
2835 return CMD_SUCCESS;
2836 }
2837
2838 /* Only display ip forwarding is enabled or not. */
2839 DEFUN (show_ip_forwarding,
2840 show_ip_forwarding_cmd,
2841 "show ip forwarding",
2842 SHOW_STR
2843 IP_STR
2844 "IP forwarding status\n")
2845 {
2846 int ret;
2847
2848 ret = ipforward();
2849
2850 if (ret == 0)
2851 vty_out(vty, "IP forwarding is off\n");
2852 else
2853 vty_out(vty, "IP forwarding is on\n");
2854 return CMD_SUCCESS;
2855 }
2856
2857 /* Only display ipv6 forwarding is enabled or not. */
2858 DEFUN (show_ipv6_forwarding,
2859 show_ipv6_forwarding_cmd,
2860 "show ipv6 forwarding",
2861 SHOW_STR
2862 "IPv6 information\n"
2863 "Forwarding status\n")
2864 {
2865 int ret;
2866
2867 ret = ipforward_ipv6();
2868
2869 switch (ret) {
2870 case -1:
2871 vty_out(vty, "ipv6 forwarding is unknown\n");
2872 break;
2873 case 0:
2874 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2875 break;
2876 case 1:
2877 vty_out(vty, "ipv6 forwarding is %s\n", "on");
2878 break;
2879 default:
2880 vty_out(vty, "ipv6 forwarding is %s\n", "off");
2881 break;
2882 }
2883 return CMD_SUCCESS;
2884 }
2885
2886 DEFUN (ipv6_forwarding,
2887 ipv6_forwarding_cmd,
2888 "ipv6 forwarding",
2889 IPV6_STR
2890 "Turn on IPv6 forwarding\n")
2891 {
2892 int ret;
2893
2894 ret = ipforward_ipv6();
2895 if (ret == 0)
2896 ret = ipforward_ipv6_on();
2897
2898 if (ret == 0) {
2899 vty_out(vty, "Can't turn on IPv6 forwarding\n");
2900 return CMD_WARNING_CONFIG_FAILED;
2901 }
2902
2903 return CMD_SUCCESS;
2904 }
2905
2906 DEFUN (no_ipv6_forwarding,
2907 no_ipv6_forwarding_cmd,
2908 "no ipv6 forwarding",
2909 NO_STR
2910 IPV6_STR
2911 "Turn off IPv6 forwarding\n")
2912 {
2913 int ret;
2914
2915 ret = ipforward_ipv6();
2916 if (ret != 0)
2917 ret = ipforward_ipv6_off();
2918
2919 if (ret != 0) {
2920 vty_out(vty, "Can't turn off IPv6 forwarding\n");
2921 return CMD_WARNING_CONFIG_FAILED;
2922 }
2923
2924 return CMD_SUCCESS;
2925 }
2926
2927 /* Display dataplane info */
2928 DEFUN (show_dataplane,
2929 show_dataplane_cmd,
2930 "show zebra dplane [detailed]",
2931 SHOW_STR
2932 ZEBRA_STR
2933 "Zebra dataplane information\n"
2934 "Detailed output\n")
2935 {
2936 int idx = 0;
2937 bool detailed = false;
2938
2939 if (argv_find(argv, argc, "detailed", &idx))
2940 detailed = true;
2941
2942 return dplane_show_helper(vty, detailed);
2943 }
2944
2945 /* Display dataplane providers info */
2946 DEFUN (show_dataplane_providers,
2947 show_dataplane_providers_cmd,
2948 "show zebra dplane providers [detailed]",
2949 SHOW_STR
2950 ZEBRA_STR
2951 "Zebra dataplane information\n"
2952 "Zebra dataplane provider information\n"
2953 "Detailed output\n")
2954 {
2955 int idx = 0;
2956 bool detailed = false;
2957
2958 if (argv_find(argv, argc, "detailed", &idx))
2959 detailed = true;
2960
2961 return dplane_show_provs_helper(vty, detailed);
2962 }
2963
2964 /* Configure dataplane incoming queue limit */
2965 DEFUN (zebra_dplane_queue_limit,
2966 zebra_dplane_queue_limit_cmd,
2967 "zebra dplane limit (0-10000)",
2968 ZEBRA_STR
2969 "Zebra dataplane\n"
2970 "Limit incoming queued updates\n"
2971 "Number of queued updates\n")
2972 {
2973 uint32_t limit = 0;
2974
2975 limit = strtoul(argv[3]->arg, NULL, 10);
2976
2977 dplane_set_in_queue_limit(limit, true);
2978
2979 return CMD_SUCCESS;
2980 }
2981
2982 /* Reset dataplane queue limit to default value */
2983 DEFUN (no_zebra_dplane_queue_limit,
2984 no_zebra_dplane_queue_limit_cmd,
2985 "no zebra dplane limit [(0-10000)]",
2986 NO_STR
2987 ZEBRA_STR
2988 "Zebra dataplane\n"
2989 "Limit incoming queued updates\n"
2990 "Number of queued updates\n")
2991 {
2992 dplane_set_in_queue_limit(0, false);
2993
2994 return CMD_SUCCESS;
2995 }
2996
2997 DEFUN (zebra_show_routing_tables_summary,
2998 zebra_show_routing_tables_summary_cmd,
2999 "show zebra router table summary",
3000 SHOW_STR
3001 ZEBRA_STR
3002 "The Zebra Router Information\n"
3003 "Table Information about this Zebra Router\n"
3004 "Summary Information\n")
3005 {
3006 zebra_router_show_table_summary(vty);
3007
3008 return CMD_SUCCESS;
3009 }
3010
3011 /* Table configuration write function. */
3012 static int config_write_table(struct vty *vty)
3013 {
3014 return 0;
3015 }
3016
3017 /* IPForwarding configuration write function. */
3018 static int config_write_forwarding(struct vty *vty)
3019 {
3020 /* FIXME: Find better place for that. */
3021 router_id_write(vty);
3022
3023 if (!ipforward())
3024 vty_out(vty, "no ip forwarding\n");
3025 if (!ipforward_ipv6())
3026 vty_out(vty, "no ipv6 forwarding\n");
3027 vty_out(vty, "!\n");
3028 return 0;
3029 }
3030
3031 DEFUN_HIDDEN (show_frr,
3032 show_frr_cmd,
3033 "show frr",
3034 SHOW_STR
3035 "FRR\n")
3036 {
3037 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
3038 vty_out(vty, ".............................7777:..............................................\n");
3039 vty_out(vty, ".............................777777,............................................\n");
3040 vty_out(vty, "... .........................77777777,..........................................\n");
3041 vty_out(vty, "............................=7777777777:........................................\n");
3042 vty_out(vty, "........................:7777777777777777,......................................\n");
3043 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
3044 vty_out(vty, "...................I7777777777+.................................................\n");
3045 vty_out(vty, "................,777777777?............ .......................................\n");
3046 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
3047 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
3048 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
3049 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
3050 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
3051 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3052 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3053 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3054 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3055 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3056 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3057 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3058 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3059 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3060 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3061 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3062 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3063 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3064 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3065 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3066 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3067 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3068 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3069 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
3070 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3071 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3072 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3073 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3074 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3075 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3076 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3077 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
3078 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
3079 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
3080 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
3081 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
3082 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
3083 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
3084 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
3085 vty_out(vty, "............................~777777777777..............+777777..................\n");
3086 vty_out(vty, "................................~77777777...............=777777.................\n");
3087 vty_out(vty, ".....................................:=?I................~777777................\n");
3088 vty_out(vty, "..........................................................:777777,..............\n");
3089 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3090
3091 return CMD_SUCCESS;
3092 }
3093
3094 /* IP node for static routes. */
3095 static struct cmd_node ip_node = {IP_NODE, "", 1};
3096 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
3097 /* table node for routing tables. */
3098 static struct cmd_node table_node = {TABLE_NODE,
3099 "", /* This node has no interface. */
3100 1};
3101 static struct cmd_node forwarding_node = {FORWARDING_NODE,
3102 "", /* This node has no interface. */
3103 1};
3104
3105 /* Route VTY. */
3106 void zebra_vty_init(void)
3107 {
3108 /* Install configuration write function. */
3109 install_node(&table_node, config_write_table);
3110 install_node(&forwarding_node, config_write_forwarding);
3111
3112 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3113 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3114 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3115 install_element(ENABLE_NODE, &show_zebra_cmd);
3116
3117 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3118 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3119 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3120
3121 /* Route-map */
3122 zebra_route_map_init();
3123
3124 install_node(&ip_node, zebra_ip_config);
3125 install_node(&protocol_node, config_write_protocol);
3126
3127 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3128 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
3129
3130 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3131 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
3132
3133 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3134 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3135 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3136 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
3137 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3138 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
3139
3140 install_element(VIEW_NODE, &show_nexthop_group_cmd);
3141
3142 install_element(VIEW_NODE, &show_vrf_cmd);
3143 install_element(VIEW_NODE, &show_vrf_vni_cmd);
3144 install_element(VIEW_NODE, &show_route_cmd);
3145 install_element(VIEW_NODE, &show_route_table_cmd);
3146 if (vrf_is_backend_netns())
3147 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
3148 install_element(VIEW_NODE, &show_route_all_table_vrf_cmd);
3149 install_element(VIEW_NODE, &show_route_detail_cmd);
3150 install_element(VIEW_NODE, &show_route_summary_cmd);
3151 install_element(VIEW_NODE, &show_ip_nht_cmd);
3152
3153 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3154 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3155
3156 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3157 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3158 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3159 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
3160 install_element(VRF_NODE, &ip_nht_default_route_cmd);
3161 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
3162 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
3163 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
3164 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3165
3166 /* Commands for VRF */
3167 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3168
3169 install_element(VIEW_NODE, &show_frr_cmd);
3170 install_element(VIEW_NODE, &show_evpn_global_cmd);
3171 install_element(VIEW_NODE, &show_evpn_vni_cmd);
3172 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
3173 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
3174 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3175 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3176 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3177 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3178 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3179 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
3180 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3181 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
3182 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
3183 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3184 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3185 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
3186 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
3187 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
3188 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3189 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
3190 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
3191 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3192 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
3193 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
3194 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
3195 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
3196
3197 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3198 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3199
3200 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3201 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
3202 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3203 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
3204
3205 install_element(VIEW_NODE, &show_dataplane_cmd);
3206 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
3207 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
3208 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
3209
3210 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
3211 }