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
);
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
);
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>",
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")
85 char *mode
= argv
[3]->text
;
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
);
98 vty_out(vty
, "Invalid mode specified\n");
99 return CMD_WARNING_CONFIG_FAILED
;
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>]",
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")
118 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
125 "show ip rpf [json]",
128 "Display RPF information for multicast source\n"
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);
136 DEFUN (show_ip_rpf_addr
,
137 show_ip_rpf_addr_cmd
,
138 "show ip rpf A.B.C.D",
141 "Display RPF information for multicast source\n"
142 "IP multicast source address (e.g. 10.0.0.0)\n")
146 struct route_node
*rn
;
147 struct route_entry
*re
;
150 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
152 vty_out(vty
, "%% Malformed address\n");
156 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
159 vty_show_ip_route_detail(vty
, rn
, 1, false);
161 vty_out(vty
, "%% No match for RPF lookup\n");
166 static char re_status_output_char(struct route_entry
*re
, struct nexthop
*nhop
)
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
))
176 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
177 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
183 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
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
)
193 struct route_entry
*re
;
194 struct nexthop
*nexthop
;
195 char buf
[SRCDEST2STR_BUFFER
];
196 struct zebra_vrf
*zvrf
;
199 dest
= rib_dest_from_rnode(rn
);
201 RNODE_FOREACH_RE (rn
, re
) {
203 * If re not selected for forwarding, skip re
204 * for "show ip/ipv6 fib <prefix>"
206 if (use_fib
&& re
!= dest
->selected_fib
)
209 const char *mcast_info
= "";
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";
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
));
221 vty_out(vty
, "[%d]", re
->instance
);
223 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
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)");
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
));
238 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
239 vty_out(vty
, ", best");
245 uptime
= monotime(NULL
);
246 uptime
-= re
->uptime
;
247 tm
= gmtime(&uptime
);
249 vty_out(vty
, " Last update ");
251 if (uptime
< ONE_DAY_SECOND
)
252 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
254 else if (uptime
< ONE_WEEK_SECOND
)
255 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
258 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
259 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
261 vty_out(vty
, " ago\n");
263 for (ALL_NEXTHOPS_PTR(re
->ng
, nexthop
)) {
266 vty_out(vty
, " %c%s",
267 re_status_output_char(re
, nexthop
),
268 nexthop
->rparent
? " " : "");
270 switch (nexthop
->type
) {
271 case NEXTHOP_TYPE_IPV4
:
272 case NEXTHOP_TYPE_IPV4_IFINDEX
:
274 inet_ntoa(nexthop
->gate
.ipv4
));
275 if (nexthop
->ifindex
)
276 vty_out(vty
, ", via %s",
281 case NEXTHOP_TYPE_IPV6
:
282 case NEXTHOP_TYPE_IPV6_IFINDEX
:
284 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
286 if (nexthop
->ifindex
)
287 vty_out(vty
, ", via %s",
292 case NEXTHOP_TYPE_IFINDEX
:
293 vty_out(vty
, " directly connected, %s",
294 ifindex2ifname(nexthop
->ifindex
,
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)");
303 case BLACKHOLE_ADMINPROHIB
:
305 " (ICMP admin-prohibited)");
308 vty_out(vty
, " (blackhole)");
310 case BLACKHOLE_UNSPEC
:
318 if ((re
->vrf_id
!= nexthop
->vrf_id
)
319 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
321 vrf_lookup_by_id(nexthop
->vrf_id
);
324 vty_out(vty
, "(vrf %s)", vrf
->name
);
326 vty_out(vty
, "(vrf UNKNOWN)");
329 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
330 vty_out(vty
, " (duplicate nexthop removed)");
332 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
333 vty_out(vty
, " inactive");
335 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
336 vty_out(vty
, " onlink");
338 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
339 vty_out(vty
, " (recursive)");
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
,
347 addrstr
, sizeof addrstr
))
348 vty_out(vty
, ", src %s",
352 case NEXTHOP_TYPE_IPV6
:
353 case NEXTHOP_TYPE_IPV6_IFINDEX
:
354 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
356 if (inet_ntop(AF_INET6
,
358 addrstr
, sizeof addrstr
))
359 vty_out(vty
, ", src %s",
368 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
370 /* Label information */
371 if (nexthop
->nh_label
372 && nexthop
->nh_label
->num_labels
) {
373 vty_out(vty
, ", label %s",
375 nexthop
->nh_label
->num_labels
,
376 nexthop
->nh_label
->label
, buf
,
386 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
387 struct route_entry
*re
, json_object
*json
,
390 struct nexthop
*nexthop
;
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
;
399 struct vrf
*vrf
= NULL
;
400 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
401 struct nexthop_group
*nhg
;
403 uptime
= monotime(NULL
);
404 uptime
-= re
->uptime
;
405 tm
= gmtime(&uptime
);
407 /* If showing fib information, use the fib view of the
411 nhg
= rib_active_nhg(re
);
416 json_route
= json_object_new_object();
417 json_nexthops
= json_object_new_array();
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
));
425 json_object_int_add(json_route
, "instance",
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",
435 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
436 json_object_boolean_true_add(json_route
, "selected");
438 if (dest
->selected_fib
== re
)
439 json_object_boolean_true_add(json_route
,
442 json_object_int_add(json_route
, "distance",
444 json_object_int_add(json_route
, "metric", re
->metric
);
446 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
447 json_object_boolean_true_add(json_route
, "installed");
449 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
450 json_object_boolean_true_add(json_route
, "failed");
452 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
453 json_object_boolean_true_add(json_route
, "queued");
456 json_object_int_add(json_route
, "tag", re
->tag
);
459 json_object_int_add(json_route
, "table", re
->table
);
461 json_object_int_add(json_route
, "internalStatus",
463 json_object_int_add(json_route
, "internalFlags",
465 json_object_int_add(json_route
, "internalNextHopNum",
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
,
472 else if (uptime
< ONE_WEEK_SECOND
)
473 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
476 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
477 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
480 json_object_string_add(json_route
, "uptime", buf
);
482 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
483 json_nexthop
= json_object_new_object();
485 json_object_int_add(json_nexthop
, "flags",
488 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
489 json_object_boolean_true_add(json_nexthop
,
492 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
493 json_object_boolean_true_add(json_nexthop
,
496 switch (nexthop
->type
) {
497 case NEXTHOP_TYPE_IPV4
:
498 case NEXTHOP_TYPE_IPV4_IFINDEX
:
499 json_object_string_add(
501 inet_ntoa(nexthop
->gate
.ipv4
));
502 json_object_string_add(json_nexthop
, "afi",
505 if (nexthop
->ifindex
) {
506 json_object_int_add(json_nexthop
,
509 json_object_string_add(
510 json_nexthop
, "interfaceName",
516 case NEXTHOP_TYPE_IPV6
:
517 case NEXTHOP_TYPE_IPV6_IFINDEX
:
518 json_object_string_add(
520 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
522 json_object_string_add(json_nexthop
, "afi",
525 if (nexthop
->ifindex
) {
526 json_object_int_add(json_nexthop
,
529 json_object_string_add(
530 json_nexthop
, "interfaceName",
537 case NEXTHOP_TYPE_IFINDEX
:
538 json_object_boolean_true_add(
539 json_nexthop
, "directlyConnected");
540 json_object_int_add(json_nexthop
,
543 json_object_string_add(
544 json_nexthop
, "interfaceName",
545 ifindex2ifname(nexthop
->ifindex
,
548 case NEXTHOP_TYPE_BLACKHOLE
:
549 json_object_boolean_true_add(json_nexthop
,
551 switch (nexthop
->bh_type
) {
552 case BLACKHOLE_REJECT
:
553 json_object_boolean_true_add(
554 json_nexthop
, "reject");
556 case BLACKHOLE_ADMINPROHIB
:
557 json_object_boolean_true_add(
562 json_object_boolean_true_add(
563 json_nexthop
, "blackhole");
565 case BLACKHOLE_UNSPEC
:
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",
579 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
580 json_object_boolean_true_add(json_nexthop
,
583 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
584 json_object_boolean_true_add(json_nexthop
,
587 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
588 json_object_boolean_true_add(json_nexthop
,
591 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
592 json_object_boolean_true_add(json_nexthop
,
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
,
602 json_object_string_add(
603 json_nexthop
, "source",
607 case NEXTHOP_TYPE_IPV6
:
608 case NEXTHOP_TYPE_IPV6_IFINDEX
:
609 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
611 if (inet_ntop(AF_INET6
,
612 &nexthop
->src
.ipv6
, buf
,
614 json_object_string_add(
615 json_nexthop
, "source",
623 if (nexthop
->nh_label
624 && nexthop
->nh_label
->num_labels
) {
625 json_labels
= json_object_new_array();
627 for (int label_index
= 0;
629 < nexthop
->nh_label
->num_labels
;
631 json_object_array_add(
634 nexthop
->nh_label
->label
637 json_object_object_add(json_nexthop
, "labels",
641 json_object_array_add(json_nexthops
, json_nexthop
);
644 json_object_object_add(json_route
, "nexthops", json_nexthops
);
645 json_object_array_add(json
, json_route
);
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
));
655 len
+= vty_out(vty
, "[%d]", re
->instance
);
658 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
661 re_status_output_char(re
, nexthop
),
662 srcdest_rnode2str(rn
, buf
, sizeof buf
));
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
,
671 vty_out(vty
, " %c%*c",
672 re_status_output_char(re
, nexthop
),
673 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
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
)
682 ifindex2ifname(nexthop
->ifindex
,
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
,
690 if (nexthop
->ifindex
)
692 ifindex2ifname(nexthop
->ifindex
,
696 case NEXTHOP_TYPE_IFINDEX
:
697 vty_out(vty
, " is directly connected, %s",
698 ifindex2ifname(nexthop
->ifindex
,
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)");
707 case BLACKHOLE_ADMINPROHIB
:
708 vty_out(vty
, " (ICMP admin-prohibited)");
711 vty_out(vty
, " (blackhole)");
713 case BLACKHOLE_UNSPEC
:
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
);
726 vty_out(vty
, "(vrf %s)", vrf
->name
);
728 vty_out(vty
, "(vrf UNKNOWN)");
731 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
732 vty_out(vty
, " inactive");
734 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
735 vty_out(vty
, " onlink");
737 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
738 vty_out(vty
, " (recursive)");
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
,
746 vty_out(vty
, ", src %s", buf
);
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
,
754 vty_out(vty
, ", src %s", buf
);
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
,
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
);
776 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
777 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
783 static void vty_show_ip_route_detail_json(struct vty
*vty
,
784 struct route_node
*rn
, bool use_fib
)
786 json_object
*json
= NULL
;
787 json_object
*json_prefix
= NULL
;
788 struct route_entry
*re
;
792 dest
= rib_dest_from_rnode(rn
);
794 json
= json_object_new_object();
795 json_prefix
= json_object_new_array();
797 RNODE_FOREACH_RE (rn
, re
) {
799 * If re not selected for forwarding, skip re
800 * for "show ip/ipv6 fib <prefix> json"
802 if (use_fib
&& re
!= dest
->selected_fib
)
804 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
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
);
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
,
822 struct route_node
*rn
;
823 struct route_entry
*re
;
826 json_object
*json
= NULL
;
827 json_object
*json_prefix
= NULL
;
832 json
= json_object_new_object();
834 /* Show all routes. */
835 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
836 dest
= rib_dest_from_rnode(rn
);
838 RNODE_FOREACH_RE (rn
, re
) {
839 if (use_fib
&& re
!= dest
->selected_fib
)
842 if (tag
&& re
->tag
!= tag
)
846 && !prefix_match(longer_prefix_p
, &rn
->p
))
849 /* This can only be true when the afi is IPv4 */
850 if (supernets_only
) {
851 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
853 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
856 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
859 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
863 if (type
&& re
->type
!= type
)
867 && (re
->type
!= ZEBRA_ROUTE_OSPF
868 || re
->instance
!= ospf_instance_id
))
873 json_prefix
= json_object_new_array();
878 SHOW_ROUTE_V4_HEADER
);
881 SHOW_ROUTE_V6_HEADER
);
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",
893 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
897 prefix2str(&rn
->p
, buf
, sizeof(buf
));
898 json_object_object_add(json
, buf
, json_prefix
);
904 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
905 JSON_C_TO_STRING_PRETTY
));
906 json_object_free(json
);
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
,
913 const struct prefix
*longer_prefix_p
,
914 bool supernets_only
, int type
,
915 unsigned short ospf_instance_id
)
917 struct route_table
*table
;
918 struct zebra_vrf
*zvrf
= NULL
;
920 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
922 vty_out(vty
, "{}\n");
924 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
928 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
930 vty_out(vty
, "{}\n");
932 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
936 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
939 vty_out(vty
, "{}\n");
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);
950 DEFPY (show_route_table
,
951 show_route_table_cmd
,
952 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
958 "The table number to display, if available\n"
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
;
965 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
967 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
968 0, 0, !!json
, table
);
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]",
981 "The table number to display, if available\n"
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
;
991 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
992 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
994 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
996 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
997 0, 0, !!json
, table
);
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]",
1008 "IP routing table\n"
1009 "Display all tables\n"
1010 VRF_FULL_CMD_HELP_STR
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
;
1019 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1020 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1023 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1024 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1026 if (zvrf
&& zvrf
!= info
->zvrf
)
1028 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1031 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
, false, 0,
1032 false, false, 0, 0, !!json
, zrt
->tableid
);
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]",
1043 "IP nexthop tracking table\n"
1044 "IP import check tracking table\n"
1050 VRF_ALL_CMD_HELP_STR
)
1052 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1053 vrf_id_t vrf_id
= VRF_DEFAULT
;
1054 struct prefix prefix
, *p
= NULL
;
1057 if (strcmp(type
, "nht") == 0)
1058 rtype
= RNH_NEXTHOP_TYPE
;
1060 rtype
= RNH_IMPORT_CHECK_TYPE
;
1064 struct zebra_vrf
*zvrf
;
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
,
1075 VRF_GET_ID(vrf_id
, vrf_name
, false);
1077 memset(&prefix
, 0, sizeof(prefix
));
1079 p
= sockunion2hostprefix(addr
, &prefix
);
1081 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1085 DEFUN (ip_nht_default_route
,
1086 ip_nht_default_route_cmd
,
1087 "ip nht resolve-via-default",
1089 "Filter Next Hop tracking route resolution\n"
1090 "Resolve via default route\n")
1092 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1097 if (zvrf
->zebra_rnh_ip_default_route
)
1100 zvrf
->zebra_rnh_ip_default_route
= 1;
1102 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1106 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1108 struct nexthop
*nexthop
= NULL
;
1109 struct nhg_connected
*rb_node_dep
= NULL
;
1110 char buf
[SRCDEST2STR_BUFFER
];
1112 struct vrf
*nhe_vrf
= vrf_lookup_by_id(nhe
->vrf_id
);
1114 vty_out(vty
, "ID: %u\n", nhe
->id
);
1115 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1118 vty_out(vty
, " VRF: %s\n", nhe_vrf
->name
);
1120 vty_out(vty
, " VRF: UNKNOWN\n");
1122 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_DUPLICATE
)) {
1123 vty_out(vty
, " Duplicate - from kernel not hashable\n");
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");
1132 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
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
);
1142 for (ALL_NEXTHOPS_PTR(nhe
->nhg
, nexthop
)) {
1143 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1146 /* Make recursive nexthops a bit more clear */
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
,
1158 case NEXTHOP_TYPE_IPV6
:
1159 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1161 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1163 if (nexthop
->ifindex
)
1164 vty_out(vty
, ", %s",
1165 ifindex2ifname(nexthop
->ifindex
,
1169 case NEXTHOP_TYPE_IFINDEX
:
1170 vty_out(vty
, " directly connected %s",
1171 ifindex2ifname(nexthop
->ifindex
,
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)");
1180 case BLACKHOLE_ADMINPROHIB
:
1181 vty_out(vty
, " (ICMP admin-prohibited)");
1183 case BLACKHOLE_NULL
:
1184 vty_out(vty
, " (blackhole)");
1186 case BLACKHOLE_UNSPEC
:
1194 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1197 vty_out(vty
, " (vrf %s)", vrf
->name
);
1199 vty_out(vty
, " (vrf UNKNOWN)");
1201 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1202 vty_out(vty
, " inactive");
1204 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1205 vty_out(vty
, " onlink");
1207 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1208 vty_out(vty
, " (recursive)");
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
,
1216 vty_out(vty
, ", src %s", buf
);
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
,
1224 vty_out(vty
, ", src %s", buf
);
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
,
1242 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1243 vty_out(vty
, " Dependents:");
1244 frr_each (nhg_connected_tree
, &nhe
->nhg_dependents
,
1246 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1253 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1255 struct nhg_hash_entry
*nhe
= NULL
;
1257 nhe
= zebra_nhg_lookup_id(id
);
1260 show_nexthop_group_out(vty
, nhe
);
1262 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1268 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1269 struct zebra_vrf
*zvrf
, afi_t afi
)
1271 struct list
*list
= hash_to_list(zrouter
.nhgs
);
1272 struct nhg_hash_entry
*nhe
= NULL
;
1273 struct listnode
*node
= NULL
;
1275 for (ALL_LIST_ELEMENTS_RO(list
, node
, nhe
)) {
1277 if (afi
&& nhe
->afi
!= afi
)
1280 if (nhe
->vrf_id
!= zvrf
->vrf
->vrf_id
)
1283 show_nexthop_group_out(vty
, nhe
);
1289 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1291 struct zebra_if
*zebra_if
= NULL
;
1292 struct nhg_connected
*rb_node_dep
= NULL
;
1294 zebra_if
= ifp
->info
;
1296 if (!if_nhg_dependents_is_empty(ifp
)) {
1297 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1299 frr_each (nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1302 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1307 DEFPY (show_interface_nexthop_group
,
1308 show_interface_nexthop_group_cmd
,
1309 "show interface [IFNAME$if_name] nexthop-group",
1311 "Interface status and configuration\n"
1313 "Show Nexthop Groups\n")
1315 struct vrf
*vrf
= NULL
;
1316 struct interface
*ifp
= NULL
;
1319 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1321 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1323 if_nexthop_group_dump_vty(vty
, ifp
);
1327 FOR_ALL_INTERFACES (vrf
, ifp
)
1328 if_nexthop_group_dump_vty(vty
, ifp
);
1334 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
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>]>",
1345 "Show Nexthop Groups\n"
1346 "Nexthop Group ID\n"
1349 VRF_FULL_CMD_HELP_STR
)
1352 struct zebra_vrf
*zvrf
= NULL
;
1356 return show_nexthop_group_id_cmd_helper(vty
, id
);
1366 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1367 struct zebra_vrf
*zvrf
;
1373 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1374 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1381 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1383 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1386 vty_out(vty
, "VRF %s specified does not exist", vrf_name
);
1390 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1395 DEFUN (no_ip_nht_default_route
,
1396 no_ip_nht_default_route_cmd
,
1397 "no ip nht resolve-via-default",
1400 "Filter Next Hop tracking route resolution\n"
1401 "Resolve via default route\n")
1403 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1408 if (!zvrf
->zebra_rnh_ip_default_route
)
1411 zvrf
->zebra_rnh_ip_default_route
= 0;
1412 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1416 DEFUN (ipv6_nht_default_route
,
1417 ipv6_nht_default_route_cmd
,
1418 "ipv6 nht resolve-via-default",
1420 "Filter Next Hop tracking route resolution\n"
1421 "Resolve via default route\n")
1423 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1428 if (zvrf
->zebra_rnh_ipv6_default_route
)
1431 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1432 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1436 DEFUN (no_ipv6_nht_default_route
,
1437 no_ipv6_nht_default_route_cmd
,
1438 "no ipv6 nht resolve-via-default",
1441 "Filter Next Hop tracking route resolution\n"
1442 "Resolve via default route\n")
1445 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1450 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1453 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1454 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1462 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1465 |A.B.C.D/M$prefix longer-prefixes\
1466 |supernets-only$supernets_only\
1469 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1470 |ospf$type_str (1-65535)$ospf_instance_id\
1472 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1475 |X:X::X:X/M$prefix longer-prefixes\
1477 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1482 "IP forwarding table\n"
1483 "IP routing table\n"
1484 VRF_FULL_CMD_HELP_STR
1485 "Show only routes with tag\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"
1494 "IP forwarding table\n"
1495 "IP routing table\n"
1496 VRF_FULL_CMD_HELP_STR
1497 "Show only routes with tag\n"
1500 "Show route matching the specified Network/Mask pair only\n"
1501 FRR_IP6_REDIST_HELP_STR_ZEBRA
1504 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1509 type
= proto_redistnum(afi
, type_str
);
1511 vty_out(vty
, "Unknown route type\n");
1517 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1518 struct zebra_vrf
*zvrf
;
1519 struct route_table
*table
;
1521 if ((zvrf
= vrf
->info
) == NULL
1522 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1526 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1527 !!json
, tag
, prefix_str
? prefix
: NULL
,
1528 !!supernets_only
, type
, ospf_instance_id
);
1531 vrf_id_t vrf_id
= VRF_DEFAULT
;
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
);
1544 DEFPY (show_route_detail
,
1545 show_route_detail_cmd
,
1548 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1553 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
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"
1568 "IPv6 forwarding table\n"
1569 "IPv6 routing table\n"
1570 VRF_FULL_CMD_HELP_STR
1575 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1576 struct route_table
*table
;
1578 struct route_node
*rn
;
1579 bool use_fib
= !!fib
;
1581 bool network_found
= false;
1584 prefix_str
= address_str
;
1585 if (str2prefix(prefix_str
, &p
) < 0) {
1586 vty_out(vty
, "%% Malformed address\n");
1592 struct zebra_vrf
*zvrf
;
1594 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1595 if ((zvrf
= vrf
->info
) == NULL
1596 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1599 rn
= route_node_match(table
, &p
);
1602 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1603 route_unlock_node(rn
);
1607 dest
= rib_dest_from_rnode(rn
);
1608 if (use_fib
&& !dest
->selected_fib
) {
1609 route_unlock_node(rn
);
1613 network_found
= true;
1615 vty_show_ip_route_detail_json(vty
, rn
,
1618 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1620 route_unlock_node(rn
);
1623 if (!network_found
) {
1625 vty_out(vty
, "{}\n");
1629 "%% Network not in FIB\n");
1632 "%% Network not in RIB\n");
1637 vrf_id_t vrf_id
= VRF_DEFAULT
;
1640 VRF_GET_ID(vrf_id
, vrf_name
, false);
1642 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1646 rn
= route_node_match(table
, &p
);
1648 dest
= rib_dest_from_rnode(rn
);
1650 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1651 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1653 vty_out(vty
, "{}\n");
1657 "%% Network not in FIB\n");
1660 "%% Network not in table\n");
1663 route_unlock_node(rn
);
1668 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1670 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1672 route_unlock_node(rn
);
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]",
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"
1692 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1693 struct route_table
*table
;
1696 table_id
= RT_TABLE_MAIN
;
1700 struct zebra_vrf
*zvrf
;
1702 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1703 if ((zvrf
= vrf
->info
) == NULL
)
1706 table
= zebra_vrf_table_with_table_id(afi
,
1714 vty_show_ip_route_summary_prefix(vty
, table
);
1716 vty_show_ip_route_summary(vty
, table
);
1719 vrf_id_t vrf_id
= VRF_DEFAULT
;
1722 VRF_GET_ID(vrf_id
, vrf_name
, false);
1724 table
= zebra_vrf_table_with_table_id(afi
,
1731 vty_show_ip_route_summary_prefix(vty
, table
);
1733 vty_show_ip_route_summary(vty
, table
);
1739 static void vty_show_ip_route_summary(struct vty
*vty
,
1740 struct route_table
*table
)
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];
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
));
1758 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1760 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1762 rib_cnt
[re
->type
]++;
1764 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1765 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1768 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1770 fib_cnt
[re
->type
]++;
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
));
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
]);
1788 vty_out(vty
, "%-20s %-20d %-20d \n",
1789 zebra_route_string(i
), rib_cnt
[i
],
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
]);
1801 * Implementation of the ip route summary prefix command.
1803 * This command prints the primary prefixes that have been installed by various
1804 * protocols on the box.
1807 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1808 struct route_table
*table
)
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];
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
) {
1826 * In case of ECMP, count only once.
1829 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1830 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1831 fib_cnt
[re
->type
]++;
1833 for (nexthop
= re
->ng
->nexthop
; (!cnt
&& nexthop
);
1834 nexthop
= nexthop
->next
) {
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
]++;
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
));
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
]);
1864 vty_out(vty
, "%-20s %-20d %-20d \n",
1865 zebra_route_string(i
), rib_cnt
[i
],
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
]);
1877 * Show IPv6 mroute command.Used to dump
1878 * the Multicast routing table.
1880 DEFUN (show_ipv6_mroute
,
1881 show_ipv6_mroute_cmd
,
1882 "show ipv6 mroute [vrf NAME]",
1885 "IPv6 Multicast routing table\n"
1888 struct route_table
*table
;
1889 struct route_node
*rn
;
1890 struct route_entry
*re
;
1892 vrf_id_t vrf_id
= VRF_DEFAULT
;
1895 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1897 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1901 /* Show all IPv6 route. */
1902 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1903 RNODE_FOREACH_RE (rn
, re
) {
1905 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1908 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1913 DEFUN (show_ipv6_mroute_vrf_all
,
1914 show_ipv6_mroute_vrf_all_cmd
,
1915 "show ipv6 mroute vrf all",
1918 "IPv6 Multicast routing table\n"
1919 VRF_ALL_CMD_HELP_STR
)
1921 struct route_table
*table
;
1922 struct route_node
*rn
;
1923 struct route_entry
*re
;
1925 struct zebra_vrf
*zvrf
;
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
)
1933 /* Show all IPv6 route. */
1934 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1935 RNODE_FOREACH_RE (rn
, re
) {
1937 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1940 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
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")
1956 DEFUN (no_allow_external_route_update
,
1957 no_allow_external_route_update_cmd
,
1958 "no allow-external-route-update",
1960 "Allow FRR routes to be overwritten by external processes\n")
1975 struct zebra_vrf
*zvrf
;
1977 if (vrf_is_backend_netns())
1978 vty_out(vty
, "netns-based vrfs\n");
1980 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1981 if (!(zvrf
= vrf
->info
))
1983 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
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
));
1993 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1995 if (vrf_is_user_cfged(vrf
))
1996 vty_out(vty
, " (configured)");
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"
2008 "Prefix routes only \n")
2011 char err
[ERR_STR_SZ
];
2012 struct zebra_vrf
*zvrf
= NULL
;
2013 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2016 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2023 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2026 vty_out(vty
, "%s\n", err
);
2033 DEFUN (no_default_vrf_vni_mapping
,
2034 no_default_vrf_vni_mapping_cmd
,
2035 "no vni " CMD_VNI_RANGE
,
2037 "VNI corresponding to DEFAULT VRF\n"
2041 char err
[ERR_STR_SZ
];
2042 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2043 struct zebra_vrf
*zvrf
= NULL
;
2045 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2049 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2051 vty_out(vty
, "%s\n", err
);
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"
2063 "prefix-routes-only\n")
2068 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2069 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2070 char err
[ERR_STR_SZ
];
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
,
2083 vty_out(vty
, "%s\n", err
);
2090 DEFUN (no_vrf_vni_mapping
,
2091 no_vrf_vni_mapping_cmd
,
2092 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2094 "VNI corresponding to tenant VRF\n"
2096 "prefix-routes-only\n")
2100 char err
[ERR_STR_SZ
];
2101 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2103 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2111 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2112 ERR_STR_SZ
, filter
, 0);
2114 vty_out(vty
, "%s\n", err
);
2118 /* If no other FRR config for this VRF, mark accordingly. */
2119 if (!zebra_vrf_has_config(zvrf
))
2120 vrf_reset_user_cfged(vrf
);
2126 DEFUN (show_vrf_vni
,
2128 "show vrf vni [json]",
2135 struct zebra_vrf
*zvrf
;
2136 json_object
*json
= NULL
;
2137 json_object
*json_vrfs
= NULL
;
2138 bool uj
= use_json(argc
, argv
);
2141 json
= json_object_new_object();
2142 json_vrfs
= json_object_new_array();
2146 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2147 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2149 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2154 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
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
);
2167 DEFUN (show_evpn_global
,
2168 show_evpn_global_cmd
,
2174 bool uj
= use_json(argc
, argv
);
2176 zebra_vxlan_print_evpn(vty
, uj
);
2180 DEFUN (show_evpn_vni
,
2182 "show evpn vni [json]",
2185 "VxLAN Network Identifier\n"
2188 struct zebra_vrf
*zvrf
;
2189 bool uj
= use_json(argc
, argv
);
2191 zvrf
= zebra_vrf_get_evpn();
2192 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2196 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2197 "show evpn vni detail [json]",
2200 "VxLAN Network Identifier\n"
2201 "Detailed Information On Each VNI\n"
2204 struct zebra_vrf
*zvrf
;
2205 bool uj
= use_json(argc
, argv
);
2207 zvrf
= zebra_vrf_get_evpn();
2208 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2212 DEFUN (show_evpn_vni_vni
,
2213 show_evpn_vni_vni_cmd
,
2214 "show evpn vni " CMD_VNI_RANGE
"[json]",
2217 "VxLAN Network Identifier\n"
2221 struct zebra_vrf
*zvrf
;
2223 bool uj
= use_json(argc
, argv
);
2225 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2226 zvrf
= zebra_vrf_get_evpn();
2227 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
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]",
2240 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2245 bool uj
= use_json(argc
, argv
);
2247 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2248 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2249 vty_out(vty
, "%% Malformed MAC address\n");
2252 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2256 DEFUN (show_evpn_rmac_vni
,
2257 show_evpn_rmac_vni_cmd
,
2258 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2267 bool uj
= use_json(argc
, argv
);
2269 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2270 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2275 DEFUN (show_evpn_rmac_vni_all
,
2276 show_evpn_rmac_vni_all_cmd
,
2277 "show evpn rmac vni all [json]",
2285 bool uj
= use_json(argc
, argv
);
2287 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
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]",
2301 "Host address (ipv4 or ipv6)\n"
2306 bool uj
= use_json(argc
, argv
);
2308 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2309 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2311 vty_out(vty
, "%% Malformed Neighbor address\n");
2314 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2319 DEFUN (show_evpn_nh_vni
,
2320 show_evpn_nh_vni_cmd
,
2321 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2330 bool uj
= use_json(argc
, argv
);
2332 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2333 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2338 DEFUN (show_evpn_nh_vni_all
,
2339 show_evpn_nh_vni_all_cmd
,
2340 "show evpn next-hops vni all [json]",
2348 bool uj
= use_json(argc
, argv
);
2350 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2355 DEFUN (show_evpn_mac_vni
,
2356 show_evpn_mac_vni_cmd
,
2357 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2361 "VxLAN Network Identifier\n"
2365 struct zebra_vrf
*zvrf
;
2367 bool uj
= use_json(argc
, argv
);
2369 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2370 zvrf
= zebra_vrf_get_evpn();
2371 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2375 DEFUN (show_evpn_mac_vni_all
,
2376 show_evpn_mac_vni_all_cmd
,
2377 "show evpn mac vni all [json]",
2381 "VxLAN Network Identifier\n"
2385 struct zebra_vrf
*zvrf
;
2386 bool uj
= use_json(argc
, argv
);
2388 zvrf
= zebra_vrf_get_evpn();
2389 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2393 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2394 "show evpn mac vni all detail [json]",
2398 "VxLAN Network Identifier\n"
2400 "Detailed Information On Each VNI MAC\n"
2403 struct zebra_vrf
*zvrf
;
2404 bool uj
= use_json(argc
, argv
);
2406 zvrf
= zebra_vrf_get_evpn();
2407 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
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]",
2417 "VxLAN Network Identifier\n"
2420 "Remote VTEP IP address\n"
2423 struct zebra_vrf
*zvrf
;
2424 struct in_addr vtep_ip
;
2425 bool uj
= use_json(argc
, argv
);
2427 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2429 vty_out(vty
, "%% Malformed VTEP IP address\n");
2432 zvrf
= zebra_vrf_get_evpn();
2433 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
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]",
2445 "VxLAN Network Identifier\n"
2448 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2452 struct zebra_vrf
*zvrf
;
2455 bool uj
= use_json(argc
, argv
);
2457 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2458 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2459 vty_out(vty
, "%% Malformed MAC address");
2462 zvrf
= zebra_vrf_get_evpn();
2463 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
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]",
2473 "VxLAN Network Identifier\n"
2476 "Remote VTEP IP address\n"
2479 struct zebra_vrf
*zvrf
;
2481 struct in_addr vtep_ip
;
2482 bool uj
= use_json(argc
, argv
);
2484 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2485 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2487 vty_out(vty
, "%% Malformed VTEP IP address\n");
2491 zvrf
= zebra_vrf_get_evpn();
2492 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2496 DEFPY (show_evpn_mac_vni_all_dad
,
2497 show_evpn_mac_vni_all_dad_cmd
,
2498 "show evpn mac vni all duplicate [json]",
2502 "VxLAN Network Identifier\n"
2504 "Duplicate address list\n"
2507 struct zebra_vrf
*zvrf
;
2508 bool uj
= use_json(argc
, argv
);
2510 zvrf
= zebra_vrf_get_evpn();
2511 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2516 DEFPY (show_evpn_mac_vni_dad
,
2517 show_evpn_mac_vni_dad_cmd
,
2518 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2522 "VxLAN Network Identifier\n"
2524 "Duplicate address list\n"
2527 struct zebra_vrf
*zvrf
;
2528 bool uj
= use_json(argc
, argv
);
2530 zvrf
= zebra_vrf_get_evpn();
2532 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
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]",
2542 "ARP and ND cache\n"
2543 "VxLAN Network Identifier\n"
2545 "Duplicate address list\n"
2548 struct zebra_vrf
*zvrf
;
2549 bool uj
= use_json(argc
, argv
);
2551 zvrf
= zebra_vrf_get_evpn();
2552 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
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]",
2561 "ARP and ND cache\n"
2562 "VxLAN Network Identifier\n"
2564 "Duplicate address list\n"
2567 struct zebra_vrf
*zvrf
;
2568 bool uj
= use_json(argc
, argv
);
2570 zvrf
= zebra_vrf_get_evpn();
2571 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2576 DEFUN (show_evpn_neigh_vni
,
2577 show_evpn_neigh_vni_cmd
,
2578 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2581 "ARP and ND cache\n"
2582 "VxLAN Network Identifier\n"
2586 struct zebra_vrf
*zvrf
;
2588 bool uj
= use_json(argc
, argv
);
2590 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2591 zvrf
= zebra_vrf_get_evpn();
2592 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2596 DEFUN (show_evpn_neigh_vni_all
,
2597 show_evpn_neigh_vni_all_cmd
,
2598 "show evpn arp-cache vni all [json]",
2601 "ARP and ND cache\n"
2602 "VxLAN Network Identifier\n"
2606 struct zebra_vrf
*zvrf
;
2607 bool uj
= use_json(argc
, argv
);
2609 zvrf
= zebra_vrf_get_evpn();
2610 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2614 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2615 "show evpn arp-cache vni all detail [json]",
2618 "ARP and ND cache\n"
2619 "VxLAN Network Identifier\n"
2621 "Neighbor details for all vnis in detail\n" JSON_STR
)
2623 struct zebra_vrf
*zvrf
;
2624 bool uj
= use_json(argc
, argv
);
2626 zvrf
= zebra_vrf_get_evpn();
2627 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
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]",
2636 "ARP and ND cache\n"
2637 "VxLAN Network Identifier\n"
2640 "Neighbor address (IPv4 or IPv6 address)\n"
2643 struct zebra_vrf
*zvrf
;
2646 bool uj
= use_json(argc
, argv
);
2648 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2649 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2651 vty_out(vty
, "%% Malformed Neighbor address\n");
2654 zvrf
= zebra_vrf_get_evpn();
2655 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
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]",
2664 "ARP and ND cache\n"
2665 "VxLAN Network Identifier\n"
2668 "Remote VTEP IP address\n"
2671 struct zebra_vrf
*zvrf
;
2673 struct in_addr vtep_ip
;
2674 bool uj
= use_json(argc
, argv
);
2676 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2677 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2679 vty_out(vty
, "%% Malformed VTEP IP address\n");
2683 zvrf
= zebra_vrf_get_evpn();
2684 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2688 /* policy routing contexts */
2689 DEFUN (show_pbr_ipset
,
2691 "show pbr ipset [WORD]",
2693 "Policy-Based Routing\n"
2694 "IPset Context information\n"
2695 "IPset Name information\n")
2699 found
= argv_find(argv
, argc
, "WORD", &idx
);
2701 zebra_pbr_show_ipset_list(vty
, NULL
);
2703 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2707 /* policy routing contexts */
2708 DEFUN (show_pbr_iptable
,
2709 show_pbr_iptable_cmd
,
2710 "show pbr iptable [WORD]",
2712 "Policy-Based Routing\n"
2713 "IPtable Context information\n"
2714 "IPtable Name information\n")
2719 found
= argv_find(argv
, argc
, "WORD", &idx
);
2721 zebra_pbr_show_iptable(vty
, NULL
);
2723 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
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>]>",
2732 "Duplicate address \n"
2733 "VxLAN Network Identifier\n"
2737 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2742 struct zebra_vrf
*zvrf
;
2743 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2744 int ret
= CMD_SUCCESS
;
2746 zvrf
= zebra_vrf_get_evpn();
2748 if (!is_zero_mac(&mac
->eth_addr
)) {
2749 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2753 if (sockunion_family(ip
) == AF_INET
) {
2754 host_ip
.ipa_type
= IPADDR_V4
;
2755 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2757 host_ip
.ipa_type
= IPADDR_V6
;
2758 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2759 sizeof(struct in6_addr
));
2761 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2765 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2768 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2774 /* Static ip route configuration write function. */
2775 static int zebra_ip_config(struct vty
*vty
)
2779 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
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]",
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"
2795 uint32_t table_id
= 0;
2797 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2798 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2800 strmatch(argv
[argc
- 2]->text
, "route-map")
2801 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2805 if (argc
== 7 || (argc
== 5 && !rmap
))
2806 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2808 if (!is_zebra_valid_kernel_table(table_id
)) {
2810 "Invalid routing table ID, %d. Must be in range 1-252\n",
2813 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2817 if (is_zebra_main_routing_table(table_id
)) {
2819 "Invalid routing table ID, %d. Must be non-default table\n",
2822 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2826 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2829 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2834 DEFUN_HIDDEN (zebra_packet_process
,
2835 zebra_packet_process_cmd
,
2836 "zebra zapi-packets (1-10000)",
2839 "Number of packets to process before relinquishing thread\n")
2841 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2843 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2844 memory_order_relaxed
);
2849 DEFUN_HIDDEN (no_zebra_packet_process
,
2850 no_zebra_packet_process_cmd
,
2851 "no zebra zapi-packets [(1-10000)]",
2855 "Number of packets to process before relinquishing thread\n")
2857 atomic_store_explicit(&zrouter
.packets_to_process
,
2858 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2859 memory_order_relaxed
);
2864 DEFUN_HIDDEN (zebra_workqueue_timer
,
2865 zebra_workqueue_timer_cmd
,
2866 "zebra work-queue (0-10000)",
2869 "Time in milliseconds\n")
2871 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2872 zrouter
.ribq
->spec
.hold
= timer
;
2877 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2878 no_zebra_workqueue_timer_cmd
,
2879 "no zebra work-queue [(0-10000)]",
2883 "Time in milliseconds\n")
2885 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
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]",
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"
2902 uint32_t table_id
= 0;
2903 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2905 if (!is_zebra_valid_kernel_table(table_id
)) {
2907 "Invalid routing table ID. Must be in range 1-252\n");
2911 if (is_zebra_main_routing_table(table_id
)) {
2913 "Invalid routing table ID, %d. Must be non-default table\n",
2918 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2921 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2924 static int config_write_protocol(struct vty
*vty
)
2927 vty_out(vty
, "allow-external-route-update\n");
2929 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2930 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
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
);
2936 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
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
2942 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2944 : ipv4_multicast_mode
2945 == MCAST_MIX_MRIB_FIRST
2947 : ipv4_multicast_mode
2948 == MCAST_MIX_DISTANCE
2952 /* Include dataplane info */
2953 dplane_config_write_helper(vty
);
2967 " Route Route Neighbor LSP LSP\n");
2969 "VRF Installs Removals Updates Installs Removals\n");
2971 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2972 struct zebra_vrf
*zvrf
= vrf
->info
;
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
);
2984 DEFUN (ip_forwarding
,
2988 "Turn on IP forwarding\n")
2994 ret
= ipforward_on();
2997 vty_out(vty
, "Can't turn on IP forwarding\n");
2998 return CMD_WARNING_CONFIG_FAILED
;
3004 DEFUN (no_ip_forwarding
,
3005 no_ip_forwarding_cmd
,
3009 "Turn off IP forwarding\n")
3015 ret
= ipforward_off();
3018 vty_out(vty
, "Can't turn off IP forwarding\n");
3019 return CMD_WARNING_CONFIG_FAILED
;
3025 /* Only display ip forwarding is enabled or not. */
3026 DEFUN (show_ip_forwarding
,
3027 show_ip_forwarding_cmd
,
3028 "show ip forwarding",
3031 "IP forwarding status\n")
3038 vty_out(vty
, "IP forwarding is off\n");
3040 vty_out(vty
, "IP forwarding is on\n");
3044 /* Only display ipv6 forwarding is enabled or not. */
3045 DEFUN (show_ipv6_forwarding
,
3046 show_ipv6_forwarding_cmd
,
3047 "show ipv6 forwarding",
3049 "IPv6 information\n"
3050 "Forwarding status\n")
3054 ret
= ipforward_ipv6();
3058 vty_out(vty
, "ipv6 forwarding is unknown\n");
3061 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3064 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3067 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3073 DEFUN (ipv6_forwarding
,
3074 ipv6_forwarding_cmd
,
3077 "Turn on IPv6 forwarding\n")
3081 ret
= ipforward_ipv6();
3083 ret
= ipforward_ipv6_on();
3086 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3087 return CMD_WARNING_CONFIG_FAILED
;
3093 DEFUN (no_ipv6_forwarding
,
3094 no_ipv6_forwarding_cmd
,
3095 "no ipv6 forwarding",
3098 "Turn off IPv6 forwarding\n")
3102 ret
= ipforward_ipv6();
3104 ret
= ipforward_ipv6_off();
3107 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3108 return CMD_WARNING_CONFIG_FAILED
;
3114 /* Display dataplane info */
3115 DEFUN (show_dataplane
,
3117 "show zebra dplane [detailed]",
3120 "Zebra dataplane information\n"
3121 "Detailed output\n")
3124 bool detailed
= false;
3126 if (argv_find(argv
, argc
, "detailed", &idx
))
3129 return dplane_show_helper(vty
, detailed
);
3132 /* Display dataplane providers info */
3133 DEFUN (show_dataplane_providers
,
3134 show_dataplane_providers_cmd
,
3135 "show zebra dplane providers [detailed]",
3138 "Zebra dataplane information\n"
3139 "Zebra dataplane provider information\n"
3140 "Detailed output\n")
3143 bool detailed
= false;
3145 if (argv_find(argv
, argc
, "detailed", &idx
))
3148 return dplane_show_provs_helper(vty
, detailed
);
3151 /* Configure dataplane incoming queue limit */
3152 DEFUN (zebra_dplane_queue_limit
,
3153 zebra_dplane_queue_limit_cmd
,
3154 "zebra dplane limit (0-10000)",
3157 "Limit incoming queued updates\n"
3158 "Number of queued updates\n")
3162 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3164 dplane_set_in_queue_limit(limit
, true);
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)]",
3176 "Limit incoming queued updates\n"
3177 "Number of queued updates\n")
3179 dplane_set_in_queue_limit(0, false);
3184 DEFUN (zebra_show_routing_tables_summary
,
3185 zebra_show_routing_tables_summary_cmd
,
3186 "show zebra router table summary",
3189 "The Zebra Router Information\n"
3190 "Table Information about this Zebra Router\n"
3191 "Summary Information\n")
3193 zebra_router_show_table_summary(vty
);
3198 /* Table configuration write function. */
3199 static int config_write_table(struct vty
*vty
)
3204 /* IPForwarding configuration write function. */
3205 static int config_write_forwarding(struct vty
*vty
)
3207 /* FIXME: Find better place for that. */
3208 router_id_write(vty
);
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");
3218 DEFUN_HIDDEN (show_frr
,
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");
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. */
3288 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3289 "", /* This node has no interface. */
3293 void zebra_vty_init(void)
3295 /* Install configuration write function. */
3296 install_node(&table_node
, config_write_table
);
3297 install_node(&forwarding_node
, config_write_forwarding
);
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
);
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
);
3309 zebra_route_map_init();
3311 install_node(&ip_node
, zebra_ip_config
);
3312 install_node(&protocol_node
, config_write_protocol
);
3314 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3315 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3317 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3318 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
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
);
3327 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3328 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
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
);
3341 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3342 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
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
);
3354 /* Commands for VRF */
3355 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
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
);
3385 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3386 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
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
);
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
);
3398 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);