]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vty.c
zebra: Only show route nexthop group ID when asked
[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 re->nexthop_num);
470 json_object_int_add(json_route, "internalNextHopActiveNum",
471 re->nexthop_active_num);
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_DUPLICATE)) {
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_table_with_table_id(afi,
1712 SAFI_UNICAST,
1713 zvrf->vrf->vrf_id,
1714 table_id);
1715 if (!table)
1716 continue;
1717
1718 if (prefix)
1719 vty_show_ip_route_summary_prefix(vty, table);
1720 else
1721 vty_show_ip_route_summary(vty, table);
1722 }
1723 } else {
1724 vrf_id_t vrf_id = VRF_DEFAULT;
1725
1726 if (vrf_name)
1727 VRF_GET_ID(vrf_id, vrf_name, false);
1728
1729 table = zebra_vrf_table_with_table_id(afi,
1730 SAFI_UNICAST,
1731 vrf_id, table_id);
1732 if (!table)
1733 return CMD_SUCCESS;
1734
1735 if (prefix)
1736 vty_show_ip_route_summary_prefix(vty, table);
1737 else
1738 vty_show_ip_route_summary(vty, table);
1739 }
1740
1741 return CMD_SUCCESS;
1742 }
1743
1744 static void vty_show_ip_route_summary(struct vty *vty,
1745 struct route_table *table)
1746 {
1747 struct route_node *rn;
1748 struct route_entry *re;
1749 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1750 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1751 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1752 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1753 uint32_t i;
1754 uint32_t is_ibgp;
1755
1756 memset(&rib_cnt, 0, sizeof(rib_cnt));
1757 memset(&fib_cnt, 0, sizeof(fib_cnt));
1758 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1759 RNODE_FOREACH_RE (rn, re) {
1760 is_ibgp = (re->type == ZEBRA_ROUTE_BGP
1761 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
1762
1763 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1764 if (is_ibgp)
1765 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1766 else
1767 rib_cnt[re->type]++;
1768
1769 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1770 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1771
1772 if (is_ibgp)
1773 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1774 else
1775 fib_cnt[re->type]++;
1776 }
1777 }
1778
1779 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1780 "FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1781
1782 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1783 if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
1784 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
1785 if (i == ZEBRA_ROUTE_BGP) {
1786 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1787 rib_cnt[ZEBRA_ROUTE_BGP],
1788 fib_cnt[ZEBRA_ROUTE_BGP]);
1789 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1790 rib_cnt[ZEBRA_ROUTE_IBGP],
1791 fib_cnt[ZEBRA_ROUTE_IBGP]);
1792 } else
1793 vty_out(vty, "%-20s %-20d %-20d \n",
1794 zebra_route_string(i), rib_cnt[i],
1795 fib_cnt[i]);
1796 }
1797 }
1798
1799 vty_out(vty, "------\n");
1800 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1801 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1802 vty_out(vty, "\n");
1803 }
1804
1805 /*
1806 * Implementation of the ip route summary prefix command.
1807 *
1808 * This command prints the primary prefixes that have been installed by various
1809 * protocols on the box.
1810 *
1811 */
1812 static void vty_show_ip_route_summary_prefix(struct vty *vty,
1813 struct route_table *table)
1814 {
1815 struct route_node *rn;
1816 struct route_entry *re;
1817 struct nexthop *nexthop;
1818 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1819 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1820 uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1821 uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
1822 uint32_t i;
1823 int cnt;
1824
1825 memset(&rib_cnt, 0, sizeof(rib_cnt));
1826 memset(&fib_cnt, 0, sizeof(fib_cnt));
1827 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1828 RNODE_FOREACH_RE (rn, re) {
1829
1830 /*
1831 * In case of ECMP, count only once.
1832 */
1833 cnt = 0;
1834 if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
1835 fib_cnt[ZEBRA_ROUTE_TOTAL]++;
1836 fib_cnt[re->type]++;
1837 }
1838 for (nexthop = re->ng->nexthop; (!cnt && nexthop);
1839 nexthop = nexthop->next) {
1840 cnt++;
1841 rib_cnt[ZEBRA_ROUTE_TOTAL]++;
1842 rib_cnt[re->type]++;
1843 if (re->type == ZEBRA_ROUTE_BGP
1844 && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
1845 rib_cnt[ZEBRA_ROUTE_IBGP]++;
1846 if (CHECK_FLAG(re->status,
1847 ROUTE_ENTRY_INSTALLED))
1848 fib_cnt[ZEBRA_ROUTE_IBGP]++;
1849 }
1850 }
1851 }
1852
1853 vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1854 "Prefix Routes", "FIB",
1855 zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
1856
1857 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
1858 if (rib_cnt[i] > 0) {
1859 if (i == ZEBRA_ROUTE_BGP) {
1860 vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
1861 rib_cnt[ZEBRA_ROUTE_BGP]
1862 - rib_cnt[ZEBRA_ROUTE_IBGP],
1863 fib_cnt[ZEBRA_ROUTE_BGP]
1864 - fib_cnt[ZEBRA_ROUTE_IBGP]);
1865 vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
1866 rib_cnt[ZEBRA_ROUTE_IBGP],
1867 fib_cnt[ZEBRA_ROUTE_IBGP]);
1868 } else
1869 vty_out(vty, "%-20s %-20d %-20d \n",
1870 zebra_route_string(i), rib_cnt[i],
1871 fib_cnt[i]);
1872 }
1873 }
1874
1875 vty_out(vty, "------\n");
1876 vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
1877 rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
1878 vty_out(vty, "\n");
1879 }
1880
1881 /*
1882 * Show IPv6 mroute command.Used to dump
1883 * the Multicast routing table.
1884 */
1885 DEFUN (show_ipv6_mroute,
1886 show_ipv6_mroute_cmd,
1887 "show ipv6 mroute [vrf NAME]",
1888 SHOW_STR
1889 IP_STR
1890 "IPv6 Multicast routing table\n"
1891 VRF_CMD_HELP_STR)
1892 {
1893 struct route_table *table;
1894 struct route_node *rn;
1895 struct route_entry *re;
1896 int first = 1;
1897 vrf_id_t vrf_id = VRF_DEFAULT;
1898
1899 if (argc == 5)
1900 VRF_GET_ID(vrf_id, argv[4]->arg, false);
1901
1902 table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
1903 if (!table)
1904 return CMD_SUCCESS;
1905
1906 /* Show all IPv6 route. */
1907 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1908 RNODE_FOREACH_RE (rn, re) {
1909 if (first) {
1910 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1911 first = 0;
1912 }
1913 vty_show_ip_route(vty, rn, re, NULL, false);
1914 }
1915 return CMD_SUCCESS;
1916 }
1917
1918 DEFUN (show_ipv6_mroute_vrf_all,
1919 show_ipv6_mroute_vrf_all_cmd,
1920 "show ipv6 mroute vrf all",
1921 SHOW_STR
1922 IP_STR
1923 "IPv6 Multicast routing table\n"
1924 VRF_ALL_CMD_HELP_STR)
1925 {
1926 struct route_table *table;
1927 struct route_node *rn;
1928 struct route_entry *re;
1929 struct vrf *vrf;
1930 struct zebra_vrf *zvrf;
1931 int first = 1;
1932
1933 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1934 if ((zvrf = vrf->info) == NULL
1935 || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
1936 continue;
1937
1938 /* Show all IPv6 route. */
1939 for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
1940 RNODE_FOREACH_RE (rn, re) {
1941 if (first) {
1942 vty_out(vty, SHOW_ROUTE_V6_HEADER);
1943 first = 0;
1944 }
1945 vty_show_ip_route(vty, rn, re, NULL, false);
1946 }
1947 }
1948 return CMD_SUCCESS;
1949 }
1950
1951 DEFUN (allow_external_route_update,
1952 allow_external_route_update_cmd,
1953 "allow-external-route-update",
1954 "Allow FRR routes to be overwritten by external processes\n")
1955 {
1956 allow_delete = 1;
1957
1958 return CMD_SUCCESS;
1959 }
1960
1961 DEFUN (no_allow_external_route_update,
1962 no_allow_external_route_update_cmd,
1963 "no allow-external-route-update",
1964 NO_STR
1965 "Allow FRR routes to be overwritten by external processes\n")
1966 {
1967 allow_delete = 0;
1968
1969 return CMD_SUCCESS;
1970 }
1971
1972 /* show vrf */
1973 DEFUN (show_vrf,
1974 show_vrf_cmd,
1975 "show vrf",
1976 SHOW_STR
1977 "VRF\n")
1978 {
1979 struct vrf *vrf;
1980 struct zebra_vrf *zvrf;
1981
1982 if (vrf_is_backend_netns())
1983 vty_out(vty, "netns-based vrfs\n");
1984
1985 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1986 if (!(zvrf = vrf->info))
1987 continue;
1988 if (zvrf_id(zvrf) == VRF_DEFAULT)
1989 continue;
1990
1991 vty_out(vty, "vrf %s ", zvrf_name(zvrf));
1992 if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
1993 vty_out(vty, "inactive");
1994 else if (zvrf_ns_name(zvrf))
1995 vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
1996 zvrf_ns_name(zvrf));
1997 else
1998 vty_out(vty, "id %u table %u", zvrf_id(zvrf),
1999 zvrf->table_id);
2000 if (vrf_is_user_cfged(vrf))
2001 vty_out(vty, " (configured)");
2002 vty_out(vty, "\n");
2003 }
2004
2005 return CMD_SUCCESS;
2006 }
2007
2008 DEFUN (default_vrf_vni_mapping,
2009 default_vrf_vni_mapping_cmd,
2010 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
2011 "VNI corresponding to the DEFAULT VRF\n"
2012 "VNI-ID\n"
2013 "Prefix routes only \n")
2014 {
2015 int ret = 0;
2016 char err[ERR_STR_SZ];
2017 struct zebra_vrf *zvrf = NULL;
2018 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
2019 int filter = 0;
2020
2021 zvrf = vrf_info_lookup(VRF_DEFAULT);
2022 if (!zvrf)
2023 return CMD_WARNING;
2024
2025 if (argc == 3)
2026 filter = 1;
2027
2028 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
2029 filter, 1);
2030 if (ret != 0) {
2031 vty_out(vty, "%s\n", err);
2032 return CMD_WARNING;
2033 }
2034
2035 return CMD_SUCCESS;
2036 }
2037
2038 DEFUN (no_default_vrf_vni_mapping,
2039 no_default_vrf_vni_mapping_cmd,
2040 "no vni " CMD_VNI_RANGE,
2041 NO_STR
2042 "VNI corresponding to DEFAULT VRF\n"
2043 "VNI-ID")
2044 {
2045 int ret = 0;
2046 char err[ERR_STR_SZ];
2047 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2048 struct zebra_vrf *zvrf = NULL;
2049
2050 zvrf = vrf_info_lookup(VRF_DEFAULT);
2051 if (!zvrf)
2052 return CMD_WARNING;
2053
2054 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
2055 if (ret != 0) {
2056 vty_out(vty, "%s\n", err);
2057 return CMD_WARNING;
2058 }
2059
2060 return CMD_SUCCESS;
2061 }
2062
2063 DEFUN (vrf_vni_mapping,
2064 vrf_vni_mapping_cmd,
2065 "vni " CMD_VNI_RANGE "[prefix-routes-only]",
2066 "VNI corresponding to tenant VRF\n"
2067 "VNI-ID\n"
2068 "prefix-routes-only\n")
2069 {
2070 int ret = 0;
2071 int filter = 0;
2072
2073 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2074 vni_t vni = strtoul(argv[1]->arg, NULL, 10);
2075 char err[ERR_STR_SZ];
2076
2077 assert(vrf);
2078 assert(zvrf);
2079
2080 if (argc == 3)
2081 filter = 1;
2082
2083 /* Mark as having FRR configuration */
2084 vrf_set_user_cfged(vrf);
2085 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
2086 filter, 1);
2087 if (ret != 0) {
2088 vty_out(vty, "%s\n", err);
2089 return CMD_WARNING;
2090 }
2091
2092 return CMD_SUCCESS;
2093 }
2094
2095 DEFUN (no_vrf_vni_mapping,
2096 no_vrf_vni_mapping_cmd,
2097 "no vni " CMD_VNI_RANGE "[prefix-routes-only]",
2098 NO_STR
2099 "VNI corresponding to tenant VRF\n"
2100 "VNI-ID\n"
2101 "prefix-routes-only\n")
2102 {
2103 int ret = 0;
2104 int filter = 0;
2105 char err[ERR_STR_SZ];
2106 vni_t vni = strtoul(argv[2]->arg, NULL, 10);
2107
2108 ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
2109
2110 assert(vrf);
2111 assert(zvrf);
2112
2113 if (argc == 4)
2114 filter = 1;
2115
2116 ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
2117 ERR_STR_SZ, filter, 0);
2118 if (ret != 0) {
2119 vty_out(vty, "%s\n", err);
2120 return CMD_WARNING;
2121 }
2122
2123 /* If no other FRR config for this VRF, mark accordingly. */
2124 if (!zebra_vrf_has_config(zvrf))
2125 vrf_reset_user_cfged(vrf);
2126
2127 return CMD_SUCCESS;
2128 }
2129
2130 /* show vrf */
2131 DEFUN (show_vrf_vni,
2132 show_vrf_vni_cmd,
2133 "show vrf vni [json]",
2134 SHOW_STR
2135 "VRF\n"
2136 "VNI\n"
2137 JSON_STR)
2138 {
2139 struct vrf *vrf;
2140 struct zebra_vrf *zvrf;
2141 json_object *json = NULL;
2142 json_object *json_vrfs = NULL;
2143 bool uj = use_json(argc, argv);
2144
2145 if (uj) {
2146 json = json_object_new_object();
2147 json_vrfs = json_object_new_array();
2148 }
2149
2150 if (!uj)
2151 vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2152 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2153
2154 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2155 zvrf = vrf->info;
2156 if (!zvrf)
2157 continue;
2158
2159 zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
2160 }
2161
2162 if (uj) {
2163 json_object_object_add(json, "vrfs", json_vrfs);
2164 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2165 json, JSON_C_TO_STRING_PRETTY));
2166 json_object_free(json);
2167 }
2168
2169 return CMD_SUCCESS;
2170 }
2171
2172 DEFUN (show_evpn_global,
2173 show_evpn_global_cmd,
2174 "show evpn [json]",
2175 SHOW_STR
2176 "EVPN\n"
2177 JSON_STR)
2178 {
2179 bool uj = use_json(argc, argv);
2180
2181 zebra_vxlan_print_evpn(vty, uj);
2182 return CMD_SUCCESS;
2183 }
2184
2185 DEFUN (show_evpn_vni,
2186 show_evpn_vni_cmd,
2187 "show evpn vni [json]",
2188 SHOW_STR
2189 "EVPN\n"
2190 "VxLAN Network Identifier\n"
2191 JSON_STR)
2192 {
2193 struct zebra_vrf *zvrf;
2194 bool uj = use_json(argc, argv);
2195
2196 zvrf = zebra_vrf_get_evpn();
2197 zebra_vxlan_print_vnis(vty, zvrf, uj);
2198 return CMD_SUCCESS;
2199 }
2200
2201 DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
2202 "show evpn vni detail [json]",
2203 SHOW_STR
2204 "EVPN\n"
2205 "VxLAN Network Identifier\n"
2206 "Detailed Information On Each VNI\n"
2207 JSON_STR)
2208 {
2209 struct zebra_vrf *zvrf;
2210 bool uj = use_json(argc, argv);
2211
2212 zvrf = zebra_vrf_get_evpn();
2213 zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
2214 return CMD_SUCCESS;
2215 }
2216
2217 DEFUN (show_evpn_vni_vni,
2218 show_evpn_vni_vni_cmd,
2219 "show evpn vni " CMD_VNI_RANGE "[json]",
2220 SHOW_STR
2221 "EVPN\n"
2222 "VxLAN Network Identifier\n"
2223 "VNI number\n"
2224 JSON_STR)
2225 {
2226 struct zebra_vrf *zvrf;
2227 vni_t vni;
2228 bool uj = use_json(argc, argv);
2229
2230 vni = strtoul(argv[3]->arg, NULL, 10);
2231 zvrf = zebra_vrf_get_evpn();
2232 zebra_vxlan_print_vni(vty, zvrf, vni, uj);
2233 return CMD_SUCCESS;
2234 }
2235
2236 DEFUN (show_evpn_rmac_vni_mac,
2237 show_evpn_rmac_vni_mac_cmd,
2238 "show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
2239 SHOW_STR
2240 "EVPN\n"
2241 "RMAC\n"
2242 "L3 VNI\n"
2243 "VNI number\n"
2244 "MAC\n"
2245 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2246 JSON_STR)
2247 {
2248 vni_t l3vni = 0;
2249 struct ethaddr mac;
2250 bool uj = use_json(argc, argv);
2251
2252 l3vni = strtoul(argv[4]->arg, NULL, 10);
2253 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2254 vty_out(vty, "%% Malformed MAC address\n");
2255 return CMD_WARNING;
2256 }
2257 zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
2258 return CMD_SUCCESS;
2259 }
2260
2261 DEFUN (show_evpn_rmac_vni,
2262 show_evpn_rmac_vni_cmd,
2263 "show evpn rmac vni " CMD_VNI_RANGE "[json]",
2264 SHOW_STR
2265 "EVPN\n"
2266 "RMAC\n"
2267 "L3 VNI\n"
2268 "VNI number\n"
2269 JSON_STR)
2270 {
2271 vni_t l3vni = 0;
2272 bool uj = use_json(argc, argv);
2273
2274 l3vni = strtoul(argv[4]->arg, NULL, 10);
2275 zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
2276
2277 return CMD_SUCCESS;
2278 }
2279
2280 DEFUN (show_evpn_rmac_vni_all,
2281 show_evpn_rmac_vni_all_cmd,
2282 "show evpn rmac vni all [json]",
2283 SHOW_STR
2284 "EVPN\n"
2285 "RMAC addresses\n"
2286 "L3 VNI\n"
2287 "All VNIs\n"
2288 JSON_STR)
2289 {
2290 bool uj = use_json(argc, argv);
2291
2292 zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
2293
2294 return CMD_SUCCESS;
2295 }
2296
2297 DEFUN (show_evpn_nh_vni_ip,
2298 show_evpn_nh_vni_ip_cmd,
2299 "show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
2300 SHOW_STR
2301 "EVPN\n"
2302 "Remote Vteps\n"
2303 "L3 VNI\n"
2304 "VNI number\n"
2305 "Ip address\n"
2306 "Host address (ipv4 or ipv6)\n"
2307 JSON_STR)
2308 {
2309 vni_t l3vni;
2310 struct ipaddr ip;
2311 bool uj = use_json(argc, argv);
2312
2313 l3vni = strtoul(argv[4]->arg, NULL, 10);
2314 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2315 if (!uj)
2316 vty_out(vty, "%% Malformed Neighbor address\n");
2317 return CMD_WARNING;
2318 }
2319 zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
2320
2321 return CMD_SUCCESS;
2322 }
2323
2324 DEFUN (show_evpn_nh_vni,
2325 show_evpn_nh_vni_cmd,
2326 "show evpn next-hops vni " CMD_VNI_RANGE "[json]",
2327 SHOW_STR
2328 "EVPN\n"
2329 "Remote Vteps\n"
2330 "L3 VNI\n"
2331 "VNI number\n"
2332 JSON_STR)
2333 {
2334 vni_t l3vni;
2335 bool uj = use_json(argc, argv);
2336
2337 l3vni = strtoul(argv[4]->arg, NULL, 10);
2338 zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
2339
2340 return CMD_SUCCESS;
2341 }
2342
2343 DEFUN (show_evpn_nh_vni_all,
2344 show_evpn_nh_vni_all_cmd,
2345 "show evpn next-hops vni all [json]",
2346 SHOW_STR
2347 "EVPN\n"
2348 "Remote VTEPs\n"
2349 "L3 VNI\n"
2350 "All VNIs\n"
2351 JSON_STR)
2352 {
2353 bool uj = use_json(argc, argv);
2354
2355 zebra_vxlan_print_nh_all_l3vni(vty, uj);
2356
2357 return CMD_SUCCESS;
2358 }
2359
2360 DEFUN (show_evpn_mac_vni,
2361 show_evpn_mac_vni_cmd,
2362 "show evpn mac vni " CMD_VNI_RANGE "[json]",
2363 SHOW_STR
2364 "EVPN\n"
2365 "MAC addresses\n"
2366 "VxLAN Network Identifier\n"
2367 "VNI number\n"
2368 JSON_STR)
2369 {
2370 struct zebra_vrf *zvrf;
2371 vni_t vni;
2372 bool uj = use_json(argc, argv);
2373
2374 vni = strtoul(argv[4]->arg, NULL, 10);
2375 zvrf = zebra_vrf_get_evpn();
2376 zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
2377 return CMD_SUCCESS;
2378 }
2379
2380 DEFUN (show_evpn_mac_vni_all,
2381 show_evpn_mac_vni_all_cmd,
2382 "show evpn mac vni all [json]",
2383 SHOW_STR
2384 "EVPN\n"
2385 "MAC addresses\n"
2386 "VxLAN Network Identifier\n"
2387 "All VNIs\n"
2388 JSON_STR)
2389 {
2390 struct zebra_vrf *zvrf;
2391 bool uj = use_json(argc, argv);
2392
2393 zvrf = zebra_vrf_get_evpn();
2394 zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
2395 return CMD_SUCCESS;
2396 }
2397
2398 DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
2399 "show evpn mac vni all detail [json]",
2400 SHOW_STR
2401 "EVPN\n"
2402 "MAC addresses\n"
2403 "VxLAN Network Identifier\n"
2404 "All VNIs\n"
2405 "Detailed Information On Each VNI MAC\n"
2406 JSON_STR)
2407 {
2408 struct zebra_vrf *zvrf;
2409 bool uj = use_json(argc, argv);
2410
2411 zvrf = zebra_vrf_get_evpn();
2412 zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
2413 return CMD_SUCCESS;
2414 }
2415
2416 DEFUN (show_evpn_mac_vni_all_vtep,
2417 show_evpn_mac_vni_all_vtep_cmd,
2418 "show evpn mac vni all vtep A.B.C.D [json]",
2419 SHOW_STR
2420 "EVPN\n"
2421 "MAC addresses\n"
2422 "VxLAN Network Identifier\n"
2423 "All VNIs\n"
2424 "Remote VTEP\n"
2425 "Remote VTEP IP address\n"
2426 JSON_STR)
2427 {
2428 struct zebra_vrf *zvrf;
2429 struct in_addr vtep_ip;
2430 bool uj = use_json(argc, argv);
2431
2432 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2433 if (!uj)
2434 vty_out(vty, "%% Malformed VTEP IP address\n");
2435 return CMD_WARNING;
2436 }
2437 zvrf = zebra_vrf_get_evpn();
2438 zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
2439
2440 return CMD_SUCCESS;
2441 }
2442
2443
2444 DEFUN (show_evpn_mac_vni_mac,
2445 show_evpn_mac_vni_mac_cmd,
2446 "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
2447 SHOW_STR
2448 "EVPN\n"
2449 "MAC addresses\n"
2450 "VxLAN Network Identifier\n"
2451 "VNI number\n"
2452 "MAC\n"
2453 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2454 JSON_STR)
2455
2456 {
2457 struct zebra_vrf *zvrf;
2458 vni_t vni;
2459 struct ethaddr mac;
2460 bool uj = use_json(argc, argv);
2461
2462 vni = strtoul(argv[4]->arg, NULL, 10);
2463 if (!prefix_str2mac(argv[6]->arg, &mac)) {
2464 vty_out(vty, "%% Malformed MAC address");
2465 return CMD_WARNING;
2466 }
2467 zvrf = zebra_vrf_get_evpn();
2468 zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
2469 return CMD_SUCCESS;
2470 }
2471
2472 DEFUN (show_evpn_mac_vni_vtep,
2473 show_evpn_mac_vni_vtep_cmd,
2474 "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
2475 SHOW_STR
2476 "EVPN\n"
2477 "MAC addresses\n"
2478 "VxLAN Network Identifier\n"
2479 "VNI number\n"
2480 "Remote VTEP\n"
2481 "Remote VTEP IP address\n"
2482 JSON_STR)
2483 {
2484 struct zebra_vrf *zvrf;
2485 vni_t vni;
2486 struct in_addr vtep_ip;
2487 bool uj = use_json(argc, argv);
2488
2489 vni = strtoul(argv[4]->arg, NULL, 10);
2490 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2491 if (!uj)
2492 vty_out(vty, "%% Malformed VTEP IP address\n");
2493 return CMD_WARNING;
2494 }
2495
2496 zvrf = zebra_vrf_get_evpn();
2497 zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2498 return CMD_SUCCESS;
2499 }
2500
2501 DEFPY (show_evpn_mac_vni_all_dad,
2502 show_evpn_mac_vni_all_dad_cmd,
2503 "show evpn mac vni all duplicate [json]",
2504 SHOW_STR
2505 "EVPN\n"
2506 "MAC addresses\n"
2507 "VxLAN Network Identifier\n"
2508 "All VNIs\n"
2509 "Duplicate address list\n"
2510 JSON_STR)
2511 {
2512 struct zebra_vrf *zvrf;
2513 bool uj = use_json(argc, argv);
2514
2515 zvrf = zebra_vrf_get_evpn();
2516 zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
2517 return CMD_SUCCESS;
2518 }
2519
2520
2521 DEFPY (show_evpn_mac_vni_dad,
2522 show_evpn_mac_vni_dad_cmd,
2523 "show evpn mac vni " CMD_VNI_RANGE " duplicate [json]",
2524 SHOW_STR
2525 "EVPN\n"
2526 "MAC addresses\n"
2527 "VxLAN Network Identifier\n"
2528 "VNI number\n"
2529 "Duplicate address list\n"
2530 JSON_STR)
2531 {
2532 struct zebra_vrf *zvrf;
2533 bool uj = use_json(argc, argv);
2534
2535 zvrf = zebra_vrf_get_evpn();
2536
2537 zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
2538
2539 return CMD_SUCCESS;
2540 }
2541
2542 DEFPY (show_evpn_neigh_vni_dad,
2543 show_evpn_neigh_vni_dad_cmd,
2544 "show evpn arp-cache vni " CMD_VNI_RANGE "duplicate [json]",
2545 SHOW_STR
2546 "EVPN\n"
2547 "ARP and ND cache\n"
2548 "VxLAN Network Identifier\n"
2549 "VNI number\n"
2550 "Duplicate address list\n"
2551 JSON_STR)
2552 {
2553 struct zebra_vrf *zvrf;
2554 bool uj = use_json(argc, argv);
2555
2556 zvrf = zebra_vrf_get_evpn();
2557 zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
2558 return CMD_SUCCESS;
2559 }
2560
2561 DEFPY (show_evpn_neigh_vni_all_dad,
2562 show_evpn_neigh_vni_all_dad_cmd,
2563 "show evpn arp-cache vni all duplicate [json]",
2564 SHOW_STR
2565 "EVPN\n"
2566 "ARP and ND cache\n"
2567 "VxLAN Network Identifier\n"
2568 "All VNIs\n"
2569 "Duplicate address list\n"
2570 JSON_STR)
2571 {
2572 struct zebra_vrf *zvrf;
2573 bool uj = use_json(argc, argv);
2574
2575 zvrf = zebra_vrf_get_evpn();
2576 zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
2577 return CMD_SUCCESS;
2578 }
2579
2580
2581 DEFUN (show_evpn_neigh_vni,
2582 show_evpn_neigh_vni_cmd,
2583 "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
2584 SHOW_STR
2585 "EVPN\n"
2586 "ARP and ND cache\n"
2587 "VxLAN Network Identifier\n"
2588 "VNI number\n"
2589 JSON_STR)
2590 {
2591 struct zebra_vrf *zvrf;
2592 vni_t vni;
2593 bool uj = use_json(argc, argv);
2594
2595 vni = strtoul(argv[4]->arg, NULL, 10);
2596 zvrf = zebra_vrf_get_evpn();
2597 zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
2598 return CMD_SUCCESS;
2599 }
2600
2601 DEFUN (show_evpn_neigh_vni_all,
2602 show_evpn_neigh_vni_all_cmd,
2603 "show evpn arp-cache vni all [json]",
2604 SHOW_STR
2605 "EVPN\n"
2606 "ARP and ND cache\n"
2607 "VxLAN Network Identifier\n"
2608 "All VNIs\n"
2609 JSON_STR)
2610 {
2611 struct zebra_vrf *zvrf;
2612 bool uj = use_json(argc, argv);
2613
2614 zvrf = zebra_vrf_get_evpn();
2615 zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
2616 return CMD_SUCCESS;
2617 }
2618
2619 DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
2620 "show evpn arp-cache vni all detail [json]",
2621 SHOW_STR
2622 "EVPN\n"
2623 "ARP and ND cache\n"
2624 "VxLAN Network Identifier\n"
2625 "All VNIs\n"
2626 "Neighbor details for all vnis in detail\n" JSON_STR)
2627 {
2628 struct zebra_vrf *zvrf;
2629 bool uj = use_json(argc, argv);
2630
2631 zvrf = zebra_vrf_get_evpn();
2632 zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
2633 return CMD_SUCCESS;
2634 }
2635
2636 DEFUN (show_evpn_neigh_vni_neigh,
2637 show_evpn_neigh_vni_neigh_cmd,
2638 "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
2639 SHOW_STR
2640 "EVPN\n"
2641 "ARP and ND cache\n"
2642 "VxLAN Network Identifier\n"
2643 "VNI number\n"
2644 "Neighbor\n"
2645 "Neighbor address (IPv4 or IPv6 address)\n"
2646 JSON_STR)
2647 {
2648 struct zebra_vrf *zvrf;
2649 vni_t vni;
2650 struct ipaddr ip;
2651 bool uj = use_json(argc, argv);
2652
2653 vni = strtoul(argv[4]->arg, NULL, 10);
2654 if (str2ipaddr(argv[6]->arg, &ip) != 0) {
2655 if (!uj)
2656 vty_out(vty, "%% Malformed Neighbor address\n");
2657 return CMD_WARNING;
2658 }
2659 zvrf = zebra_vrf_get_evpn();
2660 zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
2661 return CMD_SUCCESS;
2662 }
2663
2664 DEFUN (show_evpn_neigh_vni_vtep,
2665 show_evpn_neigh_vni_vtep_cmd,
2666 "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
2667 SHOW_STR
2668 "EVPN\n"
2669 "ARP and ND cache\n"
2670 "VxLAN Network Identifier\n"
2671 "VNI number\n"
2672 "Remote VTEP\n"
2673 "Remote VTEP IP address\n"
2674 JSON_STR)
2675 {
2676 struct zebra_vrf *zvrf;
2677 vni_t vni;
2678 struct in_addr vtep_ip;
2679 bool uj = use_json(argc, argv);
2680
2681 vni = strtoul(argv[4]->arg, NULL, 10);
2682 if (!inet_aton(argv[6]->arg, &vtep_ip)) {
2683 if (!uj)
2684 vty_out(vty, "%% Malformed VTEP IP address\n");
2685 return CMD_WARNING;
2686 }
2687
2688 zvrf = zebra_vrf_get_evpn();
2689 zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
2690 return CMD_SUCCESS;
2691 }
2692
2693 /* policy routing contexts */
2694 DEFUN (show_pbr_ipset,
2695 show_pbr_ipset_cmd,
2696 "show pbr ipset [WORD]",
2697 SHOW_STR
2698 "Policy-Based Routing\n"
2699 "IPset Context information\n"
2700 "IPset Name information\n")
2701 {
2702 int idx = 0;
2703 int found = 0;
2704 found = argv_find(argv, argc, "WORD", &idx);
2705 if (!found)
2706 zebra_pbr_show_ipset_list(vty, NULL);
2707 else
2708 zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
2709 return CMD_SUCCESS;
2710 }
2711
2712 /* policy routing contexts */
2713 DEFUN (show_pbr_iptable,
2714 show_pbr_iptable_cmd,
2715 "show pbr iptable [WORD]",
2716 SHOW_STR
2717 "Policy-Based Routing\n"
2718 "IPtable Context information\n"
2719 "IPtable Name information\n")
2720 {
2721 int idx = 0;
2722 int found = 0;
2723
2724 found = argv_find(argv, argc, "WORD", &idx);
2725 if (!found)
2726 zebra_pbr_show_iptable(vty, NULL);
2727 else
2728 zebra_pbr_show_iptable(vty, argv[idx]->arg);
2729 return CMD_SUCCESS;
2730 }
2731
2732 DEFPY (clear_evpn_dup_addr,
2733 clear_evpn_dup_addr_cmd,
2734 "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>]>",
2735 CLEAR_STR
2736 "EVPN\n"
2737 "Duplicate address \n"
2738 "VxLAN Network Identifier\n"
2739 "VNI number\n"
2740 "All VNIs\n"
2741 "MAC\n"
2742 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2743 "IP\n"
2744 "IPv4 address\n"
2745 "IPv6 address\n")
2746 {
2747 struct zebra_vrf *zvrf;
2748 struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
2749 int ret = CMD_SUCCESS;
2750
2751 zvrf = zebra_vrf_get_evpn();
2752 if (vni_str) {
2753 if (!is_zero_mac(&mac->eth_addr)) {
2754 ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
2755 vni,
2756 &mac->eth_addr);
2757 } else if (ip) {
2758 if (sockunion_family(ip) == AF_INET) {
2759 host_ip.ipa_type = IPADDR_V4;
2760 host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
2761 } else {
2762 host_ip.ipa_type = IPADDR_V6;
2763 memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
2764 sizeof(struct in6_addr));
2765 }
2766 ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
2767 vni,
2768 &host_ip);
2769 } else
2770 ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
2771
2772 } else {
2773 ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
2774 }
2775
2776 return ret;
2777 }
2778
2779 /* Static ip route configuration write function. */
2780 static int zebra_ip_config(struct vty *vty)
2781 {
2782 int write = 0;
2783
2784 write += zebra_import_table_config(vty, VRF_DEFAULT);
2785
2786 return write;
2787 }
2788
2789 DEFUN (ip_zebra_import_table_distance,
2790 ip_zebra_import_table_distance_cmd,
2791 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2792 IP_STR
2793 "import routes from non-main kernel table\n"
2794 "kernel routing table id\n"
2795 "Distance for imported routes\n"
2796 "Default distance value\n"
2797 "route-map for filtering\n"
2798 "route-map name\n")
2799 {
2800 uint32_t table_id = 0;
2801
2802 table_id = strtoul(argv[2]->arg, NULL, 10);
2803 int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
2804 char *rmap =
2805 strmatch(argv[argc - 2]->text, "route-map")
2806 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg)
2807 : NULL;
2808 int ret;
2809
2810 if (argc == 7 || (argc == 5 && !rmap))
2811 distance = strtoul(argv[4]->arg, NULL, 10);
2812
2813 if (!is_zebra_valid_kernel_table(table_id)) {
2814 vty_out(vty,
2815 "Invalid routing table ID, %d. Must be in range 1-252\n",
2816 table_id);
2817 if (rmap)
2818 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2819 return CMD_WARNING;
2820 }
2821
2822 if (is_zebra_main_routing_table(table_id)) {
2823 vty_out(vty,
2824 "Invalid routing table ID, %d. Must be non-default table\n",
2825 table_id);
2826 if (rmap)
2827 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2828 return CMD_WARNING;
2829 }
2830
2831 ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id,
2832 distance, rmap, 1);
2833 if (rmap)
2834 XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
2835
2836 return ret;
2837 }
2838
2839 DEFUN_HIDDEN (zebra_packet_process,
2840 zebra_packet_process_cmd,
2841 "zebra zapi-packets (1-10000)",
2842 ZEBRA_STR
2843 "Zapi Protocol\n"
2844 "Number of packets to process before relinquishing thread\n")
2845 {
2846 uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
2847
2848 atomic_store_explicit(&zrouter.packets_to_process, packets,
2849 memory_order_relaxed);
2850
2851 return CMD_SUCCESS;
2852 }
2853
2854 DEFUN_HIDDEN (no_zebra_packet_process,
2855 no_zebra_packet_process_cmd,
2856 "no zebra zapi-packets [(1-10000)]",
2857 NO_STR
2858 ZEBRA_STR
2859 "Zapi Protocol\n"
2860 "Number of packets to process before relinquishing thread\n")
2861 {
2862 atomic_store_explicit(&zrouter.packets_to_process,
2863 ZEBRA_ZAPI_PACKETS_TO_PROCESS,
2864 memory_order_relaxed);
2865
2866 return CMD_SUCCESS;
2867 }
2868
2869 DEFUN_HIDDEN (zebra_workqueue_timer,
2870 zebra_workqueue_timer_cmd,
2871 "zebra work-queue (0-10000)",
2872 ZEBRA_STR
2873 "Work Queue\n"
2874 "Time in milliseconds\n")
2875 {
2876 uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
2877 zrouter.ribq->spec.hold = timer;
2878
2879 return CMD_SUCCESS;
2880 }
2881
2882 DEFUN_HIDDEN (no_zebra_workqueue_timer,
2883 no_zebra_workqueue_timer_cmd,
2884 "no zebra work-queue [(0-10000)]",
2885 NO_STR
2886 ZEBRA_STR
2887 "Work Queue\n"
2888 "Time in milliseconds\n")
2889 {
2890 zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
2891
2892 return CMD_SUCCESS;
2893 }
2894
2895 DEFUN (no_ip_zebra_import_table,
2896 no_ip_zebra_import_table_cmd,
2897 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2898 NO_STR
2899 IP_STR
2900 "import routes from non-main kernel table\n"
2901 "kernel routing table id\n"
2902 "Distance for imported routes\n"
2903 "Default distance value\n"
2904 "route-map for filtering\n"
2905 "route-map name\n")
2906 {
2907 uint32_t table_id = 0;
2908 table_id = strtoul(argv[3]->arg, NULL, 10);
2909
2910 if (!is_zebra_valid_kernel_table(table_id)) {
2911 vty_out(vty,
2912 "Invalid routing table ID. Must be in range 1-252\n");
2913 return CMD_WARNING;
2914 }
2915
2916 if (is_zebra_main_routing_table(table_id)) {
2917 vty_out(vty,
2918 "Invalid routing table ID, %d. Must be non-default table\n",
2919 table_id);
2920 return CMD_WARNING;
2921 }
2922
2923 if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id))
2924 return CMD_SUCCESS;
2925
2926 return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0));
2927 }
2928
2929 static int config_write_protocol(struct vty *vty)
2930 {
2931 if (allow_delete)
2932 vty_out(vty, "allow-external-route-update\n");
2933
2934 if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
2935 vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
2936
2937 if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
2938 vty_out(vty, "zebra zapi-packets %u\n",
2939 zrouter.packets_to_process);
2940
2941 enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
2942
2943 if (ipv4_multicast_mode != MCAST_NO_CONFIG)
2944 vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
2945 ipv4_multicast_mode == MCAST_URIB_ONLY
2946 ? "urib-only"
2947 : ipv4_multicast_mode == MCAST_MRIB_ONLY
2948 ? "mrib-only"
2949 : ipv4_multicast_mode
2950 == MCAST_MIX_MRIB_FIRST
2951 ? "mrib-then-urib"
2952 : ipv4_multicast_mode
2953 == MCAST_MIX_DISTANCE
2954 ? "lower-distance"
2955 : "longer-prefix");
2956
2957 /* Include dataplane info */
2958 dplane_config_write_helper(vty);
2959
2960 return 1;
2961 }
2962
2963 DEFUN (show_zebra,
2964 show_zebra_cmd,
2965 "show zebra",
2966 SHOW_STR
2967 ZEBRA_STR)
2968 {
2969 struct vrf *vrf;
2970
2971 vty_out(vty,
2972 " Route Route Neighbor LSP LSP\n");
2973 vty_out(vty,
2974 "VRF Installs Removals Updates Installs Removals\n");
2975
2976 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
2977 struct zebra_vrf *zvrf = vrf->info;
2978
2979 vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
2980 " %10" PRIu64 " %10" PRIu64 "\n",
2981 vrf->name, zvrf->installs, zvrf->removals,
2982 zvrf->neigh_updates, zvrf->lsp_installs,
2983 zvrf->lsp_removals);
2984 }
2985
2986 return CMD_SUCCESS;
2987 }
2988
2989 DEFUN (ip_forwarding,
2990 ip_forwarding_cmd,
2991 "ip forwarding",
2992 IP_STR
2993 "Turn on IP forwarding\n")
2994 {
2995 int ret;
2996
2997 ret = ipforward();
2998 if (ret == 0)
2999 ret = ipforward_on();
3000
3001 if (ret == 0) {
3002 vty_out(vty, "Can't turn on IP forwarding\n");
3003 return CMD_WARNING_CONFIG_FAILED;
3004 }
3005
3006 return CMD_SUCCESS;
3007 }
3008
3009 DEFUN (no_ip_forwarding,
3010 no_ip_forwarding_cmd,
3011 "no ip forwarding",
3012 NO_STR
3013 IP_STR
3014 "Turn off IP forwarding\n")
3015 {
3016 int ret;
3017
3018 ret = ipforward();
3019 if (ret != 0)
3020 ret = ipforward_off();
3021
3022 if (ret != 0) {
3023 vty_out(vty, "Can't turn off IP forwarding\n");
3024 return CMD_WARNING_CONFIG_FAILED;
3025 }
3026
3027 return CMD_SUCCESS;
3028 }
3029
3030 /* Only display ip forwarding is enabled or not. */
3031 DEFUN (show_ip_forwarding,
3032 show_ip_forwarding_cmd,
3033 "show ip forwarding",
3034 SHOW_STR
3035 IP_STR
3036 "IP forwarding status\n")
3037 {
3038 int ret;
3039
3040 ret = ipforward();
3041
3042 if (ret == 0)
3043 vty_out(vty, "IP forwarding is off\n");
3044 else
3045 vty_out(vty, "IP forwarding is on\n");
3046 return CMD_SUCCESS;
3047 }
3048
3049 /* Only display ipv6 forwarding is enabled or not. */
3050 DEFUN (show_ipv6_forwarding,
3051 show_ipv6_forwarding_cmd,
3052 "show ipv6 forwarding",
3053 SHOW_STR
3054 "IPv6 information\n"
3055 "Forwarding status\n")
3056 {
3057 int ret;
3058
3059 ret = ipforward_ipv6();
3060
3061 switch (ret) {
3062 case -1:
3063 vty_out(vty, "ipv6 forwarding is unknown\n");
3064 break;
3065 case 0:
3066 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3067 break;
3068 case 1:
3069 vty_out(vty, "ipv6 forwarding is %s\n", "on");
3070 break;
3071 default:
3072 vty_out(vty, "ipv6 forwarding is %s\n", "off");
3073 break;
3074 }
3075 return CMD_SUCCESS;
3076 }
3077
3078 DEFUN (ipv6_forwarding,
3079 ipv6_forwarding_cmd,
3080 "ipv6 forwarding",
3081 IPV6_STR
3082 "Turn on IPv6 forwarding\n")
3083 {
3084 int ret;
3085
3086 ret = ipforward_ipv6();
3087 if (ret == 0)
3088 ret = ipforward_ipv6_on();
3089
3090 if (ret == 0) {
3091 vty_out(vty, "Can't turn on IPv6 forwarding\n");
3092 return CMD_WARNING_CONFIG_FAILED;
3093 }
3094
3095 return CMD_SUCCESS;
3096 }
3097
3098 DEFUN (no_ipv6_forwarding,
3099 no_ipv6_forwarding_cmd,
3100 "no ipv6 forwarding",
3101 NO_STR
3102 IPV6_STR
3103 "Turn off IPv6 forwarding\n")
3104 {
3105 int ret;
3106
3107 ret = ipforward_ipv6();
3108 if (ret != 0)
3109 ret = ipforward_ipv6_off();
3110
3111 if (ret != 0) {
3112 vty_out(vty, "Can't turn off IPv6 forwarding\n");
3113 return CMD_WARNING_CONFIG_FAILED;
3114 }
3115
3116 return CMD_SUCCESS;
3117 }
3118
3119 /* Display dataplane info */
3120 DEFUN (show_dataplane,
3121 show_dataplane_cmd,
3122 "show zebra dplane [detailed]",
3123 SHOW_STR
3124 ZEBRA_STR
3125 "Zebra dataplane information\n"
3126 "Detailed output\n")
3127 {
3128 int idx = 0;
3129 bool detailed = false;
3130
3131 if (argv_find(argv, argc, "detailed", &idx))
3132 detailed = true;
3133
3134 return dplane_show_helper(vty, detailed);
3135 }
3136
3137 /* Display dataplane providers info */
3138 DEFUN (show_dataplane_providers,
3139 show_dataplane_providers_cmd,
3140 "show zebra dplane providers [detailed]",
3141 SHOW_STR
3142 ZEBRA_STR
3143 "Zebra dataplane information\n"
3144 "Zebra dataplane provider information\n"
3145 "Detailed output\n")
3146 {
3147 int idx = 0;
3148 bool detailed = false;
3149
3150 if (argv_find(argv, argc, "detailed", &idx))
3151 detailed = true;
3152
3153 return dplane_show_provs_helper(vty, detailed);
3154 }
3155
3156 /* Configure dataplane incoming queue limit */
3157 DEFUN (zebra_dplane_queue_limit,
3158 zebra_dplane_queue_limit_cmd,
3159 "zebra dplane limit (0-10000)",
3160 ZEBRA_STR
3161 "Zebra dataplane\n"
3162 "Limit incoming queued updates\n"
3163 "Number of queued updates\n")
3164 {
3165 uint32_t limit = 0;
3166
3167 limit = strtoul(argv[3]->arg, NULL, 10);
3168
3169 dplane_set_in_queue_limit(limit, true);
3170
3171 return CMD_SUCCESS;
3172 }
3173
3174 /* Reset dataplane queue limit to default value */
3175 DEFUN (no_zebra_dplane_queue_limit,
3176 no_zebra_dplane_queue_limit_cmd,
3177 "no zebra dplane limit [(0-10000)]",
3178 NO_STR
3179 ZEBRA_STR
3180 "Zebra dataplane\n"
3181 "Limit incoming queued updates\n"
3182 "Number of queued updates\n")
3183 {
3184 dplane_set_in_queue_limit(0, false);
3185
3186 return CMD_SUCCESS;
3187 }
3188
3189 DEFUN (zebra_show_routing_tables_summary,
3190 zebra_show_routing_tables_summary_cmd,
3191 "show zebra router table summary",
3192 SHOW_STR
3193 ZEBRA_STR
3194 "The Zebra Router Information\n"
3195 "Table Information about this Zebra Router\n"
3196 "Summary Information\n")
3197 {
3198 zebra_router_show_table_summary(vty);
3199
3200 return CMD_SUCCESS;
3201 }
3202
3203 /* Table configuration write function. */
3204 static int config_write_table(struct vty *vty)
3205 {
3206 return 0;
3207 }
3208
3209 /* IPForwarding configuration write function. */
3210 static int config_write_forwarding(struct vty *vty)
3211 {
3212 /* FIXME: Find better place for that. */
3213 router_id_write(vty);
3214
3215 if (!ipforward())
3216 vty_out(vty, "no ip forwarding\n");
3217 if (!ipforward_ipv6())
3218 vty_out(vty, "no ipv6 forwarding\n");
3219 vty_out(vty, "!\n");
3220 return 0;
3221 }
3222
3223 DEFUN_HIDDEN (show_frr,
3224 show_frr_cmd,
3225 "show frr",
3226 SHOW_STR
3227 "FRR\n")
3228 {
3229 vty_out(vty, "........ .. . .. . ..... ...77:................................................\n");
3230 vty_out(vty, ".............................7777:..............................................\n");
3231 vty_out(vty, ".............................777777,............................................\n");
3232 vty_out(vty, "... .........................77777777,..........................................\n");
3233 vty_out(vty, "............................=7777777777:........................................\n");
3234 vty_out(vty, "........................:7777777777777777,......................................\n");
3235 vty_out(vty, ".................... ~7777777777777?~,..........................................\n");
3236 vty_out(vty, "...................I7777777777+.................................................\n");
3237 vty_out(vty, "................,777777777?............ .......................................\n");
3238 vty_out(vty, "..............:77777777?..........~?77777.......................................\n");
3239 vty_out(vty, ".............77777777~........=7777777777.......................................\n");
3240 vty_out(vty, ".......... +7777777,.......?7777777777777.......................................\n");
3241 vty_out(vty, "..........7777777~......:7777777777777777......77?,.............................\n");
3242 vty_out(vty, "........:777777?......+777777777777777777......777777I,.........................\n");
3243 vty_out(vty, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3244 vty_out(vty, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3245 vty_out(vty, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3246 vty_out(vty, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3247 vty_out(vty, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3248 vty_out(vty, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3249 vty_out(vty, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3250 vty_out(vty, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3251 vty_out(vty, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3252 vty_out(vty, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3253 vty_out(vty, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3254 vty_out(vty, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3255 vty_out(vty, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3256 vty_out(vty, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3257 vty_out(vty, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3258 vty_out(vty, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3259 vty_out(vty, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3260 vty_out(vty, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3261 vty_out(vty, "..........777777777777......7777777777777..................77777777777777777,...\n");
3262 vty_out(vty, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3263 vty_out(vty, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3264 vty_out(vty, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3265 vty_out(vty, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3266 vty_out(vty, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3267 vty_out(vty, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3268 vty_out(vty, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3269 vty_out(vty, "..............~777777777777777~................777777......:77777=..............\n");
3270 vty_out(vty, "...............:7777777777777777?..............:777777,.....=77=................\n");
3271 vty_out(vty, "................,777777777777777777?,...........,777777:.....,..................\n");
3272 vty_out(vty, "........... ......I777777777777777777777I.........777777~.......................\n");
3273 vty_out(vty, "...................,777777777777777777777..........777777+......................\n");
3274 vty_out(vty, ".....................+7777777777777777777...........777777?.....................\n");
3275 vty_out(vty, ".......................=77777777777777777............777777I....................\n");
3276 vty_out(vty, ".........................:777777777777777.............I77777I...................\n");
3277 vty_out(vty, "............................~777777777777..............+777777..................\n");
3278 vty_out(vty, "................................~77777777...............=777777.................\n");
3279 vty_out(vty, ".....................................:=?I................~777777................\n");
3280 vty_out(vty, "..........................................................:777777,..............\n");
3281 vty_out(vty, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3282
3283 return CMD_SUCCESS;
3284 }
3285
3286 /* IP node for static routes. */
3287 static struct cmd_node ip_node = {IP_NODE, "", 1};
3288 static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
3289 /* table node for routing tables. */
3290 static struct cmd_node table_node = {TABLE_NODE,
3291 "", /* This node has no interface. */
3292 1};
3293 static struct cmd_node forwarding_node = {FORWARDING_NODE,
3294 "", /* This node has no interface. */
3295 1};
3296
3297 /* Route VTY. */
3298 void zebra_vty_init(void)
3299 {
3300 /* Install configuration write function. */
3301 install_node(&table_node, config_write_table);
3302 install_node(&forwarding_node, config_write_forwarding);
3303
3304 install_element(VIEW_NODE, &show_ip_forwarding_cmd);
3305 install_element(CONFIG_NODE, &ip_forwarding_cmd);
3306 install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
3307 install_element(ENABLE_NODE, &show_zebra_cmd);
3308
3309 install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
3310 install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
3311 install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
3312
3313 /* Route-map */
3314 zebra_route_map_init();
3315
3316 install_node(&ip_node, zebra_ip_config);
3317 install_node(&protocol_node, config_write_protocol);
3318
3319 install_element(CONFIG_NODE, &allow_external_route_update_cmd);
3320 install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
3321
3322 install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
3323 install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
3324
3325 install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
3326 install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
3327 install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
3328 install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
3329 install_element(CONFIG_NODE, &zebra_packet_process_cmd);
3330 install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
3331
3332 install_element(VIEW_NODE, &show_nexthop_group_cmd);
3333 install_element(VIEW_NODE, &show_interface_nexthop_group_cmd);
3334
3335 install_element(VIEW_NODE, &show_vrf_cmd);
3336 install_element(VIEW_NODE, &show_vrf_vni_cmd);
3337 install_element(VIEW_NODE, &show_route_cmd);
3338 install_element(VIEW_NODE, &show_route_table_cmd);
3339 if (vrf_is_backend_netns())
3340 install_element(VIEW_NODE, &show_route_table_vrf_cmd);
3341 install_element(VIEW_NODE, &show_route_all_table_vrf_cmd);
3342 install_element(VIEW_NODE, &show_route_detail_cmd);
3343 install_element(VIEW_NODE, &show_route_summary_cmd);
3344 install_element(VIEW_NODE, &show_ip_nht_cmd);
3345
3346 install_element(VIEW_NODE, &show_ip_rpf_cmd);
3347 install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
3348
3349 install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
3350 install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);
3351 install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd);
3352 install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
3353 install_element(VRF_NODE, &ip_nht_default_route_cmd);
3354 install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
3355 install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
3356 install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
3357 install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
3358
3359 /* Commands for VRF */
3360 install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
3361
3362 install_element(VIEW_NODE, &show_frr_cmd);
3363 install_element(VIEW_NODE, &show_evpn_global_cmd);
3364 install_element(VIEW_NODE, &show_evpn_vni_cmd);
3365 install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
3366 install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
3367 install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
3368 install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
3369 install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
3370 install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
3371 install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
3372 install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
3373 install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
3374 install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
3375 install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
3376 install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
3377 install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
3378 install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
3379 install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
3380 install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
3381 install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
3382 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
3383 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
3384 install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
3385 install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
3386 install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
3387 install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
3388 install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
3389
3390 install_element(VIEW_NODE, &show_pbr_ipset_cmd);
3391 install_element(VIEW_NODE, &show_pbr_iptable_cmd);
3392
3393 install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
3394 install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
3395 install_element(VRF_NODE, &vrf_vni_mapping_cmd);
3396 install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
3397
3398 install_element(VIEW_NODE, &show_dataplane_cmd);
3399 install_element(VIEW_NODE, &show_dataplane_providers_cmd);
3400 install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
3401 install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
3402
3403 install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
3404 }