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_UNHASHABLE
))
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_lookup_table_with_table_id(
1712 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, table_id
);
1718 vty_show_ip_route_summary_prefix(vty
, table
);
1720 vty_show_ip_route_summary(vty
, table
);
1723 vrf_id_t vrf_id
= VRF_DEFAULT
;
1726 VRF_GET_ID(vrf_id
, vrf_name
, false);
1728 table
= zebra_vrf_lookup_table_with_table_id(afi
, SAFI_UNICAST
,
1734 vty_show_ip_route_summary_prefix(vty
, table
);
1736 vty_show_ip_route_summary(vty
, table
);
1742 static void vty_show_ip_route_summary(struct vty
*vty
,
1743 struct route_table
*table
)
1745 struct route_node
*rn
;
1746 struct route_entry
*re
;
1747 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1748 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1749 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1750 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1754 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1755 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1756 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1757 RNODE_FOREACH_RE (rn
, re
) {
1758 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1759 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1761 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1763 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1765 rib_cnt
[re
->type
]++;
1767 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1768 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1771 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1773 fib_cnt
[re
->type
]++;
1777 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1778 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1780 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1781 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1782 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1783 if (i
== ZEBRA_ROUTE_BGP
) {
1784 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1785 rib_cnt
[ZEBRA_ROUTE_BGP
],
1786 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1787 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1788 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1789 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1791 vty_out(vty
, "%-20s %-20d %-20d \n",
1792 zebra_route_string(i
), rib_cnt
[i
],
1797 vty_out(vty
, "------\n");
1798 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1799 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1804 * Implementation of the ip route summary prefix command.
1806 * This command prints the primary prefixes that have been installed by various
1807 * protocols on the box.
1810 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1811 struct route_table
*table
)
1813 struct route_node
*rn
;
1814 struct route_entry
*re
;
1815 struct nexthop
*nexthop
;
1816 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1817 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1818 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1819 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1823 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1824 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1825 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1826 RNODE_FOREACH_RE (rn
, re
) {
1829 * In case of ECMP, count only once.
1832 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1833 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1834 fib_cnt
[re
->type
]++;
1836 for (nexthop
= re
->ng
->nexthop
; (!cnt
&& nexthop
);
1837 nexthop
= nexthop
->next
) {
1839 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1840 rib_cnt
[re
->type
]++;
1841 if (re
->type
== ZEBRA_ROUTE_BGP
1842 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1843 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1844 if (CHECK_FLAG(re
->status
,
1845 ROUTE_ENTRY_INSTALLED
))
1846 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1851 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1852 "Prefix Routes", "FIB",
1853 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1855 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1856 if (rib_cnt
[i
] > 0) {
1857 if (i
== ZEBRA_ROUTE_BGP
) {
1858 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1859 rib_cnt
[ZEBRA_ROUTE_BGP
]
1860 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1861 fib_cnt
[ZEBRA_ROUTE_BGP
]
1862 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1863 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1864 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1865 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1867 vty_out(vty
, "%-20s %-20d %-20d \n",
1868 zebra_route_string(i
), rib_cnt
[i
],
1873 vty_out(vty
, "------\n");
1874 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1875 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1880 * Show IPv6 mroute command.Used to dump
1881 * the Multicast routing table.
1883 DEFUN (show_ipv6_mroute
,
1884 show_ipv6_mroute_cmd
,
1885 "show ipv6 mroute [vrf NAME]",
1888 "IPv6 Multicast routing table\n"
1891 struct route_table
*table
;
1892 struct route_node
*rn
;
1893 struct route_entry
*re
;
1895 vrf_id_t vrf_id
= VRF_DEFAULT
;
1898 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1900 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1904 /* Show all IPv6 route. */
1905 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1906 RNODE_FOREACH_RE (rn
, re
) {
1908 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1911 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1916 DEFUN (show_ipv6_mroute_vrf_all
,
1917 show_ipv6_mroute_vrf_all_cmd
,
1918 "show ipv6 mroute vrf all",
1921 "IPv6 Multicast routing table\n"
1922 VRF_ALL_CMD_HELP_STR
)
1924 struct route_table
*table
;
1925 struct route_node
*rn
;
1926 struct route_entry
*re
;
1928 struct zebra_vrf
*zvrf
;
1931 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1932 if ((zvrf
= vrf
->info
) == NULL
1933 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1936 /* Show all IPv6 route. */
1937 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1938 RNODE_FOREACH_RE (rn
, re
) {
1940 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1943 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1949 DEFUN (allow_external_route_update
,
1950 allow_external_route_update_cmd
,
1951 "allow-external-route-update",
1952 "Allow FRR routes to be overwritten by external processes\n")
1959 DEFUN (no_allow_external_route_update
,
1960 no_allow_external_route_update_cmd
,
1961 "no allow-external-route-update",
1963 "Allow FRR routes to be overwritten by external processes\n")
1978 struct zebra_vrf
*zvrf
;
1980 if (vrf_is_backend_netns())
1981 vty_out(vty
, "netns-based vrfs\n");
1983 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1984 if (!(zvrf
= vrf
->info
))
1986 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1989 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1990 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1991 vty_out(vty
, "inactive");
1992 else if (zvrf_ns_name(zvrf
))
1993 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1994 zvrf_ns_name(zvrf
));
1996 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1998 if (vrf_is_user_cfged(vrf
))
1999 vty_out(vty
, " (configured)");
2006 DEFUN (default_vrf_vni_mapping
,
2007 default_vrf_vni_mapping_cmd
,
2008 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2009 "VNI corresponding to the DEFAULT VRF\n"
2011 "Prefix routes only \n")
2014 char err
[ERR_STR_SZ
];
2015 struct zebra_vrf
*zvrf
= NULL
;
2016 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2019 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2026 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2029 vty_out(vty
, "%s\n", err
);
2036 DEFUN (no_default_vrf_vni_mapping
,
2037 no_default_vrf_vni_mapping_cmd
,
2038 "no vni " CMD_VNI_RANGE
,
2040 "VNI corresponding to DEFAULT VRF\n"
2044 char err
[ERR_STR_SZ
];
2045 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2046 struct zebra_vrf
*zvrf
= NULL
;
2048 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2052 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2054 vty_out(vty
, "%s\n", err
);
2061 DEFUN (vrf_vni_mapping
,
2062 vrf_vni_mapping_cmd
,
2063 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2064 "VNI corresponding to tenant VRF\n"
2066 "prefix-routes-only\n")
2071 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2072 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2073 char err
[ERR_STR_SZ
];
2081 /* Mark as having FRR configuration */
2082 vrf_set_user_cfged(vrf
);
2083 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2086 vty_out(vty
, "%s\n", err
);
2093 DEFUN (no_vrf_vni_mapping
,
2094 no_vrf_vni_mapping_cmd
,
2095 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2097 "VNI corresponding to tenant VRF\n"
2099 "prefix-routes-only\n")
2103 char err
[ERR_STR_SZ
];
2104 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2106 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2114 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2115 ERR_STR_SZ
, filter
, 0);
2117 vty_out(vty
, "%s\n", err
);
2121 /* If no other FRR config for this VRF, mark accordingly. */
2122 if (!zebra_vrf_has_config(zvrf
))
2123 vrf_reset_user_cfged(vrf
);
2129 DEFUN (show_vrf_vni
,
2131 "show vrf vni [json]",
2138 struct zebra_vrf
*zvrf
;
2139 json_object
*json
= NULL
;
2140 json_object
*json_vrfs
= NULL
;
2141 bool uj
= use_json(argc
, argv
);
2144 json
= json_object_new_object();
2145 json_vrfs
= json_object_new_array();
2149 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2150 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2152 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2157 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2161 json_object_object_add(json
, "vrfs", json_vrfs
);
2162 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2163 json
, JSON_C_TO_STRING_PRETTY
));
2164 json_object_free(json
);
2170 DEFUN (show_evpn_global
,
2171 show_evpn_global_cmd
,
2177 bool uj
= use_json(argc
, argv
);
2179 zebra_vxlan_print_evpn(vty
, uj
);
2183 DEFUN (show_evpn_vni
,
2185 "show evpn vni [json]",
2188 "VxLAN Network Identifier\n"
2191 struct zebra_vrf
*zvrf
;
2192 bool uj
= use_json(argc
, argv
);
2194 zvrf
= zebra_vrf_get_evpn();
2195 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2199 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2200 "show evpn vni detail [json]",
2203 "VxLAN Network Identifier\n"
2204 "Detailed Information On Each VNI\n"
2207 struct zebra_vrf
*zvrf
;
2208 bool uj
= use_json(argc
, argv
);
2210 zvrf
= zebra_vrf_get_evpn();
2211 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2215 DEFUN (show_evpn_vni_vni
,
2216 show_evpn_vni_vni_cmd
,
2217 "show evpn vni " CMD_VNI_RANGE
"[json]",
2220 "VxLAN Network Identifier\n"
2224 struct zebra_vrf
*zvrf
;
2226 bool uj
= use_json(argc
, argv
);
2228 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2229 zvrf
= zebra_vrf_get_evpn();
2230 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2234 DEFUN (show_evpn_rmac_vni_mac
,
2235 show_evpn_rmac_vni_mac_cmd
,
2236 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2243 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2248 bool uj
= use_json(argc
, argv
);
2250 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2251 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2252 vty_out(vty
, "%% Malformed MAC address\n");
2255 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2259 DEFUN (show_evpn_rmac_vni
,
2260 show_evpn_rmac_vni_cmd
,
2261 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2270 bool uj
= use_json(argc
, argv
);
2272 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2273 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2278 DEFUN (show_evpn_rmac_vni_all
,
2279 show_evpn_rmac_vni_all_cmd
,
2280 "show evpn rmac vni all [json]",
2288 bool uj
= use_json(argc
, argv
);
2290 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2295 DEFUN (show_evpn_nh_vni_ip
,
2296 show_evpn_nh_vni_ip_cmd
,
2297 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2304 "Host address (ipv4 or ipv6)\n"
2309 bool uj
= use_json(argc
, argv
);
2311 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2312 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2314 vty_out(vty
, "%% Malformed Neighbor address\n");
2317 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2322 DEFUN (show_evpn_nh_vni
,
2323 show_evpn_nh_vni_cmd
,
2324 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2333 bool uj
= use_json(argc
, argv
);
2335 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2336 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2341 DEFUN (show_evpn_nh_vni_all
,
2342 show_evpn_nh_vni_all_cmd
,
2343 "show evpn next-hops vni all [json]",
2351 bool uj
= use_json(argc
, argv
);
2353 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2358 DEFUN (show_evpn_mac_vni
,
2359 show_evpn_mac_vni_cmd
,
2360 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2364 "VxLAN Network Identifier\n"
2368 struct zebra_vrf
*zvrf
;
2370 bool uj
= use_json(argc
, argv
);
2372 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2373 zvrf
= zebra_vrf_get_evpn();
2374 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2378 DEFUN (show_evpn_mac_vni_all
,
2379 show_evpn_mac_vni_all_cmd
,
2380 "show evpn mac vni all [json]",
2384 "VxLAN Network Identifier\n"
2388 struct zebra_vrf
*zvrf
;
2389 bool uj
= use_json(argc
, argv
);
2391 zvrf
= zebra_vrf_get_evpn();
2392 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2396 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2397 "show evpn mac vni all detail [json]",
2401 "VxLAN Network Identifier\n"
2403 "Detailed Information On Each VNI MAC\n"
2406 struct zebra_vrf
*zvrf
;
2407 bool uj
= use_json(argc
, argv
);
2409 zvrf
= zebra_vrf_get_evpn();
2410 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2414 DEFUN (show_evpn_mac_vni_all_vtep
,
2415 show_evpn_mac_vni_all_vtep_cmd
,
2416 "show evpn mac vni all vtep A.B.C.D [json]",
2420 "VxLAN Network Identifier\n"
2423 "Remote VTEP IP address\n"
2426 struct zebra_vrf
*zvrf
;
2427 struct in_addr vtep_ip
;
2428 bool uj
= use_json(argc
, argv
);
2430 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2432 vty_out(vty
, "%% Malformed VTEP IP address\n");
2435 zvrf
= zebra_vrf_get_evpn();
2436 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2442 DEFUN (show_evpn_mac_vni_mac
,
2443 show_evpn_mac_vni_mac_cmd
,
2444 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2448 "VxLAN Network Identifier\n"
2451 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2455 struct zebra_vrf
*zvrf
;
2458 bool uj
= use_json(argc
, argv
);
2460 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2461 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2462 vty_out(vty
, "%% Malformed MAC address");
2465 zvrf
= zebra_vrf_get_evpn();
2466 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2470 DEFUN (show_evpn_mac_vni_vtep
,
2471 show_evpn_mac_vni_vtep_cmd
,
2472 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2476 "VxLAN Network Identifier\n"
2479 "Remote VTEP IP address\n"
2482 struct zebra_vrf
*zvrf
;
2484 struct in_addr vtep_ip
;
2485 bool uj
= use_json(argc
, argv
);
2487 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2488 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2490 vty_out(vty
, "%% Malformed VTEP IP address\n");
2494 zvrf
= zebra_vrf_get_evpn();
2495 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2499 DEFPY (show_evpn_mac_vni_all_dad
,
2500 show_evpn_mac_vni_all_dad_cmd
,
2501 "show evpn mac vni all duplicate [json]",
2505 "VxLAN Network Identifier\n"
2507 "Duplicate address list\n"
2510 struct zebra_vrf
*zvrf
;
2511 bool uj
= use_json(argc
, argv
);
2513 zvrf
= zebra_vrf_get_evpn();
2514 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2519 DEFPY (show_evpn_mac_vni_dad
,
2520 show_evpn_mac_vni_dad_cmd
,
2521 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2525 "VxLAN Network Identifier\n"
2527 "Duplicate address list\n"
2530 struct zebra_vrf
*zvrf
;
2531 bool uj
= use_json(argc
, argv
);
2533 zvrf
= zebra_vrf_get_evpn();
2535 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2540 DEFPY (show_evpn_neigh_vni_dad
,
2541 show_evpn_neigh_vni_dad_cmd
,
2542 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2545 "ARP and ND cache\n"
2546 "VxLAN Network Identifier\n"
2548 "Duplicate address list\n"
2551 struct zebra_vrf
*zvrf
;
2552 bool uj
= use_json(argc
, argv
);
2554 zvrf
= zebra_vrf_get_evpn();
2555 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2559 DEFPY (show_evpn_neigh_vni_all_dad
,
2560 show_evpn_neigh_vni_all_dad_cmd
,
2561 "show evpn arp-cache vni all duplicate [json]",
2564 "ARP and ND cache\n"
2565 "VxLAN Network Identifier\n"
2567 "Duplicate address list\n"
2570 struct zebra_vrf
*zvrf
;
2571 bool uj
= use_json(argc
, argv
);
2573 zvrf
= zebra_vrf_get_evpn();
2574 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2579 DEFUN (show_evpn_neigh_vni
,
2580 show_evpn_neigh_vni_cmd
,
2581 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2584 "ARP and ND cache\n"
2585 "VxLAN Network Identifier\n"
2589 struct zebra_vrf
*zvrf
;
2591 bool uj
= use_json(argc
, argv
);
2593 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2594 zvrf
= zebra_vrf_get_evpn();
2595 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2599 DEFUN (show_evpn_neigh_vni_all
,
2600 show_evpn_neigh_vni_all_cmd
,
2601 "show evpn arp-cache vni all [json]",
2604 "ARP and ND cache\n"
2605 "VxLAN Network Identifier\n"
2609 struct zebra_vrf
*zvrf
;
2610 bool uj
= use_json(argc
, argv
);
2612 zvrf
= zebra_vrf_get_evpn();
2613 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2617 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2618 "show evpn arp-cache vni all detail [json]",
2621 "ARP and ND cache\n"
2622 "VxLAN Network Identifier\n"
2624 "Neighbor details for all vnis in detail\n" JSON_STR
)
2626 struct zebra_vrf
*zvrf
;
2627 bool uj
= use_json(argc
, argv
);
2629 zvrf
= zebra_vrf_get_evpn();
2630 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2634 DEFUN (show_evpn_neigh_vni_neigh
,
2635 show_evpn_neigh_vni_neigh_cmd
,
2636 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2639 "ARP and ND cache\n"
2640 "VxLAN Network Identifier\n"
2643 "Neighbor address (IPv4 or IPv6 address)\n"
2646 struct zebra_vrf
*zvrf
;
2649 bool uj
= use_json(argc
, argv
);
2651 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2652 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2654 vty_out(vty
, "%% Malformed Neighbor address\n");
2657 zvrf
= zebra_vrf_get_evpn();
2658 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2662 DEFUN (show_evpn_neigh_vni_vtep
,
2663 show_evpn_neigh_vni_vtep_cmd
,
2664 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2667 "ARP and ND cache\n"
2668 "VxLAN Network Identifier\n"
2671 "Remote VTEP IP address\n"
2674 struct zebra_vrf
*zvrf
;
2676 struct in_addr vtep_ip
;
2677 bool uj
= use_json(argc
, argv
);
2679 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2680 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2682 vty_out(vty
, "%% Malformed VTEP IP address\n");
2686 zvrf
= zebra_vrf_get_evpn();
2687 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2691 /* policy routing contexts */
2692 DEFUN (show_pbr_ipset
,
2694 "show pbr ipset [WORD]",
2696 "Policy-Based Routing\n"
2697 "IPset Context information\n"
2698 "IPset Name information\n")
2702 found
= argv_find(argv
, argc
, "WORD", &idx
);
2704 zebra_pbr_show_ipset_list(vty
, NULL
);
2706 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2710 /* policy routing contexts */
2711 DEFUN (show_pbr_iptable
,
2712 show_pbr_iptable_cmd
,
2713 "show pbr iptable [WORD]",
2715 "Policy-Based Routing\n"
2716 "IPtable Context information\n"
2717 "IPtable Name information\n")
2722 found
= argv_find(argv
, argc
, "WORD", &idx
);
2724 zebra_pbr_show_iptable(vty
, NULL
);
2726 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2730 DEFPY (clear_evpn_dup_addr
,
2731 clear_evpn_dup_addr_cmd
,
2732 "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE
"$vni [mac X:X:X:X:X:X | ip <A.B.C.D|X:X::X:X>]>",
2735 "Duplicate address \n"
2736 "VxLAN Network Identifier\n"
2740 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2745 struct zebra_vrf
*zvrf
;
2746 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2747 int ret
= CMD_SUCCESS
;
2749 zvrf
= zebra_vrf_get_evpn();
2751 if (!is_zero_mac(&mac
->eth_addr
)) {
2752 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2756 if (sockunion_family(ip
) == AF_INET
) {
2757 host_ip
.ipa_type
= IPADDR_V4
;
2758 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2760 host_ip
.ipa_type
= IPADDR_V6
;
2761 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2762 sizeof(struct in6_addr
));
2764 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2768 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2771 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2777 /* Static ip route configuration write function. */
2778 static int zebra_ip_config(struct vty
*vty
)
2782 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2787 DEFUN (ip_zebra_import_table_distance
,
2788 ip_zebra_import_table_distance_cmd
,
2789 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2791 "import routes from non-main kernel table\n"
2792 "kernel routing table id\n"
2793 "Distance for imported routes\n"
2794 "Default distance value\n"
2795 "route-map for filtering\n"
2798 uint32_t table_id
= 0;
2800 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2801 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2803 strmatch(argv
[argc
- 2]->text
, "route-map")
2804 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2808 if (argc
== 7 || (argc
== 5 && !rmap
))
2809 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2811 if (!is_zebra_valid_kernel_table(table_id
)) {
2813 "Invalid routing table ID, %d. Must be in range 1-252\n",
2816 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2820 if (is_zebra_main_routing_table(table_id
)) {
2822 "Invalid routing table ID, %d. Must be non-default table\n",
2825 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2829 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2832 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2837 DEFUN_HIDDEN (zebra_packet_process
,
2838 zebra_packet_process_cmd
,
2839 "zebra zapi-packets (1-10000)",
2842 "Number of packets to process before relinquishing thread\n")
2844 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2846 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2847 memory_order_relaxed
);
2852 DEFUN_HIDDEN (no_zebra_packet_process
,
2853 no_zebra_packet_process_cmd
,
2854 "no zebra zapi-packets [(1-10000)]",
2858 "Number of packets to process before relinquishing thread\n")
2860 atomic_store_explicit(&zrouter
.packets_to_process
,
2861 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2862 memory_order_relaxed
);
2867 DEFUN_HIDDEN (zebra_workqueue_timer
,
2868 zebra_workqueue_timer_cmd
,
2869 "zebra work-queue (0-10000)",
2872 "Time in milliseconds\n")
2874 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2875 zrouter
.ribq
->spec
.hold
= timer
;
2880 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2881 no_zebra_workqueue_timer_cmd
,
2882 "no zebra work-queue [(0-10000)]",
2886 "Time in milliseconds\n")
2888 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2893 DEFUN (no_ip_zebra_import_table
,
2894 no_ip_zebra_import_table_cmd
,
2895 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2898 "import routes from non-main kernel table\n"
2899 "kernel routing table id\n"
2900 "Distance for imported routes\n"
2901 "Default distance value\n"
2902 "route-map for filtering\n"
2905 uint32_t table_id
= 0;
2906 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2908 if (!is_zebra_valid_kernel_table(table_id
)) {
2910 "Invalid routing table ID. Must be in range 1-252\n");
2914 if (is_zebra_main_routing_table(table_id
)) {
2916 "Invalid routing table ID, %d. Must be non-default table\n",
2921 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2924 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2927 static int config_write_protocol(struct vty
*vty
)
2930 vty_out(vty
, "allow-external-route-update\n");
2932 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2933 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2935 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2936 vty_out(vty
, "zebra zapi-packets %u\n",
2937 zrouter
.packets_to_process
);
2939 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2941 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2942 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2943 ipv4_multicast_mode
== MCAST_URIB_ONLY
2945 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2947 : ipv4_multicast_mode
2948 == MCAST_MIX_MRIB_FIRST
2950 : ipv4_multicast_mode
2951 == MCAST_MIX_DISTANCE
2955 /* Include dataplane info */
2956 dplane_config_write_helper(vty
);
2970 " Route Route Neighbor LSP LSP\n");
2972 "VRF Installs Removals Updates Installs Removals\n");
2974 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2975 struct zebra_vrf
*zvrf
= vrf
->info
;
2977 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2978 " %10" PRIu64
" %10" PRIu64
"\n",
2979 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2980 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2981 zvrf
->lsp_removals
);
2987 DEFUN (ip_forwarding
,
2991 "Turn on IP forwarding\n")
2997 ret
= ipforward_on();
3000 vty_out(vty
, "Can't turn on IP forwarding\n");
3001 return CMD_WARNING_CONFIG_FAILED
;
3007 DEFUN (no_ip_forwarding
,
3008 no_ip_forwarding_cmd
,
3012 "Turn off IP forwarding\n")
3018 ret
= ipforward_off();
3021 vty_out(vty
, "Can't turn off IP forwarding\n");
3022 return CMD_WARNING_CONFIG_FAILED
;
3028 /* Only display ip forwarding is enabled or not. */
3029 DEFUN (show_ip_forwarding
,
3030 show_ip_forwarding_cmd
,
3031 "show ip forwarding",
3034 "IP forwarding status\n")
3041 vty_out(vty
, "IP forwarding is off\n");
3043 vty_out(vty
, "IP forwarding is on\n");
3047 /* Only display ipv6 forwarding is enabled or not. */
3048 DEFUN (show_ipv6_forwarding
,
3049 show_ipv6_forwarding_cmd
,
3050 "show ipv6 forwarding",
3052 "IPv6 information\n"
3053 "Forwarding status\n")
3057 ret
= ipforward_ipv6();
3061 vty_out(vty
, "ipv6 forwarding is unknown\n");
3064 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3067 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3070 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3076 DEFUN (ipv6_forwarding
,
3077 ipv6_forwarding_cmd
,
3080 "Turn on IPv6 forwarding\n")
3084 ret
= ipforward_ipv6();
3086 ret
= ipforward_ipv6_on();
3089 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3090 return CMD_WARNING_CONFIG_FAILED
;
3096 DEFUN (no_ipv6_forwarding
,
3097 no_ipv6_forwarding_cmd
,
3098 "no ipv6 forwarding",
3101 "Turn off IPv6 forwarding\n")
3105 ret
= ipforward_ipv6();
3107 ret
= ipforward_ipv6_off();
3110 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3111 return CMD_WARNING_CONFIG_FAILED
;
3117 /* Display dataplane info */
3118 DEFUN (show_dataplane
,
3120 "show zebra dplane [detailed]",
3123 "Zebra dataplane information\n"
3124 "Detailed output\n")
3127 bool detailed
= false;
3129 if (argv_find(argv
, argc
, "detailed", &idx
))
3132 return dplane_show_helper(vty
, detailed
);
3135 /* Display dataplane providers info */
3136 DEFUN (show_dataplane_providers
,
3137 show_dataplane_providers_cmd
,
3138 "show zebra dplane providers [detailed]",
3141 "Zebra dataplane information\n"
3142 "Zebra dataplane provider information\n"
3143 "Detailed output\n")
3146 bool detailed
= false;
3148 if (argv_find(argv
, argc
, "detailed", &idx
))
3151 return dplane_show_provs_helper(vty
, detailed
);
3154 /* Configure dataplane incoming queue limit */
3155 DEFUN (zebra_dplane_queue_limit
,
3156 zebra_dplane_queue_limit_cmd
,
3157 "zebra dplane limit (0-10000)",
3160 "Limit incoming queued updates\n"
3161 "Number of queued updates\n")
3165 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3167 dplane_set_in_queue_limit(limit
, true);
3172 /* Reset dataplane queue limit to default value */
3173 DEFUN (no_zebra_dplane_queue_limit
,
3174 no_zebra_dplane_queue_limit_cmd
,
3175 "no zebra dplane limit [(0-10000)]",
3179 "Limit incoming queued updates\n"
3180 "Number of queued updates\n")
3182 dplane_set_in_queue_limit(0, false);
3187 DEFUN (zebra_show_routing_tables_summary
,
3188 zebra_show_routing_tables_summary_cmd
,
3189 "show zebra router table summary",
3192 "The Zebra Router Information\n"
3193 "Table Information about this Zebra Router\n"
3194 "Summary Information\n")
3196 zebra_router_show_table_summary(vty
);
3201 /* Table configuration write function. */
3202 static int config_write_table(struct vty
*vty
)
3207 /* IPForwarding configuration write function. */
3208 static int config_write_forwarding(struct vty
*vty
)
3210 /* FIXME: Find better place for that. */
3211 router_id_write(vty
);
3214 vty_out(vty
, "no ip forwarding\n");
3215 if (!ipforward_ipv6())
3216 vty_out(vty
, "no ipv6 forwarding\n");
3217 vty_out(vty
, "!\n");
3221 DEFUN_HIDDEN (show_frr
,
3227 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3228 vty_out(vty
, ".............................7777:..............................................\n");
3229 vty_out(vty
, ".............................777777,............................................\n");
3230 vty_out(vty
, "... .........................77777777,..........................................\n");
3231 vty_out(vty
, "............................=7777777777:........................................\n");
3232 vty_out(vty
, "........................:7777777777777777,......................................\n");
3233 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3234 vty_out(vty
, "...................I7777777777+.................................................\n");
3235 vty_out(vty
, "................,777777777?............ .......................................\n");
3236 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3237 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3238 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3239 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3240 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3241 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3242 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3243 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3244 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3245 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3246 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3247 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3248 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3249 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3250 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3251 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3252 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3253 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3254 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3255 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3256 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3257 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3258 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3259 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3260 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3261 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3262 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3263 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3264 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3265 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3266 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3267 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3268 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3269 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3270 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3271 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3272 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3273 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3274 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3275 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3276 vty_out(vty
, "................................~77777777...............=777777.................\n");
3277 vty_out(vty
, ".....................................:=?I................~777777................\n");
3278 vty_out(vty
, "..........................................................:777777,..............\n");
3279 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3284 /* IP node for static routes. */
3285 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3286 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3287 /* table node for routing tables. */
3288 static struct cmd_node table_node
= {TABLE_NODE
,
3289 "", /* This node has no interface. */
3291 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3292 "", /* This node has no interface. */
3296 void zebra_vty_init(void)
3298 /* Install configuration write function. */
3299 install_node(&table_node
, config_write_table
);
3300 install_node(&forwarding_node
, config_write_forwarding
);
3302 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3303 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3304 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3305 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3307 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3308 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3309 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3312 zebra_route_map_init();
3314 install_node(&ip_node
, zebra_ip_config
);
3315 install_node(&protocol_node
, config_write_protocol
);
3317 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3318 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3320 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3321 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3323 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3324 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3325 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3326 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3327 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3328 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3330 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3331 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3333 install_element(VIEW_NODE
, &show_vrf_cmd
);
3334 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3335 install_element(VIEW_NODE
, &show_route_cmd
);
3336 install_element(VIEW_NODE
, &show_route_table_cmd
);
3337 if (vrf_is_backend_netns())
3338 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3339 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3340 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3341 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3342 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3344 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3345 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3347 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3348 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3349 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3350 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3351 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3352 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3353 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3354 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3355 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3357 /* Commands for VRF */
3358 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3360 install_element(VIEW_NODE
, &show_frr_cmd
);
3361 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3362 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3363 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3364 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3365 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3366 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3367 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3368 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3369 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3370 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3371 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3372 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3373 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3374 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3375 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3376 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3377 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3378 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3379 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3380 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3381 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3382 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3383 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3384 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3385 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3386 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3388 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3389 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3391 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3392 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3393 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3394 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3396 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3397 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3398 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3399 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3401 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);