2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
24 #include "zebra_memory.h"
35 #include "srcdest_table.h"
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"
46 #include "zebra/zebra_vxlan.h"
47 #ifndef VTYSH_EXTRACT_PL
48 #include "zebra/zebra_vty_clippy.c"
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"
58 extern int allow_delete
;
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
,
63 const struct prefix
*longer_prefix_p
,
64 bool supernets_only
, int type
,
65 unsigned short ospf_instance_id
);
66 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
67 int mcast
, bool use_fib
, bool show_ng
);
68 static void vty_show_ip_route_summary(struct vty
*vty
,
69 struct route_table
*table
, bool use_json
);
70 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
71 struct route_table
*table
,
74 DEFUN (ip_multicast_mode
,
75 ip_multicast_mode_cmd
,
76 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
79 "RPF lookup behavior\n"
80 "Lookup in unicast RIB only\n"
81 "Lookup in multicast RIB only\n"
82 "Try multicast RIB first, fall back to unicast RIB\n"
83 "Lookup both, use entry with lower distance\n"
84 "Lookup both, use entry with longer prefix\n")
86 char *mode
= argv
[3]->text
;
88 if (strmatch(mode
, "urib-only"))
89 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
90 else if (strmatch(mode
, "mrib-only"))
91 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
92 else if (strmatch(mode
, "mrib-then-urib"))
93 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
94 else if (strmatch(mode
, "lower-distance"))
95 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
96 else if (strmatch(mode
, "longer-prefix"))
97 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
99 vty_out(vty
, "Invalid mode specified\n");
100 return CMD_WARNING_CONFIG_FAILED
;
106 DEFUN (no_ip_multicast_mode
,
107 no_ip_multicast_mode_cmd
,
108 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
111 "Multicast options\n"
112 "RPF lookup behavior\n"
113 "Lookup in unicast RIB only\n"
114 "Lookup in multicast RIB only\n"
115 "Try multicast RIB first, fall back to unicast RIB\n"
116 "Lookup both, use entry with lower distance\n"
117 "Lookup both, use entry with longer prefix\n")
119 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
126 "show ip rpf [json]",
129 "Display RPF information for multicast source\n"
132 bool uj
= use_json(argc
, argv
);
133 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
134 false, uj
, 0, NULL
, false, 0, 0);
137 DEFUN (show_ip_rpf_addr
,
138 show_ip_rpf_addr_cmd
,
139 "show ip rpf A.B.C.D",
142 "Display RPF information for multicast source\n"
143 "IP multicast source address (e.g. 10.0.0.0)\n")
147 struct route_node
*rn
;
148 struct route_entry
*re
;
151 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
153 vty_out(vty
, "%% Malformed address\n");
157 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
160 vty_show_ip_route_detail(vty
, rn
, 1, false, false);
162 vty_out(vty
, "%% No match for RPF lookup\n");
167 static char re_status_output_char(struct route_entry
*re
, struct nexthop
*nhop
)
169 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
170 if (!CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
171 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
177 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
178 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
184 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
190 /* New RIB. Detailed information for IPv4 route. */
191 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
192 int mcast
, bool use_fib
, bool show_ng
)
194 struct route_entry
*re
;
195 struct nexthop
*nexthop
;
196 char buf
[SRCDEST2STR_BUFFER
];
197 struct zebra_vrf
*zvrf
;
200 dest
= rib_dest_from_rnode(rn
);
202 RNODE_FOREACH_RE (rn
, re
) {
204 * If re not selected for forwarding, skip re
205 * for "show ip/ipv6 fib <prefix>"
207 if (use_fib
&& re
!= dest
->selected_fib
)
210 const char *mcast_info
= "";
212 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
213 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
214 ? " using Multicast RIB"
215 : " using Unicast RIB";
218 vty_out(vty
, "Routing entry for %s%s\n",
219 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
220 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
222 vty_out(vty
, "[%d]", re
->instance
);
224 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
227 vty_out(vty
, ", tag %u", re
->tag
);
228 #if defined(SUPPORT_REALMS)
229 if (re
->tag
> 0 && re
->tag
<= 255)
230 vty_out(vty
, "(realm)");
234 vty_out(vty
, ", mtu %u", re
->mtu
);
235 if (re
->vrf_id
!= VRF_DEFAULT
) {
236 zvrf
= vrf_info_lookup(re
->vrf_id
);
237 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
239 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
240 vty_out(vty
, ", best");
246 uptime
= monotime(NULL
);
247 uptime
-= re
->uptime
;
248 tm
= gmtime(&uptime
);
250 vty_out(vty
, " Last update ");
252 if (uptime
< ONE_DAY_SECOND
)
253 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
255 else if (uptime
< ONE_WEEK_SECOND
)
256 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
259 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
260 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
262 vty_out(vty
, " ago\n");
265 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
267 for (ALL_NEXTHOPS_PTR(re
->nhe
->nhg
, nexthop
)) {
270 vty_out(vty
, " %c%s",
271 re_status_output_char(re
, nexthop
),
272 nexthop
->rparent
? " " : "");
274 switch (nexthop
->type
) {
275 case NEXTHOP_TYPE_IPV4
:
276 case NEXTHOP_TYPE_IPV4_IFINDEX
:
278 inet_ntoa(nexthop
->gate
.ipv4
));
279 if (nexthop
->ifindex
)
280 vty_out(vty
, ", via %s",
285 case NEXTHOP_TYPE_IPV6
:
286 case NEXTHOP_TYPE_IPV6_IFINDEX
:
288 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
290 if (nexthop
->ifindex
)
291 vty_out(vty
, ", via %s",
296 case NEXTHOP_TYPE_IFINDEX
:
297 vty_out(vty
, " directly connected, %s",
298 ifindex2ifname(nexthop
->ifindex
,
301 case NEXTHOP_TYPE_BLACKHOLE
:
302 vty_out(vty
, " unreachable");
303 switch (nexthop
->bh_type
) {
304 case BLACKHOLE_REJECT
:
305 vty_out(vty
, " (ICMP unreachable)");
307 case BLACKHOLE_ADMINPROHIB
:
309 " (ICMP admin-prohibited)");
312 vty_out(vty
, " (blackhole)");
314 case BLACKHOLE_UNSPEC
:
322 if ((re
->vrf_id
!= nexthop
->vrf_id
)
323 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
325 vrf_lookup_by_id(nexthop
->vrf_id
);
328 vty_out(vty
, "(vrf %s)", vrf
->name
);
330 vty_out(vty
, "(vrf UNKNOWN)");
333 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
334 vty_out(vty
, " (duplicate nexthop removed)");
336 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
337 vty_out(vty
, " inactive");
339 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
340 vty_out(vty
, " onlink");
342 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
343 vty_out(vty
, " (recursive)");
345 switch (nexthop
->type
) {
346 case NEXTHOP_TYPE_IPV4
:
347 case NEXTHOP_TYPE_IPV4_IFINDEX
:
348 if (nexthop
->src
.ipv4
.s_addr
) {
349 if (inet_ntop(AF_INET
,
351 addrstr
, sizeof addrstr
))
352 vty_out(vty
, ", src %s",
356 case NEXTHOP_TYPE_IPV6
:
357 case NEXTHOP_TYPE_IPV6_IFINDEX
:
358 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
360 if (inet_ntop(AF_INET6
,
362 addrstr
, sizeof addrstr
))
363 vty_out(vty
, ", src %s",
372 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
374 /* Label information */
375 if (nexthop
->nh_label
376 && nexthop
->nh_label
->num_labels
) {
377 vty_out(vty
, ", label %s",
379 nexthop
->nh_label
->num_labels
,
380 nexthop
->nh_label
->label
, buf
,
385 vty_out(vty
, ", weight %u", nexthop
->weight
);
393 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
394 struct route_entry
*re
, json_object
*json
,
397 struct nexthop
*nexthop
;
399 char buf
[SRCDEST2STR_BUFFER
];
400 json_object
*json_nexthops
= NULL
;
401 json_object
*json_nexthop
= NULL
;
402 json_object
*json_route
= NULL
;
403 json_object
*json_labels
= NULL
;
406 struct vrf
*vrf
= NULL
;
407 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
408 struct nexthop_group
*nhg
;
410 uptime
= monotime(NULL
);
411 uptime
-= re
->uptime
;
412 tm
= gmtime(&uptime
);
414 /* If showing fib information, use the fib view of the
418 nhg
= rib_active_nhg(re
);
423 json_route
= json_object_new_object();
424 json_nexthops
= json_object_new_array();
426 json_object_string_add(json_route
, "prefix",
427 srcdest_rnode2str(rn
, buf
, sizeof buf
));
428 json_object_string_add(json_route
, "protocol",
429 zebra_route_string(re
->type
));
432 json_object_int_add(json_route
, "instance",
436 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
437 vrf
= vrf_lookup_by_id(re
->vrf_id
);
438 json_object_string_add(json_route
, "vrfName",
442 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
443 json_object_boolean_true_add(json_route
, "selected");
445 if (dest
->selected_fib
== re
)
446 json_object_boolean_true_add(json_route
,
449 json_object_int_add(json_route
, "distance",
451 json_object_int_add(json_route
, "metric", re
->metric
);
453 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
454 json_object_boolean_true_add(json_route
, "installed");
456 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
457 json_object_boolean_true_add(json_route
, "failed");
459 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
460 json_object_boolean_true_add(json_route
, "queued");
463 json_object_int_add(json_route
, "tag", re
->tag
);
466 json_object_int_add(json_route
, "table", re
->table
);
468 json_object_int_add(json_route
, "internalStatus",
470 json_object_int_add(json_route
, "internalFlags",
472 json_object_int_add(json_route
, "internalNextHopNum",
473 nexthop_group_nexthop_num(re
->nhe
->nhg
));
474 json_object_int_add(json_route
, "internalNextHopActiveNum",
475 nexthop_group_active_nexthop_num(
477 if (uptime
< ONE_DAY_SECOND
)
478 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
480 else if (uptime
< ONE_WEEK_SECOND
)
481 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
484 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
485 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
488 json_object_string_add(json_route
, "uptime", buf
);
490 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
491 json_nexthop
= json_object_new_object();
493 json_object_int_add(json_nexthop
, "flags",
496 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
497 json_object_boolean_true_add(json_nexthop
,
500 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
501 json_object_boolean_true_add(json_nexthop
,
504 switch (nexthop
->type
) {
505 case NEXTHOP_TYPE_IPV4
:
506 case NEXTHOP_TYPE_IPV4_IFINDEX
:
507 json_object_string_add(
509 inet_ntoa(nexthop
->gate
.ipv4
));
510 json_object_string_add(json_nexthop
, "afi",
513 if (nexthop
->ifindex
) {
514 json_object_int_add(json_nexthop
,
517 json_object_string_add(
518 json_nexthop
, "interfaceName",
524 case NEXTHOP_TYPE_IPV6
:
525 case NEXTHOP_TYPE_IPV6_IFINDEX
:
526 json_object_string_add(
528 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
530 json_object_string_add(json_nexthop
, "afi",
533 if (nexthop
->ifindex
) {
534 json_object_int_add(json_nexthop
,
537 json_object_string_add(
538 json_nexthop
, "interfaceName",
545 case NEXTHOP_TYPE_IFINDEX
:
546 json_object_boolean_true_add(
547 json_nexthop
, "directlyConnected");
548 json_object_int_add(json_nexthop
,
551 json_object_string_add(
552 json_nexthop
, "interfaceName",
553 ifindex2ifname(nexthop
->ifindex
,
556 case NEXTHOP_TYPE_BLACKHOLE
:
557 json_object_boolean_true_add(json_nexthop
,
559 switch (nexthop
->bh_type
) {
560 case BLACKHOLE_REJECT
:
561 json_object_boolean_true_add(
562 json_nexthop
, "reject");
564 case BLACKHOLE_ADMINPROHIB
:
565 json_object_boolean_true_add(
570 json_object_boolean_true_add(
571 json_nexthop
, "blackhole");
573 case BLACKHOLE_UNSPEC
:
581 if ((nexthop
->vrf_id
!= re
->vrf_id
)
582 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
583 vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
584 json_object_string_add(json_nexthop
, "vrf",
587 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
588 json_object_boolean_true_add(json_nexthop
,
591 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
592 json_object_boolean_true_add(json_nexthop
,
595 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
596 json_object_boolean_true_add(json_nexthop
,
599 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
600 json_object_boolean_true_add(json_nexthop
,
603 switch (nexthop
->type
) {
604 case NEXTHOP_TYPE_IPV4
:
605 case NEXTHOP_TYPE_IPV4_IFINDEX
:
606 if (nexthop
->src
.ipv4
.s_addr
) {
607 if (inet_ntop(AF_INET
,
608 &nexthop
->src
.ipv4
, buf
,
610 json_object_string_add(
611 json_nexthop
, "source",
615 case NEXTHOP_TYPE_IPV6
:
616 case NEXTHOP_TYPE_IPV6_IFINDEX
:
617 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
619 if (inet_ntop(AF_INET6
,
620 &nexthop
->src
.ipv6
, buf
,
622 json_object_string_add(
623 json_nexthop
, "source",
631 if (nexthop
->nh_label
632 && nexthop
->nh_label
->num_labels
) {
633 json_labels
= json_object_new_array();
635 for (int label_index
= 0;
637 < nexthop
->nh_label
->num_labels
;
639 json_object_array_add(
642 nexthop
->nh_label
->label
645 json_object_object_add(json_nexthop
, "labels",
649 json_object_array_add(json_nexthops
, json_nexthop
);
652 json_object_object_add(json_route
, "nexthops", json_nexthops
);
653 json_object_array_add(json
, json_route
);
657 /* Nexthop information. */
658 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
659 if (nexthop
== nhg
->nexthop
) {
660 /* Prefix information. */
661 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
663 len
+= vty_out(vty
, "[%d]", re
->instance
);
666 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
669 re_status_output_char(re
, nexthop
),
670 srcdest_rnode2str(rn
, buf
, sizeof buf
));
672 /* Distance and metric display. */
673 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
674 (re
->distance
|| re
->metric
)) ||
675 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
676 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
679 vty_out(vty
, " %c%*c",
680 re_status_output_char(re
, nexthop
),
681 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
684 switch (nexthop
->type
) {
685 case NEXTHOP_TYPE_IPV4
:
686 case NEXTHOP_TYPE_IPV4_IFINDEX
:
687 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
688 if (nexthop
->ifindex
)
690 ifindex2ifname(nexthop
->ifindex
,
693 case NEXTHOP_TYPE_IPV6
:
694 case NEXTHOP_TYPE_IPV6_IFINDEX
:
695 vty_out(vty
, " via %s",
696 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
698 if (nexthop
->ifindex
)
700 ifindex2ifname(nexthop
->ifindex
,
704 case NEXTHOP_TYPE_IFINDEX
:
705 vty_out(vty
, " is directly connected, %s",
706 ifindex2ifname(nexthop
->ifindex
,
709 case NEXTHOP_TYPE_BLACKHOLE
:
710 vty_out(vty
, " unreachable");
711 switch (nexthop
->bh_type
) {
712 case BLACKHOLE_REJECT
:
713 vty_out(vty
, " (ICMP unreachable)");
715 case BLACKHOLE_ADMINPROHIB
:
716 vty_out(vty
, " (ICMP admin-prohibited)");
719 vty_out(vty
, " (blackhole)");
721 case BLACKHOLE_UNSPEC
:
729 if ((nexthop
->vrf_id
!= re
->vrf_id
)
730 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
731 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
734 vty_out(vty
, "(vrf %s)", vrf
->name
);
736 vty_out(vty
, "(vrf UNKNOWN)");
739 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
740 vty_out(vty
, " inactive");
742 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
743 vty_out(vty
, " onlink");
745 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
746 vty_out(vty
, " (recursive)");
748 switch (nexthop
->type
) {
749 case NEXTHOP_TYPE_IPV4
:
750 case NEXTHOP_TYPE_IPV4_IFINDEX
:
751 if (nexthop
->src
.ipv4
.s_addr
) {
752 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
754 vty_out(vty
, ", src %s", buf
);
757 case NEXTHOP_TYPE_IPV6
:
758 case NEXTHOP_TYPE_IPV6_IFINDEX
:
759 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
760 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
762 vty_out(vty
, ", src %s", buf
);
769 /* Label information */
770 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
771 vty_out(vty
, ", label %s",
772 mpls_label2str(nexthop
->nh_label
->num_labels
,
773 nexthop
->nh_label
->label
, buf
,
777 if (uptime
< ONE_DAY_SECOND
)
778 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
779 tm
->tm_min
, tm
->tm_sec
);
780 else if (uptime
< ONE_WEEK_SECOND
)
781 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
782 tm
->tm_hour
, tm
->tm_min
);
784 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
785 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
791 static void vty_show_ip_route_detail_json(struct vty
*vty
,
792 struct route_node
*rn
, bool use_fib
)
794 json_object
*json
= NULL
;
795 json_object
*json_prefix
= NULL
;
796 struct route_entry
*re
;
800 dest
= rib_dest_from_rnode(rn
);
802 json
= json_object_new_object();
803 json_prefix
= json_object_new_array();
805 RNODE_FOREACH_RE (rn
, re
) {
807 * If re not selected for forwarding, skip re
808 * for "show ip/ipv6 fib <prefix> json"
810 if (use_fib
&& re
!= dest
->selected_fib
)
812 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
815 prefix2str(&rn
->p
, buf
, sizeof(buf
));
816 json_object_object_add(json
, buf
, json_prefix
);
817 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
818 json
, JSON_C_TO_STRING_PRETTY
));
819 json_object_free(json
);
822 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
823 struct route_table
*table
, afi_t afi
,
824 bool use_fib
, route_tag_t tag
,
825 const struct prefix
*longer_prefix_p
,
826 bool supernets_only
, int type
,
827 unsigned short ospf_instance_id
, bool use_json
,
830 struct route_node
*rn
;
831 struct route_entry
*re
;
834 json_object
*json
= NULL
;
835 json_object
*json_prefix
= NULL
;
840 json
= json_object_new_object();
842 /* Show all routes. */
843 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
844 dest
= rib_dest_from_rnode(rn
);
846 RNODE_FOREACH_RE (rn
, re
) {
847 if (use_fib
&& re
!= dest
->selected_fib
)
850 if (tag
&& re
->tag
!= tag
)
854 && !prefix_match(longer_prefix_p
, &rn
->p
))
857 /* This can only be true when the afi is IPv4 */
858 if (supernets_only
) {
859 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
861 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
864 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
867 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
871 if (type
&& re
->type
!= type
)
875 && (re
->type
!= ZEBRA_ROUTE_OSPF
876 || re
->instance
!= ospf_instance_id
))
881 json_prefix
= json_object_new_array();
886 SHOW_ROUTE_V4_HEADER
);
889 SHOW_ROUTE_V6_HEADER
);
891 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
892 vty_out(vty
, "\nVRF %s table %u:\n",
893 zvrf_name(zvrf
), tableid
);
894 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
895 vty_out(vty
, "\nVRF %s:\n",
901 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
905 prefix2str(&rn
->p
, buf
, sizeof(buf
));
906 json_object_object_add(json
, buf
, json_prefix
);
912 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
913 JSON_C_TO_STRING_PRETTY
));
914 json_object_free(json
);
918 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
919 safi_t safi
, bool use_fib
, bool use_json
,
921 const struct prefix
*longer_prefix_p
,
922 bool supernets_only
, int type
,
923 unsigned short ospf_instance_id
)
925 struct route_table
*table
;
926 struct zebra_vrf
*zvrf
= NULL
;
928 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
930 vty_out(vty
, "{}\n");
932 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
936 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
938 vty_out(vty
, "{}\n");
940 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
944 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
947 vty_out(vty
, "{}\n");
951 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
952 longer_prefix_p
, supernets_only
, type
,
953 ospf_instance_id
, use_json
, 0);
958 DEFPY (show_route_table
,
959 show_route_table_cmd
,
960 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
966 "The table number to display, if available\n"
969 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
970 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
971 struct route_table
*t
;
973 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
975 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
976 0, 0, !!json
, table
);
981 DEFPY (show_route_table_vrf
,
982 show_route_table_vrf_cmd
,
983 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
989 "The table number to display, if available\n"
993 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
994 struct zebra_vrf
*zvrf
;
995 struct route_table
*t
;
996 vrf_id_t vrf_id
= VRF_DEFAULT
;
999 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1000 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1002 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
1004 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
1005 0, 0, !!json
, table
);
1010 DEFPY (show_route_all_table_vrf
,
1011 show_route_all_table_vrf_cmd
,
1012 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1016 "IP routing table\n"
1017 "Display all tables\n"
1018 VRF_FULL_CMD_HELP_STR
1021 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1022 struct zebra_vrf
*zvrf
= NULL
;
1023 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1024 struct zebra_router_table
*zrt
;
1027 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1028 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1031 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1032 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1034 if (zvrf
&& zvrf
!= info
->zvrf
)
1036 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1039 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
, false, 0,
1040 false, false, 0, 0, !!json
, zrt
->tableid
);
1047 "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]",
1051 "IP nexthop tracking table\n"
1052 "IP import check tracking table\n"
1058 VRF_ALL_CMD_HELP_STR
)
1060 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1061 vrf_id_t vrf_id
= VRF_DEFAULT
;
1062 struct prefix prefix
, *p
= NULL
;
1065 if (strcmp(type
, "nht") == 0)
1066 rtype
= RNH_NEXTHOP_TYPE
;
1068 rtype
= RNH_IMPORT_CHECK_TYPE
;
1072 struct zebra_vrf
*zvrf
;
1074 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1075 if ((zvrf
= vrf
->info
) != NULL
) {
1076 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1077 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1083 VRF_GET_ID(vrf_id
, vrf_name
, false);
1085 memset(&prefix
, 0, sizeof(prefix
));
1087 p
= sockunion2hostprefix(addr
, &prefix
);
1089 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1093 DEFUN (ip_nht_default_route
,
1094 ip_nht_default_route_cmd
,
1095 "ip nht resolve-via-default",
1097 "Filter Next Hop tracking route resolution\n"
1098 "Resolve via default route\n")
1100 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1105 if (zvrf
->zebra_rnh_ip_default_route
)
1108 zvrf
->zebra_rnh_ip_default_route
= 1;
1110 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1114 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1116 struct nexthop
*nexthop
= NULL
;
1117 struct nhg_connected
*rb_node_dep
= NULL
;
1118 char buf
[SRCDEST2STR_BUFFER
];
1120 struct vrf
*nhe_vrf
= vrf_lookup_by_id(nhe
->vrf_id
);
1122 vty_out(vty
, "ID: %u\n", nhe
->id
);
1123 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1126 vty_out(vty
, " VRF: %s AFI: %s\n", nhe_vrf
->name
,
1129 vty_out(vty
, " VRF: UNKNOWN AFI: %s\n",
1132 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_UNHASHABLE
))
1133 vty_out(vty
, " Duplicate - from kernel not hashable\n");
1135 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1136 vty_out(vty
, " Valid");
1137 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1138 vty_out(vty
, ", Installed");
1142 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1144 if (!zebra_nhg_depends_is_empty(nhe
)) {
1145 vty_out(vty
, " Depends:");
1146 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1147 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1152 for (ALL_NEXTHOPS_PTR(nhe
->nhg
, nexthop
)) {
1153 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1156 /* Make recursive nexthops a bit more clear */
1159 switch (nexthop
->type
) {
1160 case NEXTHOP_TYPE_IPV4
:
1161 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1162 vty_out(vty
, " %s", inet_ntoa(nexthop
->gate
.ipv4
));
1163 if (nexthop
->ifindex
)
1164 vty_out(vty
, ", %s",
1165 ifindex2ifname(nexthop
->ifindex
,
1168 case NEXTHOP_TYPE_IPV6
:
1169 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1171 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1173 if (nexthop
->ifindex
)
1174 vty_out(vty
, ", %s",
1175 ifindex2ifname(nexthop
->ifindex
,
1179 case NEXTHOP_TYPE_IFINDEX
:
1180 vty_out(vty
, " directly connected %s",
1181 ifindex2ifname(nexthop
->ifindex
,
1184 case NEXTHOP_TYPE_BLACKHOLE
:
1185 vty_out(vty
, " unreachable");
1186 switch (nexthop
->bh_type
) {
1187 case BLACKHOLE_REJECT
:
1188 vty_out(vty
, " (ICMP unreachable)");
1190 case BLACKHOLE_ADMINPROHIB
:
1191 vty_out(vty
, " (ICMP admin-prohibited)");
1193 case BLACKHOLE_NULL
:
1194 vty_out(vty
, " (blackhole)");
1196 case BLACKHOLE_UNSPEC
:
1204 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1207 vty_out(vty
, " (vrf %s)", vrf
->name
);
1209 vty_out(vty
, " (vrf UNKNOWN)");
1211 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1212 vty_out(vty
, " inactive");
1214 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1215 vty_out(vty
, " onlink");
1217 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1218 vty_out(vty
, " (recursive)");
1220 switch (nexthop
->type
) {
1221 case NEXTHOP_TYPE_IPV4
:
1222 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1223 if (nexthop
->src
.ipv4
.s_addr
) {
1224 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1226 vty_out(vty
, ", src %s", buf
);
1229 case NEXTHOP_TYPE_IPV6
:
1230 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1231 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1232 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1234 vty_out(vty
, ", src %s", buf
);
1241 /* Label information */
1242 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1243 vty_out(vty
, ", label %s",
1244 mpls_label2str(nexthop
->nh_label
->num_labels
,
1245 nexthop
->nh_label
->label
, buf
,
1249 if (nexthop
->weight
)
1250 vty_out(vty
, ", weight %u", nexthop
->weight
);
1255 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1256 vty_out(vty
, " Dependents:");
1257 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1259 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1266 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1268 struct nhg_hash_entry
*nhe
= NULL
;
1270 nhe
= zebra_nhg_lookup_id(id
);
1273 show_nexthop_group_out(vty
, nhe
);
1275 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1281 /* Helper function for iteration through the hash of nexthop-groups/nhe-s */
1283 struct nhe_show_context
{
1289 static int nhe_show_walker(struct hash_bucket
*bucket
, void *arg
)
1291 struct nhe_show_context
*ctx
= arg
;
1292 struct nhg_hash_entry
*nhe
;
1294 nhe
= bucket
->data
; /* We won't be offered NULL buckets */
1296 if (ctx
->afi
&& nhe
->afi
!= ctx
->afi
)
1299 if (ctx
->vrf_id
&& nhe
->vrf_id
!= ctx
->vrf_id
)
1302 show_nexthop_group_out(ctx
->vty
, nhe
);
1305 return HASHWALK_CONTINUE
;
1308 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1309 struct zebra_vrf
*zvrf
,
1312 struct nhe_show_context ctx
;
1316 ctx
.vrf_id
= zvrf
->vrf
->vrf_id
;
1318 hash_walk(zrouter
.nhgs_id
, nhe_show_walker
, &ctx
);
1321 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1323 struct zebra_if
*zebra_if
= NULL
;
1324 struct nhg_connected
*rb_node_dep
= NULL
;
1326 zebra_if
= ifp
->info
;
1328 if (!if_nhg_dependents_is_empty(ifp
)) {
1329 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1331 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1334 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1339 DEFPY (show_interface_nexthop_group
,
1340 show_interface_nexthop_group_cmd
,
1341 "show interface [IFNAME$if_name] nexthop-group",
1343 "Interface status and configuration\n"
1345 "Show Nexthop Groups\n")
1347 struct vrf
*vrf
= NULL
;
1348 struct interface
*ifp
= NULL
;
1351 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1353 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1355 if_nexthop_group_dump_vty(vty
, ifp
);
1359 FOR_ALL_INTERFACES (vrf
, ifp
)
1360 if_nexthop_group_dump_vty(vty
, ifp
);
1366 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1373 DEFPY (show_nexthop_group
,
1374 show_nexthop_group_cmd
,
1375 "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
1377 "Show Nexthop Groups\n"
1379 "Nexthop Group ID\n"
1380 "Show Singleton Nexthop-Groups\n"
1383 VRF_FULL_CMD_HELP_STR
)
1386 struct zebra_vrf
*zvrf
= NULL
;
1387 afi_t afi
= AFI_UNSPEC
;
1390 return show_nexthop_group_id_cmd_helper(vty
, id
);
1397 if (vrf_is_backend_netns() && (vrf_name
|| vrf_all
)) {
1398 vty_out(vty
, "VRF subcommand does not make any sense in l3mdev based vrf's");
1405 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1406 struct zebra_vrf
*zvrf
;
1412 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1413 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1420 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1422 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1425 vty_out(vty
, "%% VRF '%s' specified does not exist\n",
1430 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1435 DEFPY_HIDDEN(nexthop_group_use_enable
,
1436 nexthop_group_use_enable_cmd
,
1437 "[no] zebra nexthop kernel enable",
1440 "Nexthop configuration \n"
1441 "Configure use of kernel nexthops\n"
1442 "Enable kernel nexthops\n")
1444 zebra_nhg_enable_kernel_nexthops(!no
);
1448 DEFUN (no_ip_nht_default_route
,
1449 no_ip_nht_default_route_cmd
,
1450 "no ip nht resolve-via-default",
1453 "Filter Next Hop tracking route resolution\n"
1454 "Resolve via default route\n")
1456 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1461 if (!zvrf
->zebra_rnh_ip_default_route
)
1464 zvrf
->zebra_rnh_ip_default_route
= 0;
1465 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1469 DEFUN (ipv6_nht_default_route
,
1470 ipv6_nht_default_route_cmd
,
1471 "ipv6 nht resolve-via-default",
1473 "Filter Next Hop tracking route resolution\n"
1474 "Resolve via default route\n")
1476 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1481 if (zvrf
->zebra_rnh_ipv6_default_route
)
1484 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1485 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1489 DEFUN (no_ipv6_nht_default_route
,
1490 no_ipv6_nht_default_route_cmd
,
1491 "no ipv6 nht resolve-via-default",
1494 "Filter Next Hop tracking route resolution\n"
1495 "Resolve via default route\n")
1498 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1503 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1506 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1507 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1515 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1518 |A.B.C.D/M$prefix longer-prefixes\
1519 |supernets-only$supernets_only\
1522 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1523 |ospf$type_str (1-65535)$ospf_instance_id\
1525 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1528 |X:X::X:X/M$prefix longer-prefixes\
1530 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1535 "IP forwarding table\n"
1536 "IP routing table\n"
1537 VRF_FULL_CMD_HELP_STR
1538 "Show only routes with tag\n"
1540 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1541 "Show route matching the specified Network/Mask pair only\n"
1542 "Show supernet entries only\n"
1543 FRR_IP_REDIST_HELP_STR_ZEBRA
1544 "Open Shortest Path First (OSPFv2)\n"
1547 "IP forwarding table\n"
1548 "IP routing table\n"
1549 VRF_FULL_CMD_HELP_STR
1550 "Show only routes with tag\n"
1553 "Show route matching the specified Network/Mask pair only\n"
1554 FRR_IP6_REDIST_HELP_STR_ZEBRA
1557 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1562 type
= proto_redistnum(afi
, type_str
);
1564 vty_out(vty
, "Unknown route type\n");
1570 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1571 struct zebra_vrf
*zvrf
;
1572 struct route_table
*table
;
1574 if ((zvrf
= vrf
->info
) == NULL
1575 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1579 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1580 !!json
, tag
, prefix_str
? prefix
: NULL
,
1581 !!supernets_only
, type
, ospf_instance_id
);
1584 vrf_id_t vrf_id
= VRF_DEFAULT
;
1587 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1588 vrf
= vrf_lookup_by_id(vrf_id
);
1589 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1590 !!json
, tag
, prefix_str
? prefix
: NULL
,
1591 !!supernets_only
, type
, ospf_instance_id
);
1597 DEFPY (show_route_detail
,
1598 show_route_detail_cmd
,
1601 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1606 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1612 [json$json] [nexthop-group$ng]",
1615 "IPv6 forwarding table\n"
1616 "IP routing table\n"
1617 VRF_FULL_CMD_HELP_STR
1618 "Network in the IP routing table to display\n"
1619 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1621 "IPv6 forwarding table\n"
1622 "IPv6 routing table\n"
1623 VRF_FULL_CMD_HELP_STR
1627 "Nexthop Group Information\n")
1629 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1630 struct route_table
*table
;
1632 struct route_node
*rn
;
1633 bool use_fib
= !!fib
;
1635 bool network_found
= false;
1636 bool show_ng
= !!ng
;
1639 prefix_str
= address_str
;
1640 if (str2prefix(prefix_str
, &p
) < 0) {
1641 vty_out(vty
, "%% Malformed address\n");
1647 struct zebra_vrf
*zvrf
;
1649 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1650 if ((zvrf
= vrf
->info
) == NULL
1651 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1654 rn
= route_node_match(table
, &p
);
1657 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1658 route_unlock_node(rn
);
1662 dest
= rib_dest_from_rnode(rn
);
1663 if (use_fib
&& !dest
->selected_fib
) {
1664 route_unlock_node(rn
);
1668 network_found
= true;
1670 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1672 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1675 route_unlock_node(rn
);
1678 if (!network_found
) {
1680 vty_out(vty
, "{}\n");
1684 "%% Network not in FIB\n");
1687 "%% Network not in RIB\n");
1692 vrf_id_t vrf_id
= VRF_DEFAULT
;
1695 VRF_GET_ID(vrf_id
, vrf_name
, false);
1697 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1701 rn
= route_node_match(table
, &p
);
1703 dest
= rib_dest_from_rnode(rn
);
1705 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1706 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1708 vty_out(vty
, "{}\n");
1712 "%% Network not in FIB\n");
1715 "%% Network not in table\n");
1718 route_unlock_node(rn
);
1723 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1725 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1727 route_unlock_node(rn
);
1733 DEFPY (show_route_summary
,
1734 show_route_summary_cmd
,
1735 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1736 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
1740 "IP routing table\n"
1741 VRF_FULL_CMD_HELP_STR
1742 "Summary of all routes\n"
1743 "Table to display summary for\n"
1744 "The table number\n"
1748 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1749 struct route_table
*table
;
1750 bool uj
= use_json(argc
, argv
);
1753 table_id
= RT_TABLE_MAIN
;
1757 struct zebra_vrf
*zvrf
;
1759 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1760 if ((zvrf
= vrf
->info
) == NULL
)
1763 table
= zebra_vrf_lookup_table_with_table_id(
1764 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, table_id
);
1770 vty_show_ip_route_summary_prefix(vty
, table
,
1773 vty_show_ip_route_summary(vty
, table
, uj
);
1776 vrf_id_t vrf_id
= VRF_DEFAULT
;
1779 VRF_GET_ID(vrf_id
, vrf_name
, false);
1781 table
= zebra_vrf_lookup_table_with_table_id(afi
, SAFI_UNICAST
,
1787 vty_show_ip_route_summary_prefix(vty
, table
, uj
);
1789 vty_show_ip_route_summary(vty
, table
, uj
);
1795 static void vty_show_ip_route_summary(struct vty
*vty
,
1796 struct route_table
*table
, bool use_json
)
1798 struct route_node
*rn
;
1799 struct route_entry
*re
;
1800 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1801 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1802 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1803 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1806 json_object
*json_route_summary
= NULL
;
1807 json_object
*json_route_routes
= NULL
;
1809 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1810 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1813 json_route_summary
= json_object_new_object();
1814 json_route_routes
= json_object_new_array();
1815 json_object_object_add(json_route_summary
, "routes",
1819 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1820 RNODE_FOREACH_RE (rn
, re
) {
1821 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1822 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1824 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1826 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1828 rib_cnt
[re
->type
]++;
1830 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1831 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1834 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1836 fib_cnt
[re
->type
]++;
1841 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1843 zvrf_name(((rib_table_info_t
*)route_table_get_info(
1847 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1848 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1849 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1850 if (i
== ZEBRA_ROUTE_BGP
) {
1852 json_object
*json_route_ebgp
=
1853 json_object_new_object();
1855 json_object_int_add(
1856 json_route_ebgp
, "fib",
1857 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1858 json_object_int_add(
1859 json_route_ebgp
, "rib",
1860 rib_cnt
[ZEBRA_ROUTE_BGP
]);
1861 json_object_string_add(json_route_ebgp
,
1863 json_object_array_add(json_route_routes
,
1866 json_object
*json_route_ibgp
=
1867 json_object_new_object();
1869 json_object_int_add(
1870 json_route_ibgp
, "fib",
1871 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1872 json_object_int_add(
1873 json_route_ibgp
, "rib",
1874 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1875 json_object_string_add(json_route_ibgp
,
1877 json_object_array_add(json_route_routes
,
1880 vty_out(vty
, "%-20s %-20d %-20d \n",
1882 rib_cnt
[ZEBRA_ROUTE_BGP
],
1883 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1884 vty_out(vty
, "%-20s %-20d %-20d \n",
1886 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1887 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1891 json_object
*json_route_type
=
1892 json_object_new_object();
1894 json_object_int_add(json_route_type
,
1896 json_object_int_add(json_route_type
,
1898 json_object_string_add(
1899 json_route_type
, "type",
1900 zebra_route_string(i
));
1901 json_object_array_add(json_route_routes
,
1904 vty_out(vty
, "%-20s %-20d %-20d \n",
1905 zebra_route_string(i
),
1906 rib_cnt
[i
], fib_cnt
[i
]);
1912 json_object_int_add(json_route_summary
, "routesTotal",
1913 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1914 json_object_int_add(json_route_summary
, "routesTotalFib",
1915 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1917 vty_out(vty
, "%s\n",
1918 json_object_to_json_string_ext(
1919 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
1920 json_object_free(json_route_summary
);
1922 vty_out(vty
, "------\n");
1923 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1924 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1930 * Implementation of the ip route summary prefix command.
1932 * This command prints the primary prefixes that have been installed by various
1933 * protocols on the box.
1936 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1937 struct route_table
*table
,
1940 struct route_node
*rn
;
1941 struct route_entry
*re
;
1942 struct nexthop
*nexthop
;
1943 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1944 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1945 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1946 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1949 json_object
*json_route_summary
= NULL
;
1950 json_object
*json_route_routes
= NULL
;
1952 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1953 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1956 json_route_summary
= json_object_new_object();
1957 json_route_routes
= json_object_new_array();
1958 json_object_object_add(json_route_summary
, "prefixRoutes",
1962 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1963 RNODE_FOREACH_RE (rn
, re
) {
1966 * In case of ECMP, count only once.
1969 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1970 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1971 fib_cnt
[re
->type
]++;
1973 for (nexthop
= re
->nhe
->nhg
->nexthop
; (!cnt
&& nexthop
);
1974 nexthop
= nexthop
->next
) {
1976 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1977 rib_cnt
[re
->type
]++;
1978 if (re
->type
== ZEBRA_ROUTE_BGP
1979 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1980 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1981 if (CHECK_FLAG(re
->status
,
1982 ROUTE_ENTRY_INSTALLED
))
1983 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1989 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1990 "Prefix Routes", "FIB",
1991 zvrf_name(((rib_table_info_t
*)route_table_get_info(
1995 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1996 if (rib_cnt
[i
] > 0) {
1997 if (i
== ZEBRA_ROUTE_BGP
) {
1999 json_object
*json_route_ebgp
=
2000 json_object_new_object();
2002 json_object_int_add(
2003 json_route_ebgp
, "fib",
2004 fib_cnt
[ZEBRA_ROUTE_BGP
]
2005 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2006 json_object_int_add(
2007 json_route_ebgp
, "rib",
2008 rib_cnt
[ZEBRA_ROUTE_BGP
]
2009 - rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2010 json_object_string_add(json_route_ebgp
,
2012 json_object_array_add(json_route_routes
,
2015 json_object
*json_route_ibgp
=
2016 json_object_new_object();
2018 json_object_int_add(
2019 json_route_ibgp
, "fib",
2020 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2021 json_object_int_add(
2022 json_route_ibgp
, "rib",
2023 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2024 json_object_string_add(json_route_ibgp
,
2026 json_object_array_add(json_route_routes
,
2029 vty_out(vty
, "%-20s %-20d %-20d \n",
2031 rib_cnt
[ZEBRA_ROUTE_BGP
]
2032 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
2033 fib_cnt
[ZEBRA_ROUTE_BGP
]
2034 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2035 vty_out(vty
, "%-20s %-20d %-20d \n",
2037 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2038 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2042 json_object
*json_route_type
=
2043 json_object_new_object();
2045 json_object_int_add(json_route_type
,
2047 json_object_int_add(json_route_type
,
2049 json_object_string_add(
2050 json_route_type
, "type",
2051 zebra_route_string(i
));
2052 json_object_array_add(json_route_routes
,
2055 vty_out(vty
, "%-20s %-20d %-20d \n",
2056 zebra_route_string(i
),
2057 rib_cnt
[i
], fib_cnt
[i
]);
2063 json_object_int_add(json_route_summary
, "prefixRoutesTotal",
2064 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2065 json_object_int_add(json_route_summary
, "prefixRoutesTotalFib",
2066 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2068 vty_out(vty
, "%s\n",
2069 json_object_to_json_string_ext(
2070 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2071 json_object_free(json_route_summary
);
2073 vty_out(vty
, "------\n");
2074 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2075 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2081 * Show IPv6 mroute command.Used to dump
2082 * the Multicast routing table.
2084 DEFUN (show_ipv6_mroute
,
2085 show_ipv6_mroute_cmd
,
2086 "show ipv6 mroute [vrf NAME]",
2089 "IPv6 Multicast routing table\n"
2092 struct route_table
*table
;
2093 struct route_node
*rn
;
2094 struct route_entry
*re
;
2096 vrf_id_t vrf_id
= VRF_DEFAULT
;
2099 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
2101 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2105 /* Show all IPv6 route. */
2106 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2107 RNODE_FOREACH_RE (rn
, re
) {
2109 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2112 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2117 DEFUN (show_ipv6_mroute_vrf_all
,
2118 show_ipv6_mroute_vrf_all_cmd
,
2119 "show ipv6 mroute vrf all",
2122 "IPv6 Multicast routing table\n"
2123 VRF_ALL_CMD_HELP_STR
)
2125 struct route_table
*table
;
2126 struct route_node
*rn
;
2127 struct route_entry
*re
;
2129 struct zebra_vrf
*zvrf
;
2132 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2133 if ((zvrf
= vrf
->info
) == NULL
2134 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2137 /* Show all IPv6 route. */
2138 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2139 RNODE_FOREACH_RE (rn
, re
) {
2141 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2144 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2150 DEFUN (allow_external_route_update
,
2151 allow_external_route_update_cmd
,
2152 "allow-external-route-update",
2153 "Allow FRR routes to be overwritten by external processes\n")
2160 DEFUN (no_allow_external_route_update
,
2161 no_allow_external_route_update_cmd
,
2162 "no allow-external-route-update",
2164 "Allow FRR routes to be overwritten by external processes\n")
2179 struct zebra_vrf
*zvrf
;
2181 if (vrf_is_backend_netns())
2182 vty_out(vty
, "netns-based vrfs\n");
2184 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2185 if (!(zvrf
= vrf
->info
))
2187 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2190 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2191 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
2192 vty_out(vty
, "inactive");
2193 else if (zvrf_ns_name(zvrf
))
2194 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2195 zvrf_ns_name(zvrf
));
2197 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2199 if (vrf_is_user_cfged(vrf
))
2200 vty_out(vty
, " (configured)");
2207 DEFUN (default_vrf_vni_mapping
,
2208 default_vrf_vni_mapping_cmd
,
2209 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2210 "VNI corresponding to the DEFAULT VRF\n"
2212 "Prefix routes only \n")
2215 char err
[ERR_STR_SZ
];
2216 struct zebra_vrf
*zvrf
= NULL
;
2217 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2220 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2227 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2230 vty_out(vty
, "%s\n", err
);
2237 DEFUN (no_default_vrf_vni_mapping
,
2238 no_default_vrf_vni_mapping_cmd
,
2239 "no vni " CMD_VNI_RANGE
,
2241 "VNI corresponding to DEFAULT VRF\n"
2245 char err
[ERR_STR_SZ
];
2246 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2247 struct zebra_vrf
*zvrf
= NULL
;
2249 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2253 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2255 vty_out(vty
, "%s\n", err
);
2262 DEFUN (vrf_vni_mapping
,
2263 vrf_vni_mapping_cmd
,
2264 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2265 "VNI corresponding to tenant VRF\n"
2267 "prefix-routes-only\n")
2272 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2273 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2274 char err
[ERR_STR_SZ
];
2282 /* Mark as having FRR configuration */
2283 vrf_set_user_cfged(vrf
);
2284 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2287 vty_out(vty
, "%s\n", err
);
2294 DEFUN (no_vrf_vni_mapping
,
2295 no_vrf_vni_mapping_cmd
,
2296 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2298 "VNI corresponding to tenant VRF\n"
2300 "prefix-routes-only\n")
2304 char err
[ERR_STR_SZ
];
2305 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2307 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2315 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2316 ERR_STR_SZ
, filter
, 0);
2318 vty_out(vty
, "%s\n", err
);
2322 /* If no other FRR config for this VRF, mark accordingly. */
2323 if (!zebra_vrf_has_config(zvrf
))
2324 vrf_reset_user_cfged(vrf
);
2330 DEFUN (show_vrf_vni
,
2332 "show vrf vni [json]",
2339 struct zebra_vrf
*zvrf
;
2340 json_object
*json
= NULL
;
2341 json_object
*json_vrfs
= NULL
;
2342 bool uj
= use_json(argc
, argv
);
2345 json
= json_object_new_object();
2346 json_vrfs
= json_object_new_array();
2350 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2351 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2353 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2358 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2362 json_object_object_add(json
, "vrfs", json_vrfs
);
2363 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2364 json
, JSON_C_TO_STRING_PRETTY
));
2365 json_object_free(json
);
2371 DEFUN (show_evpn_global
,
2372 show_evpn_global_cmd
,
2378 bool uj
= use_json(argc
, argv
);
2380 zebra_vxlan_print_evpn(vty
, uj
);
2384 DEFUN (show_evpn_vni
,
2386 "show evpn vni [json]",
2389 "VxLAN Network Identifier\n"
2392 struct zebra_vrf
*zvrf
;
2393 bool uj
= use_json(argc
, argv
);
2395 zvrf
= zebra_vrf_get_evpn();
2396 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2400 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2401 "show evpn vni detail [json]",
2404 "VxLAN Network Identifier\n"
2405 "Detailed Information On Each VNI\n"
2408 struct zebra_vrf
*zvrf
;
2409 bool uj
= use_json(argc
, argv
);
2411 zvrf
= zebra_vrf_get_evpn();
2412 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2416 DEFUN (show_evpn_vni_vni
,
2417 show_evpn_vni_vni_cmd
,
2418 "show evpn vni " CMD_VNI_RANGE
"[json]",
2421 "VxLAN Network Identifier\n"
2425 struct zebra_vrf
*zvrf
;
2427 bool uj
= use_json(argc
, argv
);
2429 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2430 zvrf
= zebra_vrf_get_evpn();
2431 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2435 DEFUN (show_evpn_rmac_vni_mac
,
2436 show_evpn_rmac_vni_mac_cmd
,
2437 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2444 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2449 bool uj
= use_json(argc
, argv
);
2451 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2452 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2453 vty_out(vty
, "%% Malformed MAC address\n");
2456 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2460 DEFUN (show_evpn_rmac_vni
,
2461 show_evpn_rmac_vni_cmd
,
2462 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2471 bool uj
= use_json(argc
, argv
);
2473 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2474 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2479 DEFUN (show_evpn_rmac_vni_all
,
2480 show_evpn_rmac_vni_all_cmd
,
2481 "show evpn rmac vni all [json]",
2489 bool uj
= use_json(argc
, argv
);
2491 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2496 DEFUN (show_evpn_nh_vni_ip
,
2497 show_evpn_nh_vni_ip_cmd
,
2498 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2505 "Host address (ipv4 or ipv6)\n"
2510 bool uj
= use_json(argc
, argv
);
2512 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2513 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2515 vty_out(vty
, "%% Malformed Neighbor address\n");
2518 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2523 DEFUN (show_evpn_nh_vni
,
2524 show_evpn_nh_vni_cmd
,
2525 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2534 bool uj
= use_json(argc
, argv
);
2536 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2537 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2542 DEFUN (show_evpn_nh_vni_all
,
2543 show_evpn_nh_vni_all_cmd
,
2544 "show evpn next-hops vni all [json]",
2552 bool uj
= use_json(argc
, argv
);
2554 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2559 DEFUN (show_evpn_mac_vni
,
2560 show_evpn_mac_vni_cmd
,
2561 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2565 "VxLAN Network Identifier\n"
2569 struct zebra_vrf
*zvrf
;
2571 bool uj
= use_json(argc
, argv
);
2573 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2574 zvrf
= zebra_vrf_get_evpn();
2575 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2579 DEFUN (show_evpn_mac_vni_all
,
2580 show_evpn_mac_vni_all_cmd
,
2581 "show evpn mac vni all [json]",
2585 "VxLAN Network Identifier\n"
2589 struct zebra_vrf
*zvrf
;
2590 bool uj
= use_json(argc
, argv
);
2592 zvrf
= zebra_vrf_get_evpn();
2593 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2597 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2598 "show evpn mac vni all detail [json]",
2602 "VxLAN Network Identifier\n"
2604 "Detailed Information On Each VNI MAC\n"
2607 struct zebra_vrf
*zvrf
;
2608 bool uj
= use_json(argc
, argv
);
2610 zvrf
= zebra_vrf_get_evpn();
2611 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2615 DEFUN (show_evpn_mac_vni_all_vtep
,
2616 show_evpn_mac_vni_all_vtep_cmd
,
2617 "show evpn mac vni all vtep A.B.C.D [json]",
2621 "VxLAN Network Identifier\n"
2624 "Remote VTEP IP address\n"
2627 struct zebra_vrf
*zvrf
;
2628 struct in_addr vtep_ip
;
2629 bool uj
= use_json(argc
, argv
);
2631 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2633 vty_out(vty
, "%% Malformed VTEP IP address\n");
2636 zvrf
= zebra_vrf_get_evpn();
2637 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2643 DEFUN (show_evpn_mac_vni_mac
,
2644 show_evpn_mac_vni_mac_cmd
,
2645 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2649 "VxLAN Network Identifier\n"
2652 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2656 struct zebra_vrf
*zvrf
;
2659 bool uj
= use_json(argc
, argv
);
2661 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2662 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2663 vty_out(vty
, "%% Malformed MAC address");
2666 zvrf
= zebra_vrf_get_evpn();
2667 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2671 DEFUN (show_evpn_mac_vni_vtep
,
2672 show_evpn_mac_vni_vtep_cmd
,
2673 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2677 "VxLAN Network Identifier\n"
2680 "Remote VTEP IP address\n"
2683 struct zebra_vrf
*zvrf
;
2685 struct in_addr vtep_ip
;
2686 bool uj
= use_json(argc
, argv
);
2688 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2689 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2691 vty_out(vty
, "%% Malformed VTEP IP address\n");
2695 zvrf
= zebra_vrf_get_evpn();
2696 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2700 DEFPY (show_evpn_mac_vni_all_dad
,
2701 show_evpn_mac_vni_all_dad_cmd
,
2702 "show evpn mac vni all duplicate [json]",
2706 "VxLAN Network Identifier\n"
2708 "Duplicate address list\n"
2711 struct zebra_vrf
*zvrf
;
2712 bool uj
= use_json(argc
, argv
);
2714 zvrf
= zebra_vrf_get_evpn();
2715 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2720 DEFPY (show_evpn_mac_vni_dad
,
2721 show_evpn_mac_vni_dad_cmd
,
2722 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2726 "VxLAN Network Identifier\n"
2728 "Duplicate address list\n"
2731 struct zebra_vrf
*zvrf
;
2732 bool uj
= use_json(argc
, argv
);
2734 zvrf
= zebra_vrf_get_evpn();
2736 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2741 DEFPY (show_evpn_neigh_vni_dad
,
2742 show_evpn_neigh_vni_dad_cmd
,
2743 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2746 "ARP and ND cache\n"
2747 "VxLAN Network Identifier\n"
2749 "Duplicate address list\n"
2752 struct zebra_vrf
*zvrf
;
2753 bool uj
= use_json(argc
, argv
);
2755 zvrf
= zebra_vrf_get_evpn();
2756 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2760 DEFPY (show_evpn_neigh_vni_all_dad
,
2761 show_evpn_neigh_vni_all_dad_cmd
,
2762 "show evpn arp-cache vni all duplicate [json]",
2765 "ARP and ND cache\n"
2766 "VxLAN Network Identifier\n"
2768 "Duplicate address list\n"
2771 struct zebra_vrf
*zvrf
;
2772 bool uj
= use_json(argc
, argv
);
2774 zvrf
= zebra_vrf_get_evpn();
2775 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2780 DEFUN (show_evpn_neigh_vni
,
2781 show_evpn_neigh_vni_cmd
,
2782 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2785 "ARP and ND cache\n"
2786 "VxLAN Network Identifier\n"
2790 struct zebra_vrf
*zvrf
;
2792 bool uj
= use_json(argc
, argv
);
2794 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2795 zvrf
= zebra_vrf_get_evpn();
2796 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2800 DEFUN (show_evpn_neigh_vni_all
,
2801 show_evpn_neigh_vni_all_cmd
,
2802 "show evpn arp-cache vni all [json]",
2805 "ARP and ND cache\n"
2806 "VxLAN Network Identifier\n"
2810 struct zebra_vrf
*zvrf
;
2811 bool uj
= use_json(argc
, argv
);
2813 zvrf
= zebra_vrf_get_evpn();
2814 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2818 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2819 "show evpn arp-cache vni all detail [json]",
2822 "ARP and ND cache\n"
2823 "VxLAN Network Identifier\n"
2825 "Neighbor details for all vnis in detail\n" JSON_STR
)
2827 struct zebra_vrf
*zvrf
;
2828 bool uj
= use_json(argc
, argv
);
2830 zvrf
= zebra_vrf_get_evpn();
2831 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2835 DEFUN (show_evpn_neigh_vni_neigh
,
2836 show_evpn_neigh_vni_neigh_cmd
,
2837 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2840 "ARP and ND cache\n"
2841 "VxLAN Network Identifier\n"
2844 "Neighbor address (IPv4 or IPv6 address)\n"
2847 struct zebra_vrf
*zvrf
;
2850 bool uj
= use_json(argc
, argv
);
2852 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2853 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2855 vty_out(vty
, "%% Malformed Neighbor address\n");
2858 zvrf
= zebra_vrf_get_evpn();
2859 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2863 DEFUN (show_evpn_neigh_vni_vtep
,
2864 show_evpn_neigh_vni_vtep_cmd
,
2865 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2868 "ARP and ND cache\n"
2869 "VxLAN Network Identifier\n"
2872 "Remote VTEP IP address\n"
2875 struct zebra_vrf
*zvrf
;
2877 struct in_addr vtep_ip
;
2878 bool uj
= use_json(argc
, argv
);
2880 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2881 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2883 vty_out(vty
, "%% Malformed VTEP IP address\n");
2887 zvrf
= zebra_vrf_get_evpn();
2888 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2892 /* policy routing contexts */
2893 DEFUN (show_pbr_ipset
,
2895 "show pbr ipset [WORD]",
2897 "Policy-Based Routing\n"
2898 "IPset Context information\n"
2899 "IPset Name information\n")
2903 found
= argv_find(argv
, argc
, "WORD", &idx
);
2905 zebra_pbr_show_ipset_list(vty
, NULL
);
2907 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2911 /* policy routing contexts */
2912 DEFUN (show_pbr_iptable
,
2913 show_pbr_iptable_cmd
,
2914 "show pbr iptable [WORD]",
2916 "Policy-Based Routing\n"
2917 "IPtable Context information\n"
2918 "IPtable Name information\n")
2923 found
= argv_find(argv
, argc
, "WORD", &idx
);
2925 zebra_pbr_show_iptable(vty
, NULL
);
2927 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2931 DEFPY (clear_evpn_dup_addr
,
2932 clear_evpn_dup_addr_cmd
,
2933 "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>]>",
2936 "Duplicate address \n"
2937 "VxLAN Network Identifier\n"
2941 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2946 struct zebra_vrf
*zvrf
;
2947 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2948 int ret
= CMD_SUCCESS
;
2950 zvrf
= zebra_vrf_get_evpn();
2952 if (!is_zero_mac(&mac
->eth_addr
)) {
2953 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2957 if (sockunion_family(ip
) == AF_INET
) {
2958 host_ip
.ipa_type
= IPADDR_V4
;
2959 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2961 host_ip
.ipa_type
= IPADDR_V6
;
2962 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2963 sizeof(struct in6_addr
));
2965 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2969 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2972 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2978 /* Static ip route configuration write function. */
2979 static int zebra_ip_config(struct vty
*vty
)
2983 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2988 DEFUN (ip_zebra_import_table_distance
,
2989 ip_zebra_import_table_distance_cmd
,
2990 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2992 "import routes from non-main kernel table\n"
2993 "kernel routing table id\n"
2994 "Distance for imported routes\n"
2995 "Default distance value\n"
2996 "route-map for filtering\n"
2999 uint32_t table_id
= 0;
3001 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
3002 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
3004 strmatch(argv
[argc
- 2]->text
, "route-map")
3005 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
3009 if (argc
== 7 || (argc
== 5 && !rmap
))
3010 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
3012 if (!is_zebra_valid_kernel_table(table_id
)) {
3014 "Invalid routing table ID, %d. Must be in range 1-252\n",
3017 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3021 if (is_zebra_main_routing_table(table_id
)) {
3023 "Invalid routing table ID, %d. Must be non-default table\n",
3026 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3030 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
3033 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3038 DEFUN_HIDDEN (zebra_packet_process
,
3039 zebra_packet_process_cmd
,
3040 "zebra zapi-packets (1-10000)",
3043 "Number of packets to process before relinquishing thread\n")
3045 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3047 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
3048 memory_order_relaxed
);
3053 DEFUN_HIDDEN (no_zebra_packet_process
,
3054 no_zebra_packet_process_cmd
,
3055 "no zebra zapi-packets [(1-10000)]",
3059 "Number of packets to process before relinquishing thread\n")
3061 atomic_store_explicit(&zrouter
.packets_to_process
,
3062 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
3063 memory_order_relaxed
);
3068 DEFUN_HIDDEN (zebra_workqueue_timer
,
3069 zebra_workqueue_timer_cmd
,
3070 "zebra work-queue (0-10000)",
3073 "Time in milliseconds\n")
3075 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3076 zrouter
.ribq
->spec
.hold
= timer
;
3081 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3082 no_zebra_workqueue_timer_cmd
,
3083 "no zebra work-queue [(0-10000)]",
3087 "Time in milliseconds\n")
3089 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3094 DEFUN (no_ip_zebra_import_table
,
3095 no_ip_zebra_import_table_cmd
,
3096 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3099 "import routes from non-main kernel table\n"
3100 "kernel routing table id\n"
3101 "Distance for imported routes\n"
3102 "Default distance value\n"
3103 "route-map for filtering\n"
3106 uint32_t table_id
= 0;
3107 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3109 if (!is_zebra_valid_kernel_table(table_id
)) {
3111 "Invalid routing table ID. Must be in range 1-252\n");
3115 if (is_zebra_main_routing_table(table_id
)) {
3117 "Invalid routing table ID, %d. Must be non-default table\n",
3122 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
3125 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
3128 static int config_write_protocol(struct vty
*vty
)
3131 vty_out(vty
, "allow-external-route-update\n");
3133 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3134 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
3136 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3137 vty_out(vty
, "zebra zapi-packets %u\n",
3138 zrouter
.packets_to_process
);
3140 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3142 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3143 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3144 ipv4_multicast_mode
== MCAST_URIB_ONLY
3146 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3148 : ipv4_multicast_mode
3149 == MCAST_MIX_MRIB_FIRST
3151 : ipv4_multicast_mode
3152 == MCAST_MIX_DISTANCE
3156 /* Include dataplane info */
3157 dplane_config_write_helper(vty
);
3159 /* Include nexthop-group config */
3160 if (!zebra_nhg_kernel_nexthops_enabled())
3161 vty_out(vty
, "no zebra nexthop kernel enable\n");
3175 " Route Route Neighbor LSP LSP\n");
3177 "VRF Installs Removals Updates Installs Removals\n");
3179 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3180 struct zebra_vrf
*zvrf
= vrf
->info
;
3182 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
3183 " %10" PRIu64
" %10" PRIu64
"\n",
3184 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3185 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3186 zvrf
->lsp_removals
);
3192 DEFUN (ip_forwarding
,
3196 "Turn on IP forwarding\n")
3202 ret
= ipforward_on();
3205 vty_out(vty
, "Can't turn on IP forwarding\n");
3206 return CMD_WARNING_CONFIG_FAILED
;
3212 DEFUN (no_ip_forwarding
,
3213 no_ip_forwarding_cmd
,
3217 "Turn off IP forwarding\n")
3223 ret
= ipforward_off();
3226 vty_out(vty
, "Can't turn off IP forwarding\n");
3227 return CMD_WARNING_CONFIG_FAILED
;
3233 /* Only display ip forwarding is enabled or not. */
3234 DEFUN (show_ip_forwarding
,
3235 show_ip_forwarding_cmd
,
3236 "show ip forwarding",
3239 "IP forwarding status\n")
3246 vty_out(vty
, "IP forwarding is off\n");
3248 vty_out(vty
, "IP forwarding is on\n");
3252 /* Only display ipv6 forwarding is enabled or not. */
3253 DEFUN (show_ipv6_forwarding
,
3254 show_ipv6_forwarding_cmd
,
3255 "show ipv6 forwarding",
3257 "IPv6 information\n"
3258 "Forwarding status\n")
3262 ret
= ipforward_ipv6();
3266 vty_out(vty
, "ipv6 forwarding is unknown\n");
3269 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3272 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3275 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3281 DEFUN (ipv6_forwarding
,
3282 ipv6_forwarding_cmd
,
3285 "Turn on IPv6 forwarding\n")
3289 ret
= ipforward_ipv6();
3291 ret
= ipforward_ipv6_on();
3294 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3295 return CMD_WARNING_CONFIG_FAILED
;
3301 DEFUN (no_ipv6_forwarding
,
3302 no_ipv6_forwarding_cmd
,
3303 "no ipv6 forwarding",
3306 "Turn off IPv6 forwarding\n")
3310 ret
= ipforward_ipv6();
3312 ret
= ipforward_ipv6_off();
3315 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3316 return CMD_WARNING_CONFIG_FAILED
;
3322 /* Display dataplane info */
3323 DEFUN (show_dataplane
,
3325 "show zebra dplane [detailed]",
3328 "Zebra dataplane information\n"
3329 "Detailed output\n")
3332 bool detailed
= false;
3334 if (argv_find(argv
, argc
, "detailed", &idx
))
3337 return dplane_show_helper(vty
, detailed
);
3340 /* Display dataplane providers info */
3341 DEFUN (show_dataplane_providers
,
3342 show_dataplane_providers_cmd
,
3343 "show zebra dplane providers [detailed]",
3346 "Zebra dataplane information\n"
3347 "Zebra dataplane provider information\n"
3348 "Detailed output\n")
3351 bool detailed
= false;
3353 if (argv_find(argv
, argc
, "detailed", &idx
))
3356 return dplane_show_provs_helper(vty
, detailed
);
3359 /* Configure dataplane incoming queue limit */
3360 DEFUN (zebra_dplane_queue_limit
,
3361 zebra_dplane_queue_limit_cmd
,
3362 "zebra dplane limit (0-10000)",
3365 "Limit incoming queued updates\n"
3366 "Number of queued updates\n")
3370 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3372 dplane_set_in_queue_limit(limit
, true);
3377 /* Reset dataplane queue limit to default value */
3378 DEFUN (no_zebra_dplane_queue_limit
,
3379 no_zebra_dplane_queue_limit_cmd
,
3380 "no zebra dplane limit [(0-10000)]",
3384 "Limit incoming queued updates\n"
3385 "Number of queued updates\n")
3387 dplane_set_in_queue_limit(0, false);
3392 DEFUN (zebra_show_routing_tables_summary
,
3393 zebra_show_routing_tables_summary_cmd
,
3394 "show zebra router table summary",
3397 "The Zebra Router Information\n"
3398 "Table Information about this Zebra Router\n"
3399 "Summary Information\n")
3401 zebra_router_show_table_summary(vty
);
3406 /* Table configuration write function. */
3407 static int config_write_table(struct vty
*vty
)
3412 /* IPForwarding configuration write function. */
3413 static int config_write_forwarding(struct vty
*vty
)
3415 /* FIXME: Find better place for that. */
3416 router_id_write(vty
);
3419 vty_out(vty
, "no ip forwarding\n");
3420 if (!ipforward_ipv6())
3421 vty_out(vty
, "no ipv6 forwarding\n");
3422 vty_out(vty
, "!\n");
3426 DEFUN_HIDDEN (show_frr
,
3432 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3433 vty_out(vty
, ".............................7777:..............................................\n");
3434 vty_out(vty
, ".............................777777,............................................\n");
3435 vty_out(vty
, "... .........................77777777,..........................................\n");
3436 vty_out(vty
, "............................=7777777777:........................................\n");
3437 vty_out(vty
, "........................:7777777777777777,......................................\n");
3438 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3439 vty_out(vty
, "...................I7777777777+.................................................\n");
3440 vty_out(vty
, "................,777777777?............ .......................................\n");
3441 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3442 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3443 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3444 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3445 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3446 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3447 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3448 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3449 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3450 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3451 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3452 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3453 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3454 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3455 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3456 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3457 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3458 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3459 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3460 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3461 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3462 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3463 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3464 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3465 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3466 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3467 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3468 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3469 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3470 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3471 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3472 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3473 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3474 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3475 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3476 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3477 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3478 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3479 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3480 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3481 vty_out(vty
, "................................~77777777...............=777777.................\n");
3482 vty_out(vty
, ".....................................:=?I................~777777................\n");
3483 vty_out(vty
, "..........................................................:777777,..............\n");
3484 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3489 /* IP node for static routes. */
3490 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3491 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3492 /* table node for routing tables. */
3493 static struct cmd_node table_node
= {TABLE_NODE
,
3494 "", /* This node has no interface. */
3496 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3497 "", /* This node has no interface. */
3501 void zebra_vty_init(void)
3503 /* Install configuration write function. */
3504 install_node(&table_node
, config_write_table
);
3505 install_node(&forwarding_node
, config_write_forwarding
);
3507 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3508 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3509 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3510 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3512 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3513 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3514 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3517 zebra_route_map_init();
3519 install_node(&ip_node
, zebra_ip_config
);
3520 install_node(&protocol_node
, config_write_protocol
);
3522 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3523 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3525 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3526 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3528 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3529 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3530 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3531 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3532 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3533 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3534 install_element(CONFIG_NODE
, &nexthop_group_use_enable_cmd
);
3536 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3537 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3539 install_element(VIEW_NODE
, &show_vrf_cmd
);
3540 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3541 install_element(VIEW_NODE
, &show_route_cmd
);
3542 install_element(VIEW_NODE
, &show_route_table_cmd
);
3543 if (vrf_is_backend_netns())
3544 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3545 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3546 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3547 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3548 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3550 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3551 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3553 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3554 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3555 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3556 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3557 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3558 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3559 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3560 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3561 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3563 /* Commands for VRF */
3564 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3566 install_element(VIEW_NODE
, &show_frr_cmd
);
3567 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3568 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3569 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3570 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3571 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3572 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3573 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3574 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3575 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3576 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3577 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3578 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3579 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3580 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3581 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3582 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3583 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3584 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3585 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3586 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3587 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3588 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3589 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3590 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3591 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3592 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3594 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3595 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3597 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3598 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3599 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3600 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3602 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3603 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3604 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3605 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3607 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);