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