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