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
);
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, 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
, bool show_ng
)
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");
264 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
266 for (ALL_NEXTHOPS_PTR(re
->ng
, nexthop
)) {
269 vty_out(vty
, " %c%s",
270 re_status_output_char(re
, nexthop
),
271 nexthop
->rparent
? " " : "");
273 switch (nexthop
->type
) {
274 case NEXTHOP_TYPE_IPV4
:
275 case NEXTHOP_TYPE_IPV4_IFINDEX
:
277 inet_ntoa(nexthop
->gate
.ipv4
));
278 if (nexthop
->ifindex
)
279 vty_out(vty
, ", via %s",
284 case NEXTHOP_TYPE_IPV6
:
285 case NEXTHOP_TYPE_IPV6_IFINDEX
:
287 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
289 if (nexthop
->ifindex
)
290 vty_out(vty
, ", via %s",
295 case NEXTHOP_TYPE_IFINDEX
:
296 vty_out(vty
, " directly connected, %s",
297 ifindex2ifname(nexthop
->ifindex
,
300 case NEXTHOP_TYPE_BLACKHOLE
:
301 vty_out(vty
, " unreachable");
302 switch (nexthop
->bh_type
) {
303 case BLACKHOLE_REJECT
:
304 vty_out(vty
, " (ICMP unreachable)");
306 case BLACKHOLE_ADMINPROHIB
:
308 " (ICMP admin-prohibited)");
311 vty_out(vty
, " (blackhole)");
313 case BLACKHOLE_UNSPEC
:
321 if ((re
->vrf_id
!= nexthop
->vrf_id
)
322 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
324 vrf_lookup_by_id(nexthop
->vrf_id
);
327 vty_out(vty
, "(vrf %s)", vrf
->name
);
329 vty_out(vty
, "(vrf UNKNOWN)");
332 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
333 vty_out(vty
, " (duplicate nexthop removed)");
335 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
336 vty_out(vty
, " inactive");
338 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
339 vty_out(vty
, " onlink");
341 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
342 vty_out(vty
, " (recursive)");
344 switch (nexthop
->type
) {
345 case NEXTHOP_TYPE_IPV4
:
346 case NEXTHOP_TYPE_IPV4_IFINDEX
:
347 if (nexthop
->src
.ipv4
.s_addr
) {
348 if (inet_ntop(AF_INET
,
350 addrstr
, sizeof addrstr
))
351 vty_out(vty
, ", src %s",
355 case NEXTHOP_TYPE_IPV6
:
356 case NEXTHOP_TYPE_IPV6_IFINDEX
:
357 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
359 if (inet_ntop(AF_INET6
,
361 addrstr
, sizeof addrstr
))
362 vty_out(vty
, ", src %s",
371 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
373 /* Label information */
374 if (nexthop
->nh_label
375 && nexthop
->nh_label
->num_labels
) {
376 vty_out(vty
, ", label %s",
378 nexthop
->nh_label
->num_labels
,
379 nexthop
->nh_label
->label
, buf
,
389 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
390 struct route_entry
*re
, json_object
*json
,
393 struct nexthop
*nexthop
;
395 char buf
[SRCDEST2STR_BUFFER
];
396 json_object
*json_nexthops
= NULL
;
397 json_object
*json_nexthop
= NULL
;
398 json_object
*json_route
= NULL
;
399 json_object
*json_labels
= NULL
;
402 struct vrf
*vrf
= NULL
;
403 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
404 struct nexthop_group
*nhg
;
406 uptime
= monotime(NULL
);
407 uptime
-= re
->uptime
;
408 tm
= gmtime(&uptime
);
410 /* If showing fib information, use the fib view of the
414 nhg
= rib_active_nhg(re
);
419 json_route
= json_object_new_object();
420 json_nexthops
= json_object_new_array();
422 json_object_string_add(json_route
, "prefix",
423 srcdest_rnode2str(rn
, buf
, sizeof buf
));
424 json_object_string_add(json_route
, "protocol",
425 zebra_route_string(re
->type
));
428 json_object_int_add(json_route
, "instance",
432 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
433 vrf
= vrf_lookup_by_id(re
->vrf_id
);
434 json_object_string_add(json_route
, "vrfName",
438 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
439 json_object_boolean_true_add(json_route
, "selected");
441 if (dest
->selected_fib
== re
)
442 json_object_boolean_true_add(json_route
,
445 json_object_int_add(json_route
, "distance",
447 json_object_int_add(json_route
, "metric", re
->metric
);
449 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
450 json_object_boolean_true_add(json_route
, "installed");
452 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
453 json_object_boolean_true_add(json_route
, "failed");
455 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
456 json_object_boolean_true_add(json_route
, "queued");
459 json_object_int_add(json_route
, "tag", re
->tag
);
462 json_object_int_add(json_route
, "table", re
->table
);
464 json_object_int_add(json_route
, "internalStatus",
466 json_object_int_add(json_route
, "internalFlags",
468 json_object_int_add(json_route
, "internalNextHopNum",
469 nexthop_group_nexthop_num(re
->ng
));
470 json_object_int_add(json_route
, "internalNextHopActiveNum",
471 nexthop_group_active_nexthop_num(re
->ng
));
472 if (uptime
< ONE_DAY_SECOND
)
473 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
475 else if (uptime
< ONE_WEEK_SECOND
)
476 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
479 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
480 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
483 json_object_string_add(json_route
, "uptime", buf
);
485 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
486 json_nexthop
= json_object_new_object();
488 json_object_int_add(json_nexthop
, "flags",
491 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
492 json_object_boolean_true_add(json_nexthop
,
495 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
496 json_object_boolean_true_add(json_nexthop
,
499 switch (nexthop
->type
) {
500 case NEXTHOP_TYPE_IPV4
:
501 case NEXTHOP_TYPE_IPV4_IFINDEX
:
502 json_object_string_add(
504 inet_ntoa(nexthop
->gate
.ipv4
));
505 json_object_string_add(json_nexthop
, "afi",
508 if (nexthop
->ifindex
) {
509 json_object_int_add(json_nexthop
,
512 json_object_string_add(
513 json_nexthop
, "interfaceName",
519 case NEXTHOP_TYPE_IPV6
:
520 case NEXTHOP_TYPE_IPV6_IFINDEX
:
521 json_object_string_add(
523 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
525 json_object_string_add(json_nexthop
, "afi",
528 if (nexthop
->ifindex
) {
529 json_object_int_add(json_nexthop
,
532 json_object_string_add(
533 json_nexthop
, "interfaceName",
540 case NEXTHOP_TYPE_IFINDEX
:
541 json_object_boolean_true_add(
542 json_nexthop
, "directlyConnected");
543 json_object_int_add(json_nexthop
,
546 json_object_string_add(
547 json_nexthop
, "interfaceName",
548 ifindex2ifname(nexthop
->ifindex
,
551 case NEXTHOP_TYPE_BLACKHOLE
:
552 json_object_boolean_true_add(json_nexthop
,
554 switch (nexthop
->bh_type
) {
555 case BLACKHOLE_REJECT
:
556 json_object_boolean_true_add(
557 json_nexthop
, "reject");
559 case BLACKHOLE_ADMINPROHIB
:
560 json_object_boolean_true_add(
565 json_object_boolean_true_add(
566 json_nexthop
, "blackhole");
568 case BLACKHOLE_UNSPEC
:
576 if ((nexthop
->vrf_id
!= re
->vrf_id
)
577 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
578 vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
579 json_object_string_add(json_nexthop
, "vrf",
582 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
583 json_object_boolean_true_add(json_nexthop
,
586 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
587 json_object_boolean_true_add(json_nexthop
,
590 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
591 json_object_boolean_true_add(json_nexthop
,
594 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
595 json_object_boolean_true_add(json_nexthop
,
598 switch (nexthop
->type
) {
599 case NEXTHOP_TYPE_IPV4
:
600 case NEXTHOP_TYPE_IPV4_IFINDEX
:
601 if (nexthop
->src
.ipv4
.s_addr
) {
602 if (inet_ntop(AF_INET
,
603 &nexthop
->src
.ipv4
, buf
,
605 json_object_string_add(
606 json_nexthop
, "source",
610 case NEXTHOP_TYPE_IPV6
:
611 case NEXTHOP_TYPE_IPV6_IFINDEX
:
612 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
614 if (inet_ntop(AF_INET6
,
615 &nexthop
->src
.ipv6
, buf
,
617 json_object_string_add(
618 json_nexthop
, "source",
626 if (nexthop
->nh_label
627 && nexthop
->nh_label
->num_labels
) {
628 json_labels
= json_object_new_array();
630 for (int label_index
= 0;
632 < nexthop
->nh_label
->num_labels
;
634 json_object_array_add(
637 nexthop
->nh_label
->label
640 json_object_object_add(json_nexthop
, "labels",
644 json_object_array_add(json_nexthops
, json_nexthop
);
647 json_object_object_add(json_route
, "nexthops", json_nexthops
);
648 json_object_array_add(json
, json_route
);
652 /* Nexthop information. */
653 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
654 if (nexthop
== nhg
->nexthop
) {
655 /* Prefix information. */
656 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
658 len
+= vty_out(vty
, "[%d]", re
->instance
);
661 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
664 re_status_output_char(re
, nexthop
),
665 srcdest_rnode2str(rn
, buf
, sizeof buf
));
667 /* Distance and metric display. */
668 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
669 (re
->distance
|| re
->metric
)) ||
670 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
671 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
674 vty_out(vty
, " %c%*c",
675 re_status_output_char(re
, nexthop
),
676 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
679 switch (nexthop
->type
) {
680 case NEXTHOP_TYPE_IPV4
:
681 case NEXTHOP_TYPE_IPV4_IFINDEX
:
682 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
683 if (nexthop
->ifindex
)
685 ifindex2ifname(nexthop
->ifindex
,
688 case NEXTHOP_TYPE_IPV6
:
689 case NEXTHOP_TYPE_IPV6_IFINDEX
:
690 vty_out(vty
, " via %s",
691 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
693 if (nexthop
->ifindex
)
695 ifindex2ifname(nexthop
->ifindex
,
699 case NEXTHOP_TYPE_IFINDEX
:
700 vty_out(vty
, " is directly connected, %s",
701 ifindex2ifname(nexthop
->ifindex
,
704 case NEXTHOP_TYPE_BLACKHOLE
:
705 vty_out(vty
, " unreachable");
706 switch (nexthop
->bh_type
) {
707 case BLACKHOLE_REJECT
:
708 vty_out(vty
, " (ICMP unreachable)");
710 case BLACKHOLE_ADMINPROHIB
:
711 vty_out(vty
, " (ICMP admin-prohibited)");
714 vty_out(vty
, " (blackhole)");
716 case BLACKHOLE_UNSPEC
:
724 if ((nexthop
->vrf_id
!= re
->vrf_id
)
725 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
726 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
729 vty_out(vty
, "(vrf %s)", vrf
->name
);
731 vty_out(vty
, "(vrf UNKNOWN)");
734 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
735 vty_out(vty
, " inactive");
737 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
738 vty_out(vty
, " onlink");
740 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
741 vty_out(vty
, " (recursive)");
743 switch (nexthop
->type
) {
744 case NEXTHOP_TYPE_IPV4
:
745 case NEXTHOP_TYPE_IPV4_IFINDEX
:
746 if (nexthop
->src
.ipv4
.s_addr
) {
747 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
749 vty_out(vty
, ", src %s", buf
);
752 case NEXTHOP_TYPE_IPV6
:
753 case NEXTHOP_TYPE_IPV6_IFINDEX
:
754 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
755 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
757 vty_out(vty
, ", src %s", buf
);
764 /* Label information */
765 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
766 vty_out(vty
, ", label %s",
767 mpls_label2str(nexthop
->nh_label
->num_labels
,
768 nexthop
->nh_label
->label
, buf
,
772 if (uptime
< ONE_DAY_SECOND
)
773 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
774 tm
->tm_min
, tm
->tm_sec
);
775 else if (uptime
< ONE_WEEK_SECOND
)
776 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
777 tm
->tm_hour
, tm
->tm_min
);
779 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
780 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
786 static void vty_show_ip_route_detail_json(struct vty
*vty
,
787 struct route_node
*rn
, bool use_fib
)
789 json_object
*json
= NULL
;
790 json_object
*json_prefix
= NULL
;
791 struct route_entry
*re
;
795 dest
= rib_dest_from_rnode(rn
);
797 json
= json_object_new_object();
798 json_prefix
= json_object_new_array();
800 RNODE_FOREACH_RE (rn
, re
) {
802 * If re not selected for forwarding, skip re
803 * for "show ip/ipv6 fib <prefix> json"
805 if (use_fib
&& re
!= dest
->selected_fib
)
807 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
810 prefix2str(&rn
->p
, buf
, sizeof(buf
));
811 json_object_object_add(json
, buf
, json_prefix
);
812 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
813 json
, JSON_C_TO_STRING_PRETTY
));
814 json_object_free(json
);
817 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
818 struct route_table
*table
, afi_t afi
,
819 bool use_fib
, route_tag_t tag
,
820 const struct prefix
*longer_prefix_p
,
821 bool supernets_only
, int type
,
822 unsigned short ospf_instance_id
, bool use_json
,
825 struct route_node
*rn
;
826 struct route_entry
*re
;
829 json_object
*json
= NULL
;
830 json_object
*json_prefix
= NULL
;
835 json
= json_object_new_object();
837 /* Show all routes. */
838 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
839 dest
= rib_dest_from_rnode(rn
);
841 RNODE_FOREACH_RE (rn
, re
) {
842 if (use_fib
&& re
!= dest
->selected_fib
)
845 if (tag
&& re
->tag
!= tag
)
849 && !prefix_match(longer_prefix_p
, &rn
->p
))
852 /* This can only be true when the afi is IPv4 */
853 if (supernets_only
) {
854 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
856 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
859 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
862 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
866 if (type
&& re
->type
!= type
)
870 && (re
->type
!= ZEBRA_ROUTE_OSPF
871 || re
->instance
!= ospf_instance_id
))
876 json_prefix
= json_object_new_array();
881 SHOW_ROUTE_V4_HEADER
);
884 SHOW_ROUTE_V6_HEADER
);
886 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
887 vty_out(vty
, "\nVRF %s table %u:\n",
888 zvrf_name(zvrf
), tableid
);
889 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
890 vty_out(vty
, "\nVRF %s:\n",
896 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
900 prefix2str(&rn
->p
, buf
, sizeof(buf
));
901 json_object_object_add(json
, buf
, json_prefix
);
907 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
908 JSON_C_TO_STRING_PRETTY
));
909 json_object_free(json
);
913 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
914 safi_t safi
, bool use_fib
, bool use_json
,
916 const struct prefix
*longer_prefix_p
,
917 bool supernets_only
, int type
,
918 unsigned short ospf_instance_id
)
920 struct route_table
*table
;
921 struct zebra_vrf
*zvrf
= NULL
;
923 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
925 vty_out(vty
, "{}\n");
927 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
931 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
933 vty_out(vty
, "{}\n");
935 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
939 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
942 vty_out(vty
, "{}\n");
946 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
947 longer_prefix_p
, supernets_only
, type
,
948 ospf_instance_id
, use_json
, 0);
953 DEFPY (show_route_table
,
954 show_route_table_cmd
,
955 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
961 "The table number to display, if available\n"
964 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
965 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
966 struct route_table
*t
;
968 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
970 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
971 0, 0, !!json
, table
);
976 DEFPY (show_route_table_vrf
,
977 show_route_table_vrf_cmd
,
978 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
984 "The table number to display, if available\n"
988 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
989 struct zebra_vrf
*zvrf
;
990 struct route_table
*t
;
991 vrf_id_t vrf_id
= VRF_DEFAULT
;
994 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
995 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
997 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
999 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
1000 0, 0, !!json
, table
);
1005 DEFPY (show_route_all_table_vrf
,
1006 show_route_all_table_vrf_cmd
,
1007 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1011 "IP routing table\n"
1012 "Display all tables\n"
1013 VRF_FULL_CMD_HELP_STR
1016 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1017 struct zebra_vrf
*zvrf
= NULL
;
1018 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1019 struct zebra_router_table
*zrt
;
1022 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1023 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1026 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1027 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1029 if (zvrf
&& zvrf
!= info
->zvrf
)
1031 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1034 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
, false, 0,
1035 false, false, 0, 0, !!json
, zrt
->tableid
);
1042 "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name [<A.B.C.D|X:X::X:X>$addr]|vrf all$vrf_all]",
1046 "IP nexthop tracking table\n"
1047 "IP import check tracking table\n"
1053 VRF_ALL_CMD_HELP_STR
)
1055 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1056 vrf_id_t vrf_id
= VRF_DEFAULT
;
1057 struct prefix prefix
, *p
= NULL
;
1060 if (strcmp(type
, "nht") == 0)
1061 rtype
= RNH_NEXTHOP_TYPE
;
1063 rtype
= RNH_IMPORT_CHECK_TYPE
;
1067 struct zebra_vrf
*zvrf
;
1069 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1070 if ((zvrf
= vrf
->info
) != NULL
) {
1071 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1072 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1078 VRF_GET_ID(vrf_id
, vrf_name
, false);
1080 memset(&prefix
, 0, sizeof(prefix
));
1082 p
= sockunion2hostprefix(addr
, &prefix
);
1084 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1088 DEFUN (ip_nht_default_route
,
1089 ip_nht_default_route_cmd
,
1090 "ip nht resolve-via-default",
1092 "Filter Next Hop tracking route resolution\n"
1093 "Resolve via default route\n")
1095 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1100 if (zvrf
->zebra_rnh_ip_default_route
)
1103 zvrf
->zebra_rnh_ip_default_route
= 1;
1105 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1109 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1111 struct nexthop
*nexthop
= NULL
;
1112 struct nhg_connected
*rb_node_dep
= NULL
;
1113 char buf
[SRCDEST2STR_BUFFER
];
1115 struct vrf
*nhe_vrf
= vrf_lookup_by_id(nhe
->vrf_id
);
1117 vty_out(vty
, "ID: %u\n", nhe
->id
);
1118 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1121 vty_out(vty
, " VRF: %s\n", nhe_vrf
->name
);
1123 vty_out(vty
, " VRF: UNKNOWN\n");
1125 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_DUPLICATE
)) {
1126 vty_out(vty
, " Duplicate - from kernel not hashable\n");
1128 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1129 vty_out(vty
, " Valid");
1130 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1131 vty_out(vty
, ", Installed");
1135 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1137 if (!zebra_nhg_depends_is_empty(nhe
)) {
1138 vty_out(vty
, " Depends:");
1139 frr_each (nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1140 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1145 for (ALL_NEXTHOPS_PTR(nhe
->nhg
, nexthop
)) {
1146 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1149 /* Make recursive nexthops a bit more clear */
1152 switch (nexthop
->type
) {
1153 case NEXTHOP_TYPE_IPV4
:
1154 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1155 vty_out(vty
, " %s", inet_ntoa(nexthop
->gate
.ipv4
));
1156 if (nexthop
->ifindex
)
1157 vty_out(vty
, ", %s",
1158 ifindex2ifname(nexthop
->ifindex
,
1161 case NEXTHOP_TYPE_IPV6
:
1162 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1164 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1166 if (nexthop
->ifindex
)
1167 vty_out(vty
, ", %s",
1168 ifindex2ifname(nexthop
->ifindex
,
1172 case NEXTHOP_TYPE_IFINDEX
:
1173 vty_out(vty
, " directly connected %s",
1174 ifindex2ifname(nexthop
->ifindex
,
1177 case NEXTHOP_TYPE_BLACKHOLE
:
1178 vty_out(vty
, " unreachable");
1179 switch (nexthop
->bh_type
) {
1180 case BLACKHOLE_REJECT
:
1181 vty_out(vty
, " (ICMP unreachable)");
1183 case BLACKHOLE_ADMINPROHIB
:
1184 vty_out(vty
, " (ICMP admin-prohibited)");
1186 case BLACKHOLE_NULL
:
1187 vty_out(vty
, " (blackhole)");
1189 case BLACKHOLE_UNSPEC
:
1197 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1200 vty_out(vty
, " (vrf %s)", vrf
->name
);
1202 vty_out(vty
, " (vrf UNKNOWN)");
1204 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1205 vty_out(vty
, " inactive");
1207 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1208 vty_out(vty
, " onlink");
1210 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1211 vty_out(vty
, " (recursive)");
1213 switch (nexthop
->type
) {
1214 case NEXTHOP_TYPE_IPV4
:
1215 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1216 if (nexthop
->src
.ipv4
.s_addr
) {
1217 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1219 vty_out(vty
, ", src %s", buf
);
1222 case NEXTHOP_TYPE_IPV6
:
1223 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1224 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1225 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1227 vty_out(vty
, ", src %s", buf
);
1234 /* Label information */
1235 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1236 vty_out(vty
, ", label %s",
1237 mpls_label2str(nexthop
->nh_label
->num_labels
,
1238 nexthop
->nh_label
->label
, buf
,
1245 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1246 vty_out(vty
, " Dependents:");
1247 frr_each (nhg_connected_tree
, &nhe
->nhg_dependents
,
1249 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1256 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1258 struct nhg_hash_entry
*nhe
= NULL
;
1260 nhe
= zebra_nhg_lookup_id(id
);
1263 show_nexthop_group_out(vty
, nhe
);
1265 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1271 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1272 struct zebra_vrf
*zvrf
, afi_t afi
)
1274 struct list
*list
= hash_to_list(zrouter
.nhgs
);
1275 struct nhg_hash_entry
*nhe
= NULL
;
1276 struct listnode
*node
= NULL
;
1278 for (ALL_LIST_ELEMENTS_RO(list
, node
, nhe
)) {
1280 if (afi
&& nhe
->afi
!= afi
)
1283 if (nhe
->vrf_id
!= zvrf
->vrf
->vrf_id
)
1286 show_nexthop_group_out(vty
, nhe
);
1292 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1294 struct zebra_if
*zebra_if
= NULL
;
1295 struct nhg_connected
*rb_node_dep
= NULL
;
1297 zebra_if
= ifp
->info
;
1299 if (!if_nhg_dependents_is_empty(ifp
)) {
1300 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1302 frr_each (nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1305 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1310 DEFPY (show_interface_nexthop_group
,
1311 show_interface_nexthop_group_cmd
,
1312 "show interface [IFNAME$if_name] nexthop-group",
1314 "Interface status and configuration\n"
1316 "Show Nexthop Groups\n")
1318 struct vrf
*vrf
= NULL
;
1319 struct interface
*ifp
= NULL
;
1322 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1324 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1326 if_nexthop_group_dump_vty(vty
, ifp
);
1330 FOR_ALL_INTERFACES (vrf
, ifp
)
1331 if_nexthop_group_dump_vty(vty
, ifp
);
1337 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1344 DEFPY (show_nexthop_group
,
1345 show_nexthop_group_cmd
,
1346 "show nexthop-group <(0-4294967295)$id|[<ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
1348 "Show Nexthop Groups\n"
1349 "Nexthop Group ID\n"
1352 VRF_FULL_CMD_HELP_STR
)
1355 struct zebra_vrf
*zvrf
= NULL
;
1359 return show_nexthop_group_id_cmd_helper(vty
, id
);
1369 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1370 struct zebra_vrf
*zvrf
;
1376 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1377 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1384 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1386 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1389 vty_out(vty
, "VRF %s specified does not exist", vrf_name
);
1393 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1398 DEFUN (no_ip_nht_default_route
,
1399 no_ip_nht_default_route_cmd
,
1400 "no ip nht resolve-via-default",
1403 "Filter Next Hop tracking route resolution\n"
1404 "Resolve via default route\n")
1406 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1411 if (!zvrf
->zebra_rnh_ip_default_route
)
1414 zvrf
->zebra_rnh_ip_default_route
= 0;
1415 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1419 DEFUN (ipv6_nht_default_route
,
1420 ipv6_nht_default_route_cmd
,
1421 "ipv6 nht resolve-via-default",
1423 "Filter Next Hop tracking route resolution\n"
1424 "Resolve via default route\n")
1426 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1431 if (zvrf
->zebra_rnh_ipv6_default_route
)
1434 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1435 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1439 DEFUN (no_ipv6_nht_default_route
,
1440 no_ipv6_nht_default_route_cmd
,
1441 "no ipv6 nht resolve-via-default",
1444 "Filter Next Hop tracking route resolution\n"
1445 "Resolve via default route\n")
1448 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1453 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1456 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1457 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1465 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1468 |A.B.C.D/M$prefix longer-prefixes\
1469 |supernets-only$supernets_only\
1472 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1473 |ospf$type_str (1-65535)$ospf_instance_id\
1475 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1478 |X:X::X:X/M$prefix longer-prefixes\
1480 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1485 "IP forwarding table\n"
1486 "IP routing table\n"
1487 VRF_FULL_CMD_HELP_STR
1488 "Show only routes with tag\n"
1490 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1491 "Show route matching the specified Network/Mask pair only\n"
1492 "Show supernet entries only\n"
1493 FRR_IP_REDIST_HELP_STR_ZEBRA
1494 "Open Shortest Path First (OSPFv2)\n"
1497 "IP forwarding table\n"
1498 "IP routing table\n"
1499 VRF_FULL_CMD_HELP_STR
1500 "Show only routes with tag\n"
1503 "Show route matching the specified Network/Mask pair only\n"
1504 FRR_IP6_REDIST_HELP_STR_ZEBRA
1507 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1512 type
= proto_redistnum(afi
, type_str
);
1514 vty_out(vty
, "Unknown route type\n");
1520 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1521 struct zebra_vrf
*zvrf
;
1522 struct route_table
*table
;
1524 if ((zvrf
= vrf
->info
) == NULL
1525 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1529 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1530 !!json
, tag
, prefix_str
? prefix
: NULL
,
1531 !!supernets_only
, type
, ospf_instance_id
);
1534 vrf_id_t vrf_id
= VRF_DEFAULT
;
1537 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1538 vrf
= vrf_lookup_by_id(vrf_id
);
1539 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1540 !!json
, tag
, prefix_str
? prefix
: NULL
,
1541 !!supernets_only
, type
, ospf_instance_id
);
1547 DEFPY (show_route_detail
,
1548 show_route_detail_cmd
,
1551 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1556 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1562 [json$json] [nexthop-group$ng]",
1565 "IPv6 forwarding table\n"
1566 "IP routing table\n"
1567 VRF_FULL_CMD_HELP_STR
1568 "Network in the IP routing table to display\n"
1569 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1571 "IPv6 forwarding table\n"
1572 "IPv6 routing table\n"
1573 VRF_FULL_CMD_HELP_STR
1577 "Nexthop Group Information\n")
1579 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1580 struct route_table
*table
;
1582 struct route_node
*rn
;
1583 bool use_fib
= !!fib
;
1585 bool network_found
= false;
1586 bool show_ng
= !!ng
;
1589 prefix_str
= address_str
;
1590 if (str2prefix(prefix_str
, &p
) < 0) {
1591 vty_out(vty
, "%% Malformed address\n");
1597 struct zebra_vrf
*zvrf
;
1599 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1600 if ((zvrf
= vrf
->info
) == NULL
1601 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1604 rn
= route_node_match(table
, &p
);
1607 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1608 route_unlock_node(rn
);
1612 dest
= rib_dest_from_rnode(rn
);
1613 if (use_fib
&& !dest
->selected_fib
) {
1614 route_unlock_node(rn
);
1618 network_found
= true;
1620 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1622 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1625 route_unlock_node(rn
);
1628 if (!network_found
) {
1630 vty_out(vty
, "{}\n");
1634 "%% Network not in FIB\n");
1637 "%% Network not in RIB\n");
1642 vrf_id_t vrf_id
= VRF_DEFAULT
;
1645 VRF_GET_ID(vrf_id
, vrf_name
, false);
1647 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1651 rn
= route_node_match(table
, &p
);
1653 dest
= rib_dest_from_rnode(rn
);
1655 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1656 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1658 vty_out(vty
, "{}\n");
1662 "%% Network not in FIB\n");
1665 "%% Network not in table\n");
1668 route_unlock_node(rn
);
1673 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1675 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1677 route_unlock_node(rn
);
1683 DEFPY (show_route_summary
,
1684 show_route_summary_cmd
,
1685 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1686 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1690 "IP routing table\n"
1691 VRF_FULL_CMD_HELP_STR
1692 "Summary of all routes\n"
1693 "Table to display summary for\n"
1694 "The table number\n"
1697 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1698 struct route_table
*table
;
1701 table_id
= RT_TABLE_MAIN
;
1705 struct zebra_vrf
*zvrf
;
1707 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1708 if ((zvrf
= vrf
->info
) == NULL
)
1711 table
= zebra_vrf_table_with_table_id(afi
,
1719 vty_show_ip_route_summary_prefix(vty
, table
);
1721 vty_show_ip_route_summary(vty
, table
);
1724 vrf_id_t vrf_id
= VRF_DEFAULT
;
1727 VRF_GET_ID(vrf_id
, vrf_name
, false);
1729 table
= zebra_vrf_table_with_table_id(afi
,
1736 vty_show_ip_route_summary_prefix(vty
, table
);
1738 vty_show_ip_route_summary(vty
, table
);
1744 static void vty_show_ip_route_summary(struct vty
*vty
,
1745 struct route_table
*table
)
1747 struct route_node
*rn
;
1748 struct route_entry
*re
;
1749 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1750 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1751 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1752 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1756 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1757 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1758 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1759 RNODE_FOREACH_RE (rn
, re
) {
1760 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1761 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1763 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1765 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1767 rib_cnt
[re
->type
]++;
1769 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1770 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1773 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1775 fib_cnt
[re
->type
]++;
1779 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1780 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1782 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1783 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1784 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1785 if (i
== ZEBRA_ROUTE_BGP
) {
1786 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1787 rib_cnt
[ZEBRA_ROUTE_BGP
],
1788 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1789 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1790 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1791 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1793 vty_out(vty
, "%-20s %-20d %-20d \n",
1794 zebra_route_string(i
), rib_cnt
[i
],
1799 vty_out(vty
, "------\n");
1800 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1801 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1806 * Implementation of the ip route summary prefix command.
1808 * This command prints the primary prefixes that have been installed by various
1809 * protocols on the box.
1812 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1813 struct route_table
*table
)
1815 struct route_node
*rn
;
1816 struct route_entry
*re
;
1817 struct nexthop
*nexthop
;
1818 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1819 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1820 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1821 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1825 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1826 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1827 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1828 RNODE_FOREACH_RE (rn
, re
) {
1831 * In case of ECMP, count only once.
1834 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1835 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1836 fib_cnt
[re
->type
]++;
1838 for (nexthop
= re
->ng
->nexthop
; (!cnt
&& nexthop
);
1839 nexthop
= nexthop
->next
) {
1841 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1842 rib_cnt
[re
->type
]++;
1843 if (re
->type
== ZEBRA_ROUTE_BGP
1844 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1845 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1846 if (CHECK_FLAG(re
->status
,
1847 ROUTE_ENTRY_INSTALLED
))
1848 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1853 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1854 "Prefix Routes", "FIB",
1855 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1857 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1858 if (rib_cnt
[i
] > 0) {
1859 if (i
== ZEBRA_ROUTE_BGP
) {
1860 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1861 rib_cnt
[ZEBRA_ROUTE_BGP
]
1862 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1863 fib_cnt
[ZEBRA_ROUTE_BGP
]
1864 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1865 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1866 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1867 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1869 vty_out(vty
, "%-20s %-20d %-20d \n",
1870 zebra_route_string(i
), rib_cnt
[i
],
1875 vty_out(vty
, "------\n");
1876 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1877 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1882 * Show IPv6 mroute command.Used to dump
1883 * the Multicast routing table.
1885 DEFUN (show_ipv6_mroute
,
1886 show_ipv6_mroute_cmd
,
1887 "show ipv6 mroute [vrf NAME]",
1890 "IPv6 Multicast routing table\n"
1893 struct route_table
*table
;
1894 struct route_node
*rn
;
1895 struct route_entry
*re
;
1897 vrf_id_t vrf_id
= VRF_DEFAULT
;
1900 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1902 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1906 /* Show all IPv6 route. */
1907 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1908 RNODE_FOREACH_RE (rn
, re
) {
1910 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1913 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1918 DEFUN (show_ipv6_mroute_vrf_all
,
1919 show_ipv6_mroute_vrf_all_cmd
,
1920 "show ipv6 mroute vrf all",
1923 "IPv6 Multicast routing table\n"
1924 VRF_ALL_CMD_HELP_STR
)
1926 struct route_table
*table
;
1927 struct route_node
*rn
;
1928 struct route_entry
*re
;
1930 struct zebra_vrf
*zvrf
;
1933 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1934 if ((zvrf
= vrf
->info
) == NULL
1935 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1938 /* Show all IPv6 route. */
1939 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1940 RNODE_FOREACH_RE (rn
, re
) {
1942 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1945 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1951 DEFUN (allow_external_route_update
,
1952 allow_external_route_update_cmd
,
1953 "allow-external-route-update",
1954 "Allow FRR routes to be overwritten by external processes\n")
1961 DEFUN (no_allow_external_route_update
,
1962 no_allow_external_route_update_cmd
,
1963 "no allow-external-route-update",
1965 "Allow FRR routes to be overwritten by external processes\n")
1980 struct zebra_vrf
*zvrf
;
1982 if (vrf_is_backend_netns())
1983 vty_out(vty
, "netns-based vrfs\n");
1985 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1986 if (!(zvrf
= vrf
->info
))
1988 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1991 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1992 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1993 vty_out(vty
, "inactive");
1994 else if (zvrf_ns_name(zvrf
))
1995 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1996 zvrf_ns_name(zvrf
));
1998 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2000 if (vrf_is_user_cfged(vrf
))
2001 vty_out(vty
, " (configured)");
2008 DEFUN (default_vrf_vni_mapping
,
2009 default_vrf_vni_mapping_cmd
,
2010 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2011 "VNI corresponding to the DEFAULT VRF\n"
2013 "Prefix routes only \n")
2016 char err
[ERR_STR_SZ
];
2017 struct zebra_vrf
*zvrf
= NULL
;
2018 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2021 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2028 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2031 vty_out(vty
, "%s\n", err
);
2038 DEFUN (no_default_vrf_vni_mapping
,
2039 no_default_vrf_vni_mapping_cmd
,
2040 "no vni " CMD_VNI_RANGE
,
2042 "VNI corresponding to DEFAULT VRF\n"
2046 char err
[ERR_STR_SZ
];
2047 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2048 struct zebra_vrf
*zvrf
= NULL
;
2050 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2054 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2056 vty_out(vty
, "%s\n", err
);
2063 DEFUN (vrf_vni_mapping
,
2064 vrf_vni_mapping_cmd
,
2065 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2066 "VNI corresponding to tenant VRF\n"
2068 "prefix-routes-only\n")
2073 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2074 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2075 char err
[ERR_STR_SZ
];
2083 /* Mark as having FRR configuration */
2084 vrf_set_user_cfged(vrf
);
2085 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2088 vty_out(vty
, "%s\n", err
);
2095 DEFUN (no_vrf_vni_mapping
,
2096 no_vrf_vni_mapping_cmd
,
2097 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2099 "VNI corresponding to tenant VRF\n"
2101 "prefix-routes-only\n")
2105 char err
[ERR_STR_SZ
];
2106 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2108 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2116 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2117 ERR_STR_SZ
, filter
, 0);
2119 vty_out(vty
, "%s\n", err
);
2123 /* If no other FRR config for this VRF, mark accordingly. */
2124 if (!zebra_vrf_has_config(zvrf
))
2125 vrf_reset_user_cfged(vrf
);
2131 DEFUN (show_vrf_vni
,
2133 "show vrf vni [json]",
2140 struct zebra_vrf
*zvrf
;
2141 json_object
*json
= NULL
;
2142 json_object
*json_vrfs
= NULL
;
2143 bool uj
= use_json(argc
, argv
);
2146 json
= json_object_new_object();
2147 json_vrfs
= json_object_new_array();
2151 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2152 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2154 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2159 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2163 json_object_object_add(json
, "vrfs", json_vrfs
);
2164 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2165 json
, JSON_C_TO_STRING_PRETTY
));
2166 json_object_free(json
);
2172 DEFUN (show_evpn_global
,
2173 show_evpn_global_cmd
,
2179 bool uj
= use_json(argc
, argv
);
2181 zebra_vxlan_print_evpn(vty
, uj
);
2185 DEFUN (show_evpn_vni
,
2187 "show evpn vni [json]",
2190 "VxLAN Network Identifier\n"
2193 struct zebra_vrf
*zvrf
;
2194 bool uj
= use_json(argc
, argv
);
2196 zvrf
= zebra_vrf_get_evpn();
2197 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2201 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2202 "show evpn vni detail [json]",
2205 "VxLAN Network Identifier\n"
2206 "Detailed Information On Each VNI\n"
2209 struct zebra_vrf
*zvrf
;
2210 bool uj
= use_json(argc
, argv
);
2212 zvrf
= zebra_vrf_get_evpn();
2213 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2217 DEFUN (show_evpn_vni_vni
,
2218 show_evpn_vni_vni_cmd
,
2219 "show evpn vni " CMD_VNI_RANGE
"[json]",
2222 "VxLAN Network Identifier\n"
2226 struct zebra_vrf
*zvrf
;
2228 bool uj
= use_json(argc
, argv
);
2230 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2231 zvrf
= zebra_vrf_get_evpn();
2232 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2236 DEFUN (show_evpn_rmac_vni_mac
,
2237 show_evpn_rmac_vni_mac_cmd
,
2238 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2245 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2250 bool uj
= use_json(argc
, argv
);
2252 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2253 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2254 vty_out(vty
, "%% Malformed MAC address\n");
2257 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2261 DEFUN (show_evpn_rmac_vni
,
2262 show_evpn_rmac_vni_cmd
,
2263 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2272 bool uj
= use_json(argc
, argv
);
2274 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2275 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2280 DEFUN (show_evpn_rmac_vni_all
,
2281 show_evpn_rmac_vni_all_cmd
,
2282 "show evpn rmac vni all [json]",
2290 bool uj
= use_json(argc
, argv
);
2292 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2297 DEFUN (show_evpn_nh_vni_ip
,
2298 show_evpn_nh_vni_ip_cmd
,
2299 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2306 "Host address (ipv4 or ipv6)\n"
2311 bool uj
= use_json(argc
, argv
);
2313 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2314 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2316 vty_out(vty
, "%% Malformed Neighbor address\n");
2319 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2324 DEFUN (show_evpn_nh_vni
,
2325 show_evpn_nh_vni_cmd
,
2326 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2335 bool uj
= use_json(argc
, argv
);
2337 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2338 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2343 DEFUN (show_evpn_nh_vni_all
,
2344 show_evpn_nh_vni_all_cmd
,
2345 "show evpn next-hops vni all [json]",
2353 bool uj
= use_json(argc
, argv
);
2355 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2360 DEFUN (show_evpn_mac_vni
,
2361 show_evpn_mac_vni_cmd
,
2362 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2366 "VxLAN Network Identifier\n"
2370 struct zebra_vrf
*zvrf
;
2372 bool uj
= use_json(argc
, argv
);
2374 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2375 zvrf
= zebra_vrf_get_evpn();
2376 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2380 DEFUN (show_evpn_mac_vni_all
,
2381 show_evpn_mac_vni_all_cmd
,
2382 "show evpn mac vni all [json]",
2386 "VxLAN Network Identifier\n"
2390 struct zebra_vrf
*zvrf
;
2391 bool uj
= use_json(argc
, argv
);
2393 zvrf
= zebra_vrf_get_evpn();
2394 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2398 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2399 "show evpn mac vni all detail [json]",
2403 "VxLAN Network Identifier\n"
2405 "Detailed Information On Each VNI MAC\n"
2408 struct zebra_vrf
*zvrf
;
2409 bool uj
= use_json(argc
, argv
);
2411 zvrf
= zebra_vrf_get_evpn();
2412 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2416 DEFUN (show_evpn_mac_vni_all_vtep
,
2417 show_evpn_mac_vni_all_vtep_cmd
,
2418 "show evpn mac vni all vtep A.B.C.D [json]",
2422 "VxLAN Network Identifier\n"
2425 "Remote VTEP IP address\n"
2428 struct zebra_vrf
*zvrf
;
2429 struct in_addr vtep_ip
;
2430 bool uj
= use_json(argc
, argv
);
2432 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2434 vty_out(vty
, "%% Malformed VTEP IP address\n");
2437 zvrf
= zebra_vrf_get_evpn();
2438 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2444 DEFUN (show_evpn_mac_vni_mac
,
2445 show_evpn_mac_vni_mac_cmd
,
2446 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2450 "VxLAN Network Identifier\n"
2453 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2457 struct zebra_vrf
*zvrf
;
2460 bool uj
= use_json(argc
, argv
);
2462 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2463 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2464 vty_out(vty
, "%% Malformed MAC address");
2467 zvrf
= zebra_vrf_get_evpn();
2468 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2472 DEFUN (show_evpn_mac_vni_vtep
,
2473 show_evpn_mac_vni_vtep_cmd
,
2474 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2478 "VxLAN Network Identifier\n"
2481 "Remote VTEP IP address\n"
2484 struct zebra_vrf
*zvrf
;
2486 struct in_addr vtep_ip
;
2487 bool uj
= use_json(argc
, argv
);
2489 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2490 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2492 vty_out(vty
, "%% Malformed VTEP IP address\n");
2496 zvrf
= zebra_vrf_get_evpn();
2497 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2501 DEFPY (show_evpn_mac_vni_all_dad
,
2502 show_evpn_mac_vni_all_dad_cmd
,
2503 "show evpn mac vni all duplicate [json]",
2507 "VxLAN Network Identifier\n"
2509 "Duplicate address list\n"
2512 struct zebra_vrf
*zvrf
;
2513 bool uj
= use_json(argc
, argv
);
2515 zvrf
= zebra_vrf_get_evpn();
2516 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2521 DEFPY (show_evpn_mac_vni_dad
,
2522 show_evpn_mac_vni_dad_cmd
,
2523 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2527 "VxLAN Network Identifier\n"
2529 "Duplicate address list\n"
2532 struct zebra_vrf
*zvrf
;
2533 bool uj
= use_json(argc
, argv
);
2535 zvrf
= zebra_vrf_get_evpn();
2537 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2542 DEFPY (show_evpn_neigh_vni_dad
,
2543 show_evpn_neigh_vni_dad_cmd
,
2544 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2547 "ARP and ND cache\n"
2548 "VxLAN Network Identifier\n"
2550 "Duplicate address list\n"
2553 struct zebra_vrf
*zvrf
;
2554 bool uj
= use_json(argc
, argv
);
2556 zvrf
= zebra_vrf_get_evpn();
2557 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2561 DEFPY (show_evpn_neigh_vni_all_dad
,
2562 show_evpn_neigh_vni_all_dad_cmd
,
2563 "show evpn arp-cache vni all duplicate [json]",
2566 "ARP and ND cache\n"
2567 "VxLAN Network Identifier\n"
2569 "Duplicate address list\n"
2572 struct zebra_vrf
*zvrf
;
2573 bool uj
= use_json(argc
, argv
);
2575 zvrf
= zebra_vrf_get_evpn();
2576 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2581 DEFUN (show_evpn_neigh_vni
,
2582 show_evpn_neigh_vni_cmd
,
2583 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2586 "ARP and ND cache\n"
2587 "VxLAN Network Identifier\n"
2591 struct zebra_vrf
*zvrf
;
2593 bool uj
= use_json(argc
, argv
);
2595 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2596 zvrf
= zebra_vrf_get_evpn();
2597 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2601 DEFUN (show_evpn_neigh_vni_all
,
2602 show_evpn_neigh_vni_all_cmd
,
2603 "show evpn arp-cache vni all [json]",
2606 "ARP and ND cache\n"
2607 "VxLAN Network Identifier\n"
2611 struct zebra_vrf
*zvrf
;
2612 bool uj
= use_json(argc
, argv
);
2614 zvrf
= zebra_vrf_get_evpn();
2615 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2619 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2620 "show evpn arp-cache vni all detail [json]",
2623 "ARP and ND cache\n"
2624 "VxLAN Network Identifier\n"
2626 "Neighbor details for all vnis in detail\n" JSON_STR
)
2628 struct zebra_vrf
*zvrf
;
2629 bool uj
= use_json(argc
, argv
);
2631 zvrf
= zebra_vrf_get_evpn();
2632 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2636 DEFUN (show_evpn_neigh_vni_neigh
,
2637 show_evpn_neigh_vni_neigh_cmd
,
2638 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2641 "ARP and ND cache\n"
2642 "VxLAN Network Identifier\n"
2645 "Neighbor address (IPv4 or IPv6 address)\n"
2648 struct zebra_vrf
*zvrf
;
2651 bool uj
= use_json(argc
, argv
);
2653 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2654 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2656 vty_out(vty
, "%% Malformed Neighbor address\n");
2659 zvrf
= zebra_vrf_get_evpn();
2660 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2664 DEFUN (show_evpn_neigh_vni_vtep
,
2665 show_evpn_neigh_vni_vtep_cmd
,
2666 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2669 "ARP and ND cache\n"
2670 "VxLAN Network Identifier\n"
2673 "Remote VTEP IP address\n"
2676 struct zebra_vrf
*zvrf
;
2678 struct in_addr vtep_ip
;
2679 bool uj
= use_json(argc
, argv
);
2681 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2682 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2684 vty_out(vty
, "%% Malformed VTEP IP address\n");
2688 zvrf
= zebra_vrf_get_evpn();
2689 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2693 /* policy routing contexts */
2694 DEFUN (show_pbr_ipset
,
2696 "show pbr ipset [WORD]",
2698 "Policy-Based Routing\n"
2699 "IPset Context information\n"
2700 "IPset Name information\n")
2704 found
= argv_find(argv
, argc
, "WORD", &idx
);
2706 zebra_pbr_show_ipset_list(vty
, NULL
);
2708 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2712 /* policy routing contexts */
2713 DEFUN (show_pbr_iptable
,
2714 show_pbr_iptable_cmd
,
2715 "show pbr iptable [WORD]",
2717 "Policy-Based Routing\n"
2718 "IPtable Context information\n"
2719 "IPtable Name information\n")
2724 found
= argv_find(argv
, argc
, "WORD", &idx
);
2726 zebra_pbr_show_iptable(vty
, NULL
);
2728 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2732 DEFPY (clear_evpn_dup_addr
,
2733 clear_evpn_dup_addr_cmd
,
2734 "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE
"$vni [mac X:X:X:X:X:X | ip <A.B.C.D|X:X::X:X>]>",
2737 "Duplicate address \n"
2738 "VxLAN Network Identifier\n"
2742 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2747 struct zebra_vrf
*zvrf
;
2748 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2749 int ret
= CMD_SUCCESS
;
2751 zvrf
= zebra_vrf_get_evpn();
2753 if (!is_zero_mac(&mac
->eth_addr
)) {
2754 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2758 if (sockunion_family(ip
) == AF_INET
) {
2759 host_ip
.ipa_type
= IPADDR_V4
;
2760 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2762 host_ip
.ipa_type
= IPADDR_V6
;
2763 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2764 sizeof(struct in6_addr
));
2766 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2770 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2773 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2779 /* Static ip route configuration write function. */
2780 static int zebra_ip_config(struct vty
*vty
)
2784 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2789 DEFUN (ip_zebra_import_table_distance
,
2790 ip_zebra_import_table_distance_cmd
,
2791 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2793 "import routes from non-main kernel table\n"
2794 "kernel routing table id\n"
2795 "Distance for imported routes\n"
2796 "Default distance value\n"
2797 "route-map for filtering\n"
2800 uint32_t table_id
= 0;
2802 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2803 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2805 strmatch(argv
[argc
- 2]->text
, "route-map")
2806 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2810 if (argc
== 7 || (argc
== 5 && !rmap
))
2811 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2813 if (!is_zebra_valid_kernel_table(table_id
)) {
2815 "Invalid routing table ID, %d. Must be in range 1-252\n",
2818 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2822 if (is_zebra_main_routing_table(table_id
)) {
2824 "Invalid routing table ID, %d. Must be non-default table\n",
2827 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2831 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2834 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2839 DEFUN_HIDDEN (zebra_packet_process
,
2840 zebra_packet_process_cmd
,
2841 "zebra zapi-packets (1-10000)",
2844 "Number of packets to process before relinquishing thread\n")
2846 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2848 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2849 memory_order_relaxed
);
2854 DEFUN_HIDDEN (no_zebra_packet_process
,
2855 no_zebra_packet_process_cmd
,
2856 "no zebra zapi-packets [(1-10000)]",
2860 "Number of packets to process before relinquishing thread\n")
2862 atomic_store_explicit(&zrouter
.packets_to_process
,
2863 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2864 memory_order_relaxed
);
2869 DEFUN_HIDDEN (zebra_workqueue_timer
,
2870 zebra_workqueue_timer_cmd
,
2871 "zebra work-queue (0-10000)",
2874 "Time in milliseconds\n")
2876 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2877 zrouter
.ribq
->spec
.hold
= timer
;
2882 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2883 no_zebra_workqueue_timer_cmd
,
2884 "no zebra work-queue [(0-10000)]",
2888 "Time in milliseconds\n")
2890 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2895 DEFUN (no_ip_zebra_import_table
,
2896 no_ip_zebra_import_table_cmd
,
2897 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2900 "import routes from non-main kernel table\n"
2901 "kernel routing table id\n"
2902 "Distance for imported routes\n"
2903 "Default distance value\n"
2904 "route-map for filtering\n"
2907 uint32_t table_id
= 0;
2908 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2910 if (!is_zebra_valid_kernel_table(table_id
)) {
2912 "Invalid routing table ID. Must be in range 1-252\n");
2916 if (is_zebra_main_routing_table(table_id
)) {
2918 "Invalid routing table ID, %d. Must be non-default table\n",
2923 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2926 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2929 static int config_write_protocol(struct vty
*vty
)
2932 vty_out(vty
, "allow-external-route-update\n");
2934 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2935 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2937 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2938 vty_out(vty
, "zebra zapi-packets %u\n",
2939 zrouter
.packets_to_process
);
2941 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2943 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2944 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2945 ipv4_multicast_mode
== MCAST_URIB_ONLY
2947 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2949 : ipv4_multicast_mode
2950 == MCAST_MIX_MRIB_FIRST
2952 : ipv4_multicast_mode
2953 == MCAST_MIX_DISTANCE
2957 /* Include dataplane info */
2958 dplane_config_write_helper(vty
);
2972 " Route Route Neighbor LSP LSP\n");
2974 "VRF Installs Removals Updates Installs Removals\n");
2976 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2977 struct zebra_vrf
*zvrf
= vrf
->info
;
2979 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2980 " %10" PRIu64
" %10" PRIu64
"\n",
2981 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2982 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2983 zvrf
->lsp_removals
);
2989 DEFUN (ip_forwarding
,
2993 "Turn on IP forwarding\n")
2999 ret
= ipforward_on();
3002 vty_out(vty
, "Can't turn on IP forwarding\n");
3003 return CMD_WARNING_CONFIG_FAILED
;
3009 DEFUN (no_ip_forwarding
,
3010 no_ip_forwarding_cmd
,
3014 "Turn off IP forwarding\n")
3020 ret
= ipforward_off();
3023 vty_out(vty
, "Can't turn off IP forwarding\n");
3024 return CMD_WARNING_CONFIG_FAILED
;
3030 /* Only display ip forwarding is enabled or not. */
3031 DEFUN (show_ip_forwarding
,
3032 show_ip_forwarding_cmd
,
3033 "show ip forwarding",
3036 "IP forwarding status\n")
3043 vty_out(vty
, "IP forwarding is off\n");
3045 vty_out(vty
, "IP forwarding is on\n");
3049 /* Only display ipv6 forwarding is enabled or not. */
3050 DEFUN (show_ipv6_forwarding
,
3051 show_ipv6_forwarding_cmd
,
3052 "show ipv6 forwarding",
3054 "IPv6 information\n"
3055 "Forwarding status\n")
3059 ret
= ipforward_ipv6();
3063 vty_out(vty
, "ipv6 forwarding is unknown\n");
3066 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3069 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3072 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3078 DEFUN (ipv6_forwarding
,
3079 ipv6_forwarding_cmd
,
3082 "Turn on IPv6 forwarding\n")
3086 ret
= ipforward_ipv6();
3088 ret
= ipforward_ipv6_on();
3091 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3092 return CMD_WARNING_CONFIG_FAILED
;
3098 DEFUN (no_ipv6_forwarding
,
3099 no_ipv6_forwarding_cmd
,
3100 "no ipv6 forwarding",
3103 "Turn off IPv6 forwarding\n")
3107 ret
= ipforward_ipv6();
3109 ret
= ipforward_ipv6_off();
3112 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3113 return CMD_WARNING_CONFIG_FAILED
;
3119 /* Display dataplane info */
3120 DEFUN (show_dataplane
,
3122 "show zebra dplane [detailed]",
3125 "Zebra dataplane information\n"
3126 "Detailed output\n")
3129 bool detailed
= false;
3131 if (argv_find(argv
, argc
, "detailed", &idx
))
3134 return dplane_show_helper(vty
, detailed
);
3137 /* Display dataplane providers info */
3138 DEFUN (show_dataplane_providers
,
3139 show_dataplane_providers_cmd
,
3140 "show zebra dplane providers [detailed]",
3143 "Zebra dataplane information\n"
3144 "Zebra dataplane provider information\n"
3145 "Detailed output\n")
3148 bool detailed
= false;
3150 if (argv_find(argv
, argc
, "detailed", &idx
))
3153 return dplane_show_provs_helper(vty
, detailed
);
3156 /* Configure dataplane incoming queue limit */
3157 DEFUN (zebra_dplane_queue_limit
,
3158 zebra_dplane_queue_limit_cmd
,
3159 "zebra dplane limit (0-10000)",
3162 "Limit incoming queued updates\n"
3163 "Number of queued updates\n")
3167 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3169 dplane_set_in_queue_limit(limit
, true);
3174 /* Reset dataplane queue limit to default value */
3175 DEFUN (no_zebra_dplane_queue_limit
,
3176 no_zebra_dplane_queue_limit_cmd
,
3177 "no zebra dplane limit [(0-10000)]",
3181 "Limit incoming queued updates\n"
3182 "Number of queued updates\n")
3184 dplane_set_in_queue_limit(0, false);
3189 DEFUN (zebra_show_routing_tables_summary
,
3190 zebra_show_routing_tables_summary_cmd
,
3191 "show zebra router table summary",
3194 "The Zebra Router Information\n"
3195 "Table Information about this Zebra Router\n"
3196 "Summary Information\n")
3198 zebra_router_show_table_summary(vty
);
3203 /* Table configuration write function. */
3204 static int config_write_table(struct vty
*vty
)
3209 /* IPForwarding configuration write function. */
3210 static int config_write_forwarding(struct vty
*vty
)
3212 /* FIXME: Find better place for that. */
3213 router_id_write(vty
);
3216 vty_out(vty
, "no ip forwarding\n");
3217 if (!ipforward_ipv6())
3218 vty_out(vty
, "no ipv6 forwarding\n");
3219 vty_out(vty
, "!\n");
3223 DEFUN_HIDDEN (show_frr
,
3229 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3230 vty_out(vty
, ".............................7777:..............................................\n");
3231 vty_out(vty
, ".............................777777,............................................\n");
3232 vty_out(vty
, "... .........................77777777,..........................................\n");
3233 vty_out(vty
, "............................=7777777777:........................................\n");
3234 vty_out(vty
, "........................:7777777777777777,......................................\n");
3235 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3236 vty_out(vty
, "...................I7777777777+.................................................\n");
3237 vty_out(vty
, "................,777777777?............ .......................................\n");
3238 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3239 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3240 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3241 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3242 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3243 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3244 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3245 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3246 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3247 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3248 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3249 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3250 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3251 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3252 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3253 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3254 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3255 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3256 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3257 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3258 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3259 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3260 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3261 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3262 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3263 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3264 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3265 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3266 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3267 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3268 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3269 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3270 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3271 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3272 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3273 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3274 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3275 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3276 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3277 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3278 vty_out(vty
, "................................~77777777...............=777777.................\n");
3279 vty_out(vty
, ".....................................:=?I................~777777................\n");
3280 vty_out(vty
, "..........................................................:777777,..............\n");
3281 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3286 /* IP node for static routes. */
3287 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3288 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3289 /* table node for routing tables. */
3290 static struct cmd_node table_node
= {TABLE_NODE
,
3291 "", /* This node has no interface. */
3293 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3294 "", /* This node has no interface. */
3298 void zebra_vty_init(void)
3300 /* Install configuration write function. */
3301 install_node(&table_node
, config_write_table
);
3302 install_node(&forwarding_node
, config_write_forwarding
);
3304 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3305 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3306 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3307 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3309 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3310 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3311 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3314 zebra_route_map_init();
3316 install_node(&ip_node
, zebra_ip_config
);
3317 install_node(&protocol_node
, config_write_protocol
);
3319 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3320 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3322 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3323 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3325 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3326 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3327 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3328 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3329 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3330 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3332 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3333 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3335 install_element(VIEW_NODE
, &show_vrf_cmd
);
3336 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3337 install_element(VIEW_NODE
, &show_route_cmd
);
3338 install_element(VIEW_NODE
, &show_route_table_cmd
);
3339 if (vrf_is_backend_netns())
3340 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3341 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3342 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3343 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3344 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3346 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3347 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3349 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3350 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3351 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3352 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3353 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3354 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3355 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3356 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3357 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3359 /* Commands for VRF */
3360 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3362 install_element(VIEW_NODE
, &show_frr_cmd
);
3363 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3364 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3365 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3366 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3367 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3368 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3369 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3370 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3371 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3372 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3373 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3374 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3375 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3376 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3377 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3378 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3379 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3380 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3381 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3382 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3383 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3384 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3385 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3386 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3387 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3388 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3390 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3391 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3393 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3394 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3395 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3396 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3398 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3399 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3400 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3401 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3403 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);