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
->nhe
->nhg
, 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
->nhe
->nhg
));
470 json_object_int_add(json_route
, "internalNextHopActiveNum",
471 nexthop_group_active_nexthop_num(
473 if (uptime
< ONE_DAY_SECOND
)
474 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
476 else if (uptime
< ONE_WEEK_SECOND
)
477 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
480 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
481 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
484 json_object_string_add(json_route
, "uptime", buf
);
486 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
487 json_nexthop
= json_object_new_object();
489 json_object_int_add(json_nexthop
, "flags",
492 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
493 json_object_boolean_true_add(json_nexthop
,
496 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
497 json_object_boolean_true_add(json_nexthop
,
500 switch (nexthop
->type
) {
501 case NEXTHOP_TYPE_IPV4
:
502 case NEXTHOP_TYPE_IPV4_IFINDEX
:
503 json_object_string_add(
505 inet_ntoa(nexthop
->gate
.ipv4
));
506 json_object_string_add(json_nexthop
, "afi",
509 if (nexthop
->ifindex
) {
510 json_object_int_add(json_nexthop
,
513 json_object_string_add(
514 json_nexthop
, "interfaceName",
520 case NEXTHOP_TYPE_IPV6
:
521 case NEXTHOP_TYPE_IPV6_IFINDEX
:
522 json_object_string_add(
524 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
526 json_object_string_add(json_nexthop
, "afi",
529 if (nexthop
->ifindex
) {
530 json_object_int_add(json_nexthop
,
533 json_object_string_add(
534 json_nexthop
, "interfaceName",
541 case NEXTHOP_TYPE_IFINDEX
:
542 json_object_boolean_true_add(
543 json_nexthop
, "directlyConnected");
544 json_object_int_add(json_nexthop
,
547 json_object_string_add(
548 json_nexthop
, "interfaceName",
549 ifindex2ifname(nexthop
->ifindex
,
552 case NEXTHOP_TYPE_BLACKHOLE
:
553 json_object_boolean_true_add(json_nexthop
,
555 switch (nexthop
->bh_type
) {
556 case BLACKHOLE_REJECT
:
557 json_object_boolean_true_add(
558 json_nexthop
, "reject");
560 case BLACKHOLE_ADMINPROHIB
:
561 json_object_boolean_true_add(
566 json_object_boolean_true_add(
567 json_nexthop
, "blackhole");
569 case BLACKHOLE_UNSPEC
:
577 if ((nexthop
->vrf_id
!= re
->vrf_id
)
578 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
579 vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
580 json_object_string_add(json_nexthop
, "vrf",
583 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
584 json_object_boolean_true_add(json_nexthop
,
587 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
588 json_object_boolean_true_add(json_nexthop
,
591 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
592 json_object_boolean_true_add(json_nexthop
,
595 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
596 json_object_boolean_true_add(json_nexthop
,
599 switch (nexthop
->type
) {
600 case NEXTHOP_TYPE_IPV4
:
601 case NEXTHOP_TYPE_IPV4_IFINDEX
:
602 if (nexthop
->src
.ipv4
.s_addr
) {
603 if (inet_ntop(AF_INET
,
604 &nexthop
->src
.ipv4
, buf
,
606 json_object_string_add(
607 json_nexthop
, "source",
611 case NEXTHOP_TYPE_IPV6
:
612 case NEXTHOP_TYPE_IPV6_IFINDEX
:
613 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
615 if (inet_ntop(AF_INET6
,
616 &nexthop
->src
.ipv6
, buf
,
618 json_object_string_add(
619 json_nexthop
, "source",
627 if (nexthop
->nh_label
628 && nexthop
->nh_label
->num_labels
) {
629 json_labels
= json_object_new_array();
631 for (int label_index
= 0;
633 < nexthop
->nh_label
->num_labels
;
635 json_object_array_add(
638 nexthop
->nh_label
->label
641 json_object_object_add(json_nexthop
, "labels",
645 json_object_array_add(json_nexthops
, json_nexthop
);
648 json_object_object_add(json_route
, "nexthops", json_nexthops
);
649 json_object_array_add(json
, json_route
);
653 /* Nexthop information. */
654 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
655 if (nexthop
== nhg
->nexthop
) {
656 /* Prefix information. */
657 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
659 len
+= vty_out(vty
, "[%d]", re
->instance
);
662 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
665 re_status_output_char(re
, nexthop
),
666 srcdest_rnode2str(rn
, buf
, sizeof buf
));
668 /* Distance and metric display. */
669 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
670 (re
->distance
|| re
->metric
)) ||
671 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
672 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
675 vty_out(vty
, " %c%*c",
676 re_status_output_char(re
, nexthop
),
677 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
680 switch (nexthop
->type
) {
681 case NEXTHOP_TYPE_IPV4
:
682 case NEXTHOP_TYPE_IPV4_IFINDEX
:
683 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
684 if (nexthop
->ifindex
)
686 ifindex2ifname(nexthop
->ifindex
,
689 case NEXTHOP_TYPE_IPV6
:
690 case NEXTHOP_TYPE_IPV6_IFINDEX
:
691 vty_out(vty
, " via %s",
692 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
694 if (nexthop
->ifindex
)
696 ifindex2ifname(nexthop
->ifindex
,
700 case NEXTHOP_TYPE_IFINDEX
:
701 vty_out(vty
, " is directly connected, %s",
702 ifindex2ifname(nexthop
->ifindex
,
705 case NEXTHOP_TYPE_BLACKHOLE
:
706 vty_out(vty
, " unreachable");
707 switch (nexthop
->bh_type
) {
708 case BLACKHOLE_REJECT
:
709 vty_out(vty
, " (ICMP unreachable)");
711 case BLACKHOLE_ADMINPROHIB
:
712 vty_out(vty
, " (ICMP admin-prohibited)");
715 vty_out(vty
, " (blackhole)");
717 case BLACKHOLE_UNSPEC
:
725 if ((nexthop
->vrf_id
!= re
->vrf_id
)
726 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
727 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
730 vty_out(vty
, "(vrf %s)", vrf
->name
);
732 vty_out(vty
, "(vrf UNKNOWN)");
735 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
736 vty_out(vty
, " inactive");
738 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
739 vty_out(vty
, " onlink");
741 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
742 vty_out(vty
, " (recursive)");
744 switch (nexthop
->type
) {
745 case NEXTHOP_TYPE_IPV4
:
746 case NEXTHOP_TYPE_IPV4_IFINDEX
:
747 if (nexthop
->src
.ipv4
.s_addr
) {
748 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
750 vty_out(vty
, ", src %s", buf
);
753 case NEXTHOP_TYPE_IPV6
:
754 case NEXTHOP_TYPE_IPV6_IFINDEX
:
755 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
756 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
758 vty_out(vty
, ", src %s", buf
);
765 /* Label information */
766 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
767 vty_out(vty
, ", label %s",
768 mpls_label2str(nexthop
->nh_label
->num_labels
,
769 nexthop
->nh_label
->label
, buf
,
773 if (uptime
< ONE_DAY_SECOND
)
774 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
775 tm
->tm_min
, tm
->tm_sec
);
776 else if (uptime
< ONE_WEEK_SECOND
)
777 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
778 tm
->tm_hour
, tm
->tm_min
);
780 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
781 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
787 static void vty_show_ip_route_detail_json(struct vty
*vty
,
788 struct route_node
*rn
, bool use_fib
)
790 json_object
*json
= NULL
;
791 json_object
*json_prefix
= NULL
;
792 struct route_entry
*re
;
796 dest
= rib_dest_from_rnode(rn
);
798 json
= json_object_new_object();
799 json_prefix
= json_object_new_array();
801 RNODE_FOREACH_RE (rn
, re
) {
803 * If re not selected for forwarding, skip re
804 * for "show ip/ipv6 fib <prefix> json"
806 if (use_fib
&& re
!= dest
->selected_fib
)
808 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
811 prefix2str(&rn
->p
, buf
, sizeof(buf
));
812 json_object_object_add(json
, buf
, json_prefix
);
813 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
814 json
, JSON_C_TO_STRING_PRETTY
));
815 json_object_free(json
);
818 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
819 struct route_table
*table
, afi_t afi
,
820 bool use_fib
, route_tag_t tag
,
821 const struct prefix
*longer_prefix_p
,
822 bool supernets_only
, int type
,
823 unsigned short ospf_instance_id
, bool use_json
,
826 struct route_node
*rn
;
827 struct route_entry
*re
;
830 json_object
*json
= NULL
;
831 json_object
*json_prefix
= NULL
;
836 json
= json_object_new_object();
838 /* Show all routes. */
839 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
840 dest
= rib_dest_from_rnode(rn
);
842 RNODE_FOREACH_RE (rn
, re
) {
843 if (use_fib
&& re
!= dest
->selected_fib
)
846 if (tag
&& re
->tag
!= tag
)
850 && !prefix_match(longer_prefix_p
, &rn
->p
))
853 /* This can only be true when the afi is IPv4 */
854 if (supernets_only
) {
855 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
857 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
860 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
863 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
867 if (type
&& re
->type
!= type
)
871 && (re
->type
!= ZEBRA_ROUTE_OSPF
872 || re
->instance
!= ospf_instance_id
))
877 json_prefix
= json_object_new_array();
882 SHOW_ROUTE_V4_HEADER
);
885 SHOW_ROUTE_V6_HEADER
);
887 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
888 vty_out(vty
, "\nVRF %s table %u:\n",
889 zvrf_name(zvrf
), tableid
);
890 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
891 vty_out(vty
, "\nVRF %s:\n",
897 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
901 prefix2str(&rn
->p
, buf
, sizeof(buf
));
902 json_object_object_add(json
, buf
, json_prefix
);
908 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
909 JSON_C_TO_STRING_PRETTY
));
910 json_object_free(json
);
914 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
915 safi_t safi
, bool use_fib
, bool use_json
,
917 const struct prefix
*longer_prefix_p
,
918 bool supernets_only
, int type
,
919 unsigned short ospf_instance_id
)
921 struct route_table
*table
;
922 struct zebra_vrf
*zvrf
= NULL
;
924 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
926 vty_out(vty
, "{}\n");
928 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
932 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
934 vty_out(vty
, "{}\n");
936 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
940 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
943 vty_out(vty
, "{}\n");
947 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
948 longer_prefix_p
, supernets_only
, type
,
949 ospf_instance_id
, use_json
, 0);
954 DEFPY (show_route_table
,
955 show_route_table_cmd
,
956 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
962 "The table number to display, if available\n"
965 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
966 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
967 struct route_table
*t
;
969 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
971 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
972 0, 0, !!json
, table
);
977 DEFPY (show_route_table_vrf
,
978 show_route_table_vrf_cmd
,
979 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
985 "The table number to display, if available\n"
989 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
990 struct zebra_vrf
*zvrf
;
991 struct route_table
*t
;
992 vrf_id_t vrf_id
= VRF_DEFAULT
;
995 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
996 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
998 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
1000 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
1001 0, 0, !!json
, table
);
1006 DEFPY (show_route_all_table_vrf
,
1007 show_route_all_table_vrf_cmd
,
1008 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1012 "IP routing table\n"
1013 "Display all tables\n"
1014 VRF_FULL_CMD_HELP_STR
1017 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1018 struct zebra_vrf
*zvrf
= NULL
;
1019 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1020 struct zebra_router_table
*zrt
;
1023 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1024 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1027 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1028 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1030 if (zvrf
&& zvrf
!= info
->zvrf
)
1032 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1035 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
, false, 0,
1036 false, false, 0, 0, !!json
, zrt
->tableid
);
1043 "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]",
1047 "IP nexthop tracking table\n"
1048 "IP import check tracking table\n"
1054 VRF_ALL_CMD_HELP_STR
)
1056 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1057 vrf_id_t vrf_id
= VRF_DEFAULT
;
1058 struct prefix prefix
, *p
= NULL
;
1061 if (strcmp(type
, "nht") == 0)
1062 rtype
= RNH_NEXTHOP_TYPE
;
1064 rtype
= RNH_IMPORT_CHECK_TYPE
;
1068 struct zebra_vrf
*zvrf
;
1070 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1071 if ((zvrf
= vrf
->info
) != NULL
) {
1072 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1073 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1079 VRF_GET_ID(vrf_id
, vrf_name
, false);
1081 memset(&prefix
, 0, sizeof(prefix
));
1083 p
= sockunion2hostprefix(addr
, &prefix
);
1085 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1089 DEFUN (ip_nht_default_route
,
1090 ip_nht_default_route_cmd
,
1091 "ip nht resolve-via-default",
1093 "Filter Next Hop tracking route resolution\n"
1094 "Resolve via default route\n")
1096 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1101 if (zvrf
->zebra_rnh_ip_default_route
)
1104 zvrf
->zebra_rnh_ip_default_route
= 1;
1106 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1110 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1112 struct nexthop
*nexthop
= NULL
;
1113 struct nhg_connected
*rb_node_dep
= NULL
;
1114 char buf
[SRCDEST2STR_BUFFER
];
1116 struct vrf
*nhe_vrf
= vrf_lookup_by_id(nhe
->vrf_id
);
1118 vty_out(vty
, "ID: %u\n", nhe
->id
);
1119 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1122 vty_out(vty
, " VRF: %s\n", nhe_vrf
->name
);
1124 vty_out(vty
, " VRF: UNKNOWN\n");
1126 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_UNHASHABLE
))
1127 vty_out(vty
, " Duplicate - from kernel not hashable\n");
1129 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1130 vty_out(vty
, " Valid");
1131 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1132 vty_out(vty
, ", Installed");
1136 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1138 if (!zebra_nhg_depends_is_empty(nhe
)) {
1139 vty_out(vty
, " Depends:");
1140 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1141 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1146 for (ALL_NEXTHOPS_PTR(nhe
->nhg
, nexthop
)) {
1147 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1150 /* Make recursive nexthops a bit more clear */
1153 switch (nexthop
->type
) {
1154 case NEXTHOP_TYPE_IPV4
:
1155 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1156 vty_out(vty
, " %s", inet_ntoa(nexthop
->gate
.ipv4
));
1157 if (nexthop
->ifindex
)
1158 vty_out(vty
, ", %s",
1159 ifindex2ifname(nexthop
->ifindex
,
1162 case NEXTHOP_TYPE_IPV6
:
1163 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1165 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1167 if (nexthop
->ifindex
)
1168 vty_out(vty
, ", %s",
1169 ifindex2ifname(nexthop
->ifindex
,
1173 case NEXTHOP_TYPE_IFINDEX
:
1174 vty_out(vty
, " directly connected %s",
1175 ifindex2ifname(nexthop
->ifindex
,
1178 case NEXTHOP_TYPE_BLACKHOLE
:
1179 vty_out(vty
, " unreachable");
1180 switch (nexthop
->bh_type
) {
1181 case BLACKHOLE_REJECT
:
1182 vty_out(vty
, " (ICMP unreachable)");
1184 case BLACKHOLE_ADMINPROHIB
:
1185 vty_out(vty
, " (ICMP admin-prohibited)");
1187 case BLACKHOLE_NULL
:
1188 vty_out(vty
, " (blackhole)");
1190 case BLACKHOLE_UNSPEC
:
1198 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1201 vty_out(vty
, " (vrf %s)", vrf
->name
);
1203 vty_out(vty
, " (vrf UNKNOWN)");
1205 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1206 vty_out(vty
, " inactive");
1208 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1209 vty_out(vty
, " onlink");
1211 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1212 vty_out(vty
, " (recursive)");
1214 switch (nexthop
->type
) {
1215 case NEXTHOP_TYPE_IPV4
:
1216 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1217 if (nexthop
->src
.ipv4
.s_addr
) {
1218 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1220 vty_out(vty
, ", src %s", buf
);
1223 case NEXTHOP_TYPE_IPV6
:
1224 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1225 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1226 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1228 vty_out(vty
, ", src %s", buf
);
1235 /* Label information */
1236 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1237 vty_out(vty
, ", label %s",
1238 mpls_label2str(nexthop
->nh_label
->num_labels
,
1239 nexthop
->nh_label
->label
, buf
,
1246 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1247 vty_out(vty
, " Dependents:");
1248 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1250 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1257 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1259 struct nhg_hash_entry
*nhe
= NULL
;
1261 nhe
= zebra_nhg_lookup_id(id
);
1264 show_nexthop_group_out(vty
, nhe
);
1266 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1272 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1273 struct zebra_vrf
*zvrf
, afi_t afi
)
1275 struct list
*list
= hash_to_list(zrouter
.nhgs
);
1276 struct nhg_hash_entry
*nhe
= NULL
;
1277 struct listnode
*node
= NULL
;
1279 for (ALL_LIST_ELEMENTS_RO(list
, node
, nhe
)) {
1281 if (afi
&& nhe
->afi
!= afi
)
1284 if (nhe
->vrf_id
!= zvrf
->vrf
->vrf_id
)
1287 show_nexthop_group_out(vty
, nhe
);
1293 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1295 struct zebra_if
*zebra_if
= NULL
;
1296 struct nhg_connected
*rb_node_dep
= NULL
;
1298 zebra_if
= ifp
->info
;
1300 if (!if_nhg_dependents_is_empty(ifp
)) {
1301 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1303 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1306 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1311 DEFPY (show_interface_nexthop_group
,
1312 show_interface_nexthop_group_cmd
,
1313 "show interface [IFNAME$if_name] nexthop-group",
1315 "Interface status and configuration\n"
1317 "Show Nexthop Groups\n")
1319 struct vrf
*vrf
= NULL
;
1320 struct interface
*ifp
= NULL
;
1323 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1325 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1327 if_nexthop_group_dump_vty(vty
, ifp
);
1331 FOR_ALL_INTERFACES (vrf
, ifp
)
1332 if_nexthop_group_dump_vty(vty
, ifp
);
1338 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1345 DEFPY (show_nexthop_group
,
1346 show_nexthop_group_cmd
,
1347 "show nexthop-group <(0-4294967295)$id|[<ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
1349 "Show Nexthop Groups\n"
1350 "Nexthop Group ID\n"
1353 VRF_FULL_CMD_HELP_STR
)
1356 struct zebra_vrf
*zvrf
= NULL
;
1360 return show_nexthop_group_id_cmd_helper(vty
, id
);
1370 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1371 struct zebra_vrf
*zvrf
;
1377 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1378 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1385 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1387 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1390 vty_out(vty
, "VRF %s specified does not exist", vrf_name
);
1394 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1399 DEFUN (no_ip_nht_default_route
,
1400 no_ip_nht_default_route_cmd
,
1401 "no ip nht resolve-via-default",
1404 "Filter Next Hop tracking route resolution\n"
1405 "Resolve via default route\n")
1407 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1412 if (!zvrf
->zebra_rnh_ip_default_route
)
1415 zvrf
->zebra_rnh_ip_default_route
= 0;
1416 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1420 DEFUN (ipv6_nht_default_route
,
1421 ipv6_nht_default_route_cmd
,
1422 "ipv6 nht resolve-via-default",
1424 "Filter Next Hop tracking route resolution\n"
1425 "Resolve via default route\n")
1427 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1432 if (zvrf
->zebra_rnh_ipv6_default_route
)
1435 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1436 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1440 DEFUN (no_ipv6_nht_default_route
,
1441 no_ipv6_nht_default_route_cmd
,
1442 "no ipv6 nht resolve-via-default",
1445 "Filter Next Hop tracking route resolution\n"
1446 "Resolve via default route\n")
1449 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1454 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1457 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1458 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1466 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1469 |A.B.C.D/M$prefix longer-prefixes\
1470 |supernets-only$supernets_only\
1473 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1474 |ospf$type_str (1-65535)$ospf_instance_id\
1476 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1479 |X:X::X:X/M$prefix longer-prefixes\
1481 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1486 "IP forwarding table\n"
1487 "IP routing table\n"
1488 VRF_FULL_CMD_HELP_STR
1489 "Show only routes with tag\n"
1491 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1492 "Show route matching the specified Network/Mask pair only\n"
1493 "Show supernet entries only\n"
1494 FRR_IP_REDIST_HELP_STR_ZEBRA
1495 "Open Shortest Path First (OSPFv2)\n"
1498 "IP forwarding table\n"
1499 "IP routing table\n"
1500 VRF_FULL_CMD_HELP_STR
1501 "Show only routes with tag\n"
1504 "Show route matching the specified Network/Mask pair only\n"
1505 FRR_IP6_REDIST_HELP_STR_ZEBRA
1508 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1513 type
= proto_redistnum(afi
, type_str
);
1515 vty_out(vty
, "Unknown route type\n");
1521 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1522 struct zebra_vrf
*zvrf
;
1523 struct route_table
*table
;
1525 if ((zvrf
= vrf
->info
) == NULL
1526 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1530 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1531 !!json
, tag
, prefix_str
? prefix
: NULL
,
1532 !!supernets_only
, type
, ospf_instance_id
);
1535 vrf_id_t vrf_id
= VRF_DEFAULT
;
1538 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1539 vrf
= vrf_lookup_by_id(vrf_id
);
1540 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1541 !!json
, tag
, prefix_str
? prefix
: NULL
,
1542 !!supernets_only
, type
, ospf_instance_id
);
1548 DEFPY (show_route_detail
,
1549 show_route_detail_cmd
,
1552 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1557 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1563 [json$json] [nexthop-group$ng]",
1566 "IPv6 forwarding table\n"
1567 "IP routing table\n"
1568 VRF_FULL_CMD_HELP_STR
1569 "Network in the IP routing table to display\n"
1570 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1572 "IPv6 forwarding table\n"
1573 "IPv6 routing table\n"
1574 VRF_FULL_CMD_HELP_STR
1578 "Nexthop Group Information\n")
1580 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1581 struct route_table
*table
;
1583 struct route_node
*rn
;
1584 bool use_fib
= !!fib
;
1586 bool network_found
= false;
1587 bool show_ng
= !!ng
;
1590 prefix_str
= address_str
;
1591 if (str2prefix(prefix_str
, &p
) < 0) {
1592 vty_out(vty
, "%% Malformed address\n");
1598 struct zebra_vrf
*zvrf
;
1600 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1601 if ((zvrf
= vrf
->info
) == NULL
1602 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1605 rn
= route_node_match(table
, &p
);
1608 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1609 route_unlock_node(rn
);
1613 dest
= rib_dest_from_rnode(rn
);
1614 if (use_fib
&& !dest
->selected_fib
) {
1615 route_unlock_node(rn
);
1619 network_found
= true;
1621 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1623 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1626 route_unlock_node(rn
);
1629 if (!network_found
) {
1631 vty_out(vty
, "{}\n");
1635 "%% Network not in FIB\n");
1638 "%% Network not in RIB\n");
1643 vrf_id_t vrf_id
= VRF_DEFAULT
;
1646 VRF_GET_ID(vrf_id
, vrf_name
, false);
1648 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1652 rn
= route_node_match(table
, &p
);
1654 dest
= rib_dest_from_rnode(rn
);
1656 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1657 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1659 vty_out(vty
, "{}\n");
1663 "%% Network not in FIB\n");
1666 "%% Network not in table\n");
1669 route_unlock_node(rn
);
1674 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1676 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1678 route_unlock_node(rn
);
1684 DEFPY (show_route_summary
,
1685 show_route_summary_cmd
,
1686 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1687 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1691 "IP routing table\n"
1692 VRF_FULL_CMD_HELP_STR
1693 "Summary of all routes\n"
1694 "Table to display summary for\n"
1695 "The table number\n"
1698 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1699 struct route_table
*table
;
1702 table_id
= RT_TABLE_MAIN
;
1706 struct zebra_vrf
*zvrf
;
1708 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1709 if ((zvrf
= vrf
->info
) == NULL
)
1712 table
= zebra_vrf_lookup_table_with_table_id(
1713 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, table_id
);
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_lookup_table_with_table_id(afi
, SAFI_UNICAST
,
1735 vty_show_ip_route_summary_prefix(vty
, table
);
1737 vty_show_ip_route_summary(vty
, table
);
1743 static void vty_show_ip_route_summary(struct vty
*vty
,
1744 struct route_table
*table
)
1746 struct route_node
*rn
;
1747 struct route_entry
*re
;
1748 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1749 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1750 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1751 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1755 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1756 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1757 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1758 RNODE_FOREACH_RE (rn
, re
) {
1759 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1760 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1762 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1764 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1766 rib_cnt
[re
->type
]++;
1768 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1769 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1772 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1774 fib_cnt
[re
->type
]++;
1778 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1779 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1781 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1782 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1783 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1784 if (i
== ZEBRA_ROUTE_BGP
) {
1785 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1786 rib_cnt
[ZEBRA_ROUTE_BGP
],
1787 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1788 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1789 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1790 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1792 vty_out(vty
, "%-20s %-20d %-20d \n",
1793 zebra_route_string(i
), rib_cnt
[i
],
1798 vty_out(vty
, "------\n");
1799 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1800 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1805 * Implementation of the ip route summary prefix command.
1807 * This command prints the primary prefixes that have been installed by various
1808 * protocols on the box.
1811 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1812 struct route_table
*table
)
1814 struct route_node
*rn
;
1815 struct route_entry
*re
;
1816 struct nexthop
*nexthop
;
1817 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1818 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1819 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1820 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1824 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1825 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1826 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1827 RNODE_FOREACH_RE (rn
, re
) {
1830 * In case of ECMP, count only once.
1833 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1834 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1835 fib_cnt
[re
->type
]++;
1837 for (nexthop
= re
->nhe
->nhg
->nexthop
; (!cnt
&& nexthop
);
1838 nexthop
= nexthop
->next
) {
1840 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1841 rib_cnt
[re
->type
]++;
1842 if (re
->type
== ZEBRA_ROUTE_BGP
1843 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1844 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1845 if (CHECK_FLAG(re
->status
,
1846 ROUTE_ENTRY_INSTALLED
))
1847 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1852 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1853 "Prefix Routes", "FIB",
1854 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1856 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1857 if (rib_cnt
[i
] > 0) {
1858 if (i
== ZEBRA_ROUTE_BGP
) {
1859 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1860 rib_cnt
[ZEBRA_ROUTE_BGP
]
1861 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1862 fib_cnt
[ZEBRA_ROUTE_BGP
]
1863 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1864 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1865 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1866 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1868 vty_out(vty
, "%-20s %-20d %-20d \n",
1869 zebra_route_string(i
), rib_cnt
[i
],
1874 vty_out(vty
, "------\n");
1875 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1876 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1881 * Show IPv6 mroute command.Used to dump
1882 * the Multicast routing table.
1884 DEFUN (show_ipv6_mroute
,
1885 show_ipv6_mroute_cmd
,
1886 "show ipv6 mroute [vrf NAME]",
1889 "IPv6 Multicast routing table\n"
1892 struct route_table
*table
;
1893 struct route_node
*rn
;
1894 struct route_entry
*re
;
1896 vrf_id_t vrf_id
= VRF_DEFAULT
;
1899 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1901 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1905 /* Show all IPv6 route. */
1906 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1907 RNODE_FOREACH_RE (rn
, re
) {
1909 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1912 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1917 DEFUN (show_ipv6_mroute_vrf_all
,
1918 show_ipv6_mroute_vrf_all_cmd
,
1919 "show ipv6 mroute vrf all",
1922 "IPv6 Multicast routing table\n"
1923 VRF_ALL_CMD_HELP_STR
)
1925 struct route_table
*table
;
1926 struct route_node
*rn
;
1927 struct route_entry
*re
;
1929 struct zebra_vrf
*zvrf
;
1932 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1933 if ((zvrf
= vrf
->info
) == NULL
1934 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1937 /* Show all IPv6 route. */
1938 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1939 RNODE_FOREACH_RE (rn
, re
) {
1941 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1944 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1950 DEFUN (allow_external_route_update
,
1951 allow_external_route_update_cmd
,
1952 "allow-external-route-update",
1953 "Allow FRR routes to be overwritten by external processes\n")
1960 DEFUN (no_allow_external_route_update
,
1961 no_allow_external_route_update_cmd
,
1962 "no allow-external-route-update",
1964 "Allow FRR routes to be overwritten by external processes\n")
1979 struct zebra_vrf
*zvrf
;
1981 if (vrf_is_backend_netns())
1982 vty_out(vty
, "netns-based vrfs\n");
1984 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1985 if (!(zvrf
= vrf
->info
))
1987 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1990 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1991 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1992 vty_out(vty
, "inactive");
1993 else if (zvrf_ns_name(zvrf
))
1994 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1995 zvrf_ns_name(zvrf
));
1997 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1999 if (vrf_is_user_cfged(vrf
))
2000 vty_out(vty
, " (configured)");
2007 DEFUN (default_vrf_vni_mapping
,
2008 default_vrf_vni_mapping_cmd
,
2009 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2010 "VNI corresponding to the DEFAULT VRF\n"
2012 "Prefix routes only \n")
2015 char err
[ERR_STR_SZ
];
2016 struct zebra_vrf
*zvrf
= NULL
;
2017 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2020 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2027 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2030 vty_out(vty
, "%s\n", err
);
2037 DEFUN (no_default_vrf_vni_mapping
,
2038 no_default_vrf_vni_mapping_cmd
,
2039 "no vni " CMD_VNI_RANGE
,
2041 "VNI corresponding to DEFAULT VRF\n"
2045 char err
[ERR_STR_SZ
];
2046 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2047 struct zebra_vrf
*zvrf
= NULL
;
2049 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2053 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2055 vty_out(vty
, "%s\n", err
);
2062 DEFUN (vrf_vni_mapping
,
2063 vrf_vni_mapping_cmd
,
2064 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2065 "VNI corresponding to tenant VRF\n"
2067 "prefix-routes-only\n")
2072 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2073 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2074 char err
[ERR_STR_SZ
];
2082 /* Mark as having FRR configuration */
2083 vrf_set_user_cfged(vrf
);
2084 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2087 vty_out(vty
, "%s\n", err
);
2094 DEFUN (no_vrf_vni_mapping
,
2095 no_vrf_vni_mapping_cmd
,
2096 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2098 "VNI corresponding to tenant VRF\n"
2100 "prefix-routes-only\n")
2104 char err
[ERR_STR_SZ
];
2105 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2107 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2115 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2116 ERR_STR_SZ
, filter
, 0);
2118 vty_out(vty
, "%s\n", err
);
2122 /* If no other FRR config for this VRF, mark accordingly. */
2123 if (!zebra_vrf_has_config(zvrf
))
2124 vrf_reset_user_cfged(vrf
);
2130 DEFUN (show_vrf_vni
,
2132 "show vrf vni [json]",
2139 struct zebra_vrf
*zvrf
;
2140 json_object
*json
= NULL
;
2141 json_object
*json_vrfs
= NULL
;
2142 bool uj
= use_json(argc
, argv
);
2145 json
= json_object_new_object();
2146 json_vrfs
= json_object_new_array();
2150 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2151 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2153 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2158 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2162 json_object_object_add(json
, "vrfs", json_vrfs
);
2163 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2164 json
, JSON_C_TO_STRING_PRETTY
));
2165 json_object_free(json
);
2171 DEFUN (show_evpn_global
,
2172 show_evpn_global_cmd
,
2178 bool uj
= use_json(argc
, argv
);
2180 zebra_vxlan_print_evpn(vty
, uj
);
2184 DEFUN (show_evpn_vni
,
2186 "show evpn vni [json]",
2189 "VxLAN Network Identifier\n"
2192 struct zebra_vrf
*zvrf
;
2193 bool uj
= use_json(argc
, argv
);
2195 zvrf
= zebra_vrf_get_evpn();
2196 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2200 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2201 "show evpn vni detail [json]",
2204 "VxLAN Network Identifier\n"
2205 "Detailed Information On Each VNI\n"
2208 struct zebra_vrf
*zvrf
;
2209 bool uj
= use_json(argc
, argv
);
2211 zvrf
= zebra_vrf_get_evpn();
2212 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2216 DEFUN (show_evpn_vni_vni
,
2217 show_evpn_vni_vni_cmd
,
2218 "show evpn vni " CMD_VNI_RANGE
"[json]",
2221 "VxLAN Network Identifier\n"
2225 struct zebra_vrf
*zvrf
;
2227 bool uj
= use_json(argc
, argv
);
2229 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2230 zvrf
= zebra_vrf_get_evpn();
2231 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2235 DEFUN (show_evpn_rmac_vni_mac
,
2236 show_evpn_rmac_vni_mac_cmd
,
2237 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2244 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2249 bool uj
= use_json(argc
, argv
);
2251 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2252 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2253 vty_out(vty
, "%% Malformed MAC address\n");
2256 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2260 DEFUN (show_evpn_rmac_vni
,
2261 show_evpn_rmac_vni_cmd
,
2262 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2271 bool uj
= use_json(argc
, argv
);
2273 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2274 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2279 DEFUN (show_evpn_rmac_vni_all
,
2280 show_evpn_rmac_vni_all_cmd
,
2281 "show evpn rmac vni all [json]",
2289 bool uj
= use_json(argc
, argv
);
2291 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2296 DEFUN (show_evpn_nh_vni_ip
,
2297 show_evpn_nh_vni_ip_cmd
,
2298 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2305 "Host address (ipv4 or ipv6)\n"
2310 bool uj
= use_json(argc
, argv
);
2312 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2313 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2315 vty_out(vty
, "%% Malformed Neighbor address\n");
2318 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2323 DEFUN (show_evpn_nh_vni
,
2324 show_evpn_nh_vni_cmd
,
2325 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2334 bool uj
= use_json(argc
, argv
);
2336 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2337 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2342 DEFUN (show_evpn_nh_vni_all
,
2343 show_evpn_nh_vni_all_cmd
,
2344 "show evpn next-hops vni all [json]",
2352 bool uj
= use_json(argc
, argv
);
2354 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2359 DEFUN (show_evpn_mac_vni
,
2360 show_evpn_mac_vni_cmd
,
2361 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2365 "VxLAN Network Identifier\n"
2369 struct zebra_vrf
*zvrf
;
2371 bool uj
= use_json(argc
, argv
);
2373 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2374 zvrf
= zebra_vrf_get_evpn();
2375 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2379 DEFUN (show_evpn_mac_vni_all
,
2380 show_evpn_mac_vni_all_cmd
,
2381 "show evpn mac vni all [json]",
2385 "VxLAN Network Identifier\n"
2389 struct zebra_vrf
*zvrf
;
2390 bool uj
= use_json(argc
, argv
);
2392 zvrf
= zebra_vrf_get_evpn();
2393 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2397 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2398 "show evpn mac vni all detail [json]",
2402 "VxLAN Network Identifier\n"
2404 "Detailed Information On Each VNI MAC\n"
2407 struct zebra_vrf
*zvrf
;
2408 bool uj
= use_json(argc
, argv
);
2410 zvrf
= zebra_vrf_get_evpn();
2411 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2415 DEFUN (show_evpn_mac_vni_all_vtep
,
2416 show_evpn_mac_vni_all_vtep_cmd
,
2417 "show evpn mac vni all vtep A.B.C.D [json]",
2421 "VxLAN Network Identifier\n"
2424 "Remote VTEP IP address\n"
2427 struct zebra_vrf
*zvrf
;
2428 struct in_addr vtep_ip
;
2429 bool uj
= use_json(argc
, argv
);
2431 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2433 vty_out(vty
, "%% Malformed VTEP IP address\n");
2436 zvrf
= zebra_vrf_get_evpn();
2437 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2443 DEFUN (show_evpn_mac_vni_mac
,
2444 show_evpn_mac_vni_mac_cmd
,
2445 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2449 "VxLAN Network Identifier\n"
2452 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2456 struct zebra_vrf
*zvrf
;
2459 bool uj
= use_json(argc
, argv
);
2461 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2462 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2463 vty_out(vty
, "%% Malformed MAC address");
2466 zvrf
= zebra_vrf_get_evpn();
2467 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2471 DEFUN (show_evpn_mac_vni_vtep
,
2472 show_evpn_mac_vni_vtep_cmd
,
2473 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2477 "VxLAN Network Identifier\n"
2480 "Remote VTEP IP address\n"
2483 struct zebra_vrf
*zvrf
;
2485 struct in_addr vtep_ip
;
2486 bool uj
= use_json(argc
, argv
);
2488 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2489 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2491 vty_out(vty
, "%% Malformed VTEP IP address\n");
2495 zvrf
= zebra_vrf_get_evpn();
2496 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2500 DEFPY (show_evpn_mac_vni_all_dad
,
2501 show_evpn_mac_vni_all_dad_cmd
,
2502 "show evpn mac vni all duplicate [json]",
2506 "VxLAN Network Identifier\n"
2508 "Duplicate address list\n"
2511 struct zebra_vrf
*zvrf
;
2512 bool uj
= use_json(argc
, argv
);
2514 zvrf
= zebra_vrf_get_evpn();
2515 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2520 DEFPY (show_evpn_mac_vni_dad
,
2521 show_evpn_mac_vni_dad_cmd
,
2522 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2526 "VxLAN Network Identifier\n"
2528 "Duplicate address list\n"
2531 struct zebra_vrf
*zvrf
;
2532 bool uj
= use_json(argc
, argv
);
2534 zvrf
= zebra_vrf_get_evpn();
2536 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2541 DEFPY (show_evpn_neigh_vni_dad
,
2542 show_evpn_neigh_vni_dad_cmd
,
2543 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2546 "ARP and ND cache\n"
2547 "VxLAN Network Identifier\n"
2549 "Duplicate address list\n"
2552 struct zebra_vrf
*zvrf
;
2553 bool uj
= use_json(argc
, argv
);
2555 zvrf
= zebra_vrf_get_evpn();
2556 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2560 DEFPY (show_evpn_neigh_vni_all_dad
,
2561 show_evpn_neigh_vni_all_dad_cmd
,
2562 "show evpn arp-cache vni all duplicate [json]",
2565 "ARP and ND cache\n"
2566 "VxLAN Network Identifier\n"
2568 "Duplicate address list\n"
2571 struct zebra_vrf
*zvrf
;
2572 bool uj
= use_json(argc
, argv
);
2574 zvrf
= zebra_vrf_get_evpn();
2575 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2580 DEFUN (show_evpn_neigh_vni
,
2581 show_evpn_neigh_vni_cmd
,
2582 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2585 "ARP and ND cache\n"
2586 "VxLAN Network Identifier\n"
2590 struct zebra_vrf
*zvrf
;
2592 bool uj
= use_json(argc
, argv
);
2594 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2595 zvrf
= zebra_vrf_get_evpn();
2596 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2600 DEFUN (show_evpn_neigh_vni_all
,
2601 show_evpn_neigh_vni_all_cmd
,
2602 "show evpn arp-cache vni all [json]",
2605 "ARP and ND cache\n"
2606 "VxLAN Network Identifier\n"
2610 struct zebra_vrf
*zvrf
;
2611 bool uj
= use_json(argc
, argv
);
2613 zvrf
= zebra_vrf_get_evpn();
2614 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2618 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2619 "show evpn arp-cache vni all detail [json]",
2622 "ARP and ND cache\n"
2623 "VxLAN Network Identifier\n"
2625 "Neighbor details for all vnis in detail\n" JSON_STR
)
2627 struct zebra_vrf
*zvrf
;
2628 bool uj
= use_json(argc
, argv
);
2630 zvrf
= zebra_vrf_get_evpn();
2631 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2635 DEFUN (show_evpn_neigh_vni_neigh
,
2636 show_evpn_neigh_vni_neigh_cmd
,
2637 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2640 "ARP and ND cache\n"
2641 "VxLAN Network Identifier\n"
2644 "Neighbor address (IPv4 or IPv6 address)\n"
2647 struct zebra_vrf
*zvrf
;
2650 bool uj
= use_json(argc
, argv
);
2652 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2653 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2655 vty_out(vty
, "%% Malformed Neighbor address\n");
2658 zvrf
= zebra_vrf_get_evpn();
2659 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2663 DEFUN (show_evpn_neigh_vni_vtep
,
2664 show_evpn_neigh_vni_vtep_cmd
,
2665 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2668 "ARP and ND cache\n"
2669 "VxLAN Network Identifier\n"
2672 "Remote VTEP IP address\n"
2675 struct zebra_vrf
*zvrf
;
2677 struct in_addr vtep_ip
;
2678 bool uj
= use_json(argc
, argv
);
2680 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2681 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2683 vty_out(vty
, "%% Malformed VTEP IP address\n");
2687 zvrf
= zebra_vrf_get_evpn();
2688 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2692 /* policy routing contexts */
2693 DEFUN (show_pbr_ipset
,
2695 "show pbr ipset [WORD]",
2697 "Policy-Based Routing\n"
2698 "IPset Context information\n"
2699 "IPset Name information\n")
2703 found
= argv_find(argv
, argc
, "WORD", &idx
);
2705 zebra_pbr_show_ipset_list(vty
, NULL
);
2707 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2711 /* policy routing contexts */
2712 DEFUN (show_pbr_iptable
,
2713 show_pbr_iptable_cmd
,
2714 "show pbr iptable [WORD]",
2716 "Policy-Based Routing\n"
2717 "IPtable Context information\n"
2718 "IPtable Name information\n")
2723 found
= argv_find(argv
, argc
, "WORD", &idx
);
2725 zebra_pbr_show_iptable(vty
, NULL
);
2727 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2731 DEFPY (clear_evpn_dup_addr
,
2732 clear_evpn_dup_addr_cmd
,
2733 "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>]>",
2736 "Duplicate address \n"
2737 "VxLAN Network Identifier\n"
2741 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2746 struct zebra_vrf
*zvrf
;
2747 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2748 int ret
= CMD_SUCCESS
;
2750 zvrf
= zebra_vrf_get_evpn();
2752 if (!is_zero_mac(&mac
->eth_addr
)) {
2753 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2757 if (sockunion_family(ip
) == AF_INET
) {
2758 host_ip
.ipa_type
= IPADDR_V4
;
2759 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2761 host_ip
.ipa_type
= IPADDR_V6
;
2762 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2763 sizeof(struct in6_addr
));
2765 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2769 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2772 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2778 /* Static ip route configuration write function. */
2779 static int zebra_ip_config(struct vty
*vty
)
2783 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2788 DEFUN (ip_zebra_import_table_distance
,
2789 ip_zebra_import_table_distance_cmd
,
2790 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2792 "import routes from non-main kernel table\n"
2793 "kernel routing table id\n"
2794 "Distance for imported routes\n"
2795 "Default distance value\n"
2796 "route-map for filtering\n"
2799 uint32_t table_id
= 0;
2801 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2802 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2804 strmatch(argv
[argc
- 2]->text
, "route-map")
2805 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2809 if (argc
== 7 || (argc
== 5 && !rmap
))
2810 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2812 if (!is_zebra_valid_kernel_table(table_id
)) {
2814 "Invalid routing table ID, %d. Must be in range 1-252\n",
2817 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2821 if (is_zebra_main_routing_table(table_id
)) {
2823 "Invalid routing table ID, %d. Must be non-default table\n",
2826 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2830 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2833 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2838 DEFUN_HIDDEN (zebra_packet_process
,
2839 zebra_packet_process_cmd
,
2840 "zebra zapi-packets (1-10000)",
2843 "Number of packets to process before relinquishing thread\n")
2845 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2847 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2848 memory_order_relaxed
);
2853 DEFUN_HIDDEN (no_zebra_packet_process
,
2854 no_zebra_packet_process_cmd
,
2855 "no zebra zapi-packets [(1-10000)]",
2859 "Number of packets to process before relinquishing thread\n")
2861 atomic_store_explicit(&zrouter
.packets_to_process
,
2862 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2863 memory_order_relaxed
);
2868 DEFUN_HIDDEN (zebra_workqueue_timer
,
2869 zebra_workqueue_timer_cmd
,
2870 "zebra work-queue (0-10000)",
2873 "Time in milliseconds\n")
2875 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2876 zrouter
.ribq
->spec
.hold
= timer
;
2881 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2882 no_zebra_workqueue_timer_cmd
,
2883 "no zebra work-queue [(0-10000)]",
2887 "Time in milliseconds\n")
2889 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2894 DEFUN (no_ip_zebra_import_table
,
2895 no_ip_zebra_import_table_cmd
,
2896 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2899 "import routes from non-main kernel table\n"
2900 "kernel routing table id\n"
2901 "Distance for imported routes\n"
2902 "Default distance value\n"
2903 "route-map for filtering\n"
2906 uint32_t table_id
= 0;
2907 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2909 if (!is_zebra_valid_kernel_table(table_id
)) {
2911 "Invalid routing table ID. Must be in range 1-252\n");
2915 if (is_zebra_main_routing_table(table_id
)) {
2917 "Invalid routing table ID, %d. Must be non-default table\n",
2922 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2925 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2928 static int config_write_protocol(struct vty
*vty
)
2931 vty_out(vty
, "allow-external-route-update\n");
2933 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2934 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2936 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2937 vty_out(vty
, "zebra zapi-packets %u\n",
2938 zrouter
.packets_to_process
);
2940 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2942 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2943 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2944 ipv4_multicast_mode
== MCAST_URIB_ONLY
2946 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2948 : ipv4_multicast_mode
2949 == MCAST_MIX_MRIB_FIRST
2951 : ipv4_multicast_mode
2952 == MCAST_MIX_DISTANCE
2956 /* Include dataplane info */
2957 dplane_config_write_helper(vty
);
2971 " Route Route Neighbor LSP LSP\n");
2973 "VRF Installs Removals Updates Installs Removals\n");
2975 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2976 struct zebra_vrf
*zvrf
= vrf
->info
;
2978 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2979 " %10" PRIu64
" %10" PRIu64
"\n",
2980 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2981 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2982 zvrf
->lsp_removals
);
2988 DEFUN (ip_forwarding
,
2992 "Turn on IP forwarding\n")
2998 ret
= ipforward_on();
3001 vty_out(vty
, "Can't turn on IP forwarding\n");
3002 return CMD_WARNING_CONFIG_FAILED
;
3008 DEFUN (no_ip_forwarding
,
3009 no_ip_forwarding_cmd
,
3013 "Turn off IP forwarding\n")
3019 ret
= ipforward_off();
3022 vty_out(vty
, "Can't turn off IP forwarding\n");
3023 return CMD_WARNING_CONFIG_FAILED
;
3029 /* Only display ip forwarding is enabled or not. */
3030 DEFUN (show_ip_forwarding
,
3031 show_ip_forwarding_cmd
,
3032 "show ip forwarding",
3035 "IP forwarding status\n")
3042 vty_out(vty
, "IP forwarding is off\n");
3044 vty_out(vty
, "IP forwarding is on\n");
3048 /* Only display ipv6 forwarding is enabled or not. */
3049 DEFUN (show_ipv6_forwarding
,
3050 show_ipv6_forwarding_cmd
,
3051 "show ipv6 forwarding",
3053 "IPv6 information\n"
3054 "Forwarding status\n")
3058 ret
= ipforward_ipv6();
3062 vty_out(vty
, "ipv6 forwarding is unknown\n");
3065 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3068 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3071 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3077 DEFUN (ipv6_forwarding
,
3078 ipv6_forwarding_cmd
,
3081 "Turn on IPv6 forwarding\n")
3085 ret
= ipforward_ipv6();
3087 ret
= ipforward_ipv6_on();
3090 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3091 return CMD_WARNING_CONFIG_FAILED
;
3097 DEFUN (no_ipv6_forwarding
,
3098 no_ipv6_forwarding_cmd
,
3099 "no ipv6 forwarding",
3102 "Turn off IPv6 forwarding\n")
3106 ret
= ipforward_ipv6();
3108 ret
= ipforward_ipv6_off();
3111 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3112 return CMD_WARNING_CONFIG_FAILED
;
3118 /* Display dataplane info */
3119 DEFUN (show_dataplane
,
3121 "show zebra dplane [detailed]",
3124 "Zebra dataplane information\n"
3125 "Detailed output\n")
3128 bool detailed
= false;
3130 if (argv_find(argv
, argc
, "detailed", &idx
))
3133 return dplane_show_helper(vty
, detailed
);
3136 /* Display dataplane providers info */
3137 DEFUN (show_dataplane_providers
,
3138 show_dataplane_providers_cmd
,
3139 "show zebra dplane providers [detailed]",
3142 "Zebra dataplane information\n"
3143 "Zebra dataplane provider information\n"
3144 "Detailed output\n")
3147 bool detailed
= false;
3149 if (argv_find(argv
, argc
, "detailed", &idx
))
3152 return dplane_show_provs_helper(vty
, detailed
);
3155 /* Configure dataplane incoming queue limit */
3156 DEFUN (zebra_dplane_queue_limit
,
3157 zebra_dplane_queue_limit_cmd
,
3158 "zebra dplane limit (0-10000)",
3161 "Limit incoming queued updates\n"
3162 "Number of queued updates\n")
3166 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3168 dplane_set_in_queue_limit(limit
, true);
3173 /* Reset dataplane queue limit to default value */
3174 DEFUN (no_zebra_dplane_queue_limit
,
3175 no_zebra_dplane_queue_limit_cmd
,
3176 "no zebra dplane limit [(0-10000)]",
3180 "Limit incoming queued updates\n"
3181 "Number of queued updates\n")
3183 dplane_set_in_queue_limit(0, false);
3188 DEFUN (zebra_show_routing_tables_summary
,
3189 zebra_show_routing_tables_summary_cmd
,
3190 "show zebra router table summary",
3193 "The Zebra Router Information\n"
3194 "Table Information about this Zebra Router\n"
3195 "Summary Information\n")
3197 zebra_router_show_table_summary(vty
);
3202 /* Table configuration write function. */
3203 static int config_write_table(struct vty
*vty
)
3208 /* IPForwarding configuration write function. */
3209 static int config_write_forwarding(struct vty
*vty
)
3211 /* FIXME: Find better place for that. */
3212 router_id_write(vty
);
3215 vty_out(vty
, "no ip forwarding\n");
3216 if (!ipforward_ipv6())
3217 vty_out(vty
, "no ipv6 forwarding\n");
3218 vty_out(vty
, "!\n");
3222 DEFUN_HIDDEN (show_frr
,
3228 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3229 vty_out(vty
, ".............................7777:..............................................\n");
3230 vty_out(vty
, ".............................777777,............................................\n");
3231 vty_out(vty
, "... .........................77777777,..........................................\n");
3232 vty_out(vty
, "............................=7777777777:........................................\n");
3233 vty_out(vty
, "........................:7777777777777777,......................................\n");
3234 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3235 vty_out(vty
, "...................I7777777777+.................................................\n");
3236 vty_out(vty
, "................,777777777?............ .......................................\n");
3237 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3238 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3239 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3240 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3241 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3242 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3243 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3244 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3245 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3246 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3247 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3248 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3249 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3250 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3251 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3252 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3253 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3254 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3255 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3256 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3257 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3258 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3259 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3260 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3261 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3262 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3263 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3264 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3265 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3266 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3267 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3268 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3269 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3270 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3271 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3272 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3273 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3274 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3275 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3276 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3277 vty_out(vty
, "................................~77777777...............=777777.................\n");
3278 vty_out(vty
, ".....................................:=?I................~777777................\n");
3279 vty_out(vty
, "..........................................................:777777,..............\n");
3280 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3285 /* IP node for static routes. */
3286 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3287 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3288 /* table node for routing tables. */
3289 static struct cmd_node table_node
= {TABLE_NODE
,
3290 "", /* This node has no interface. */
3292 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3293 "", /* This node has no interface. */
3297 void zebra_vty_init(void)
3299 /* Install configuration write function. */
3300 install_node(&table_node
, config_write_table
);
3301 install_node(&forwarding_node
, config_write_forwarding
);
3303 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3304 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3305 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3306 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3308 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3309 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3310 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3313 zebra_route_map_init();
3315 install_node(&ip_node
, zebra_ip_config
);
3316 install_node(&protocol_node
, config_write_protocol
);
3318 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3319 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3321 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3322 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3324 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3325 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3326 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3327 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3328 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3329 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3331 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3332 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3334 install_element(VIEW_NODE
, &show_vrf_cmd
);
3335 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3336 install_element(VIEW_NODE
, &show_route_cmd
);
3337 install_element(VIEW_NODE
, &show_route_table_cmd
);
3338 if (vrf_is_backend_netns())
3339 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3340 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3341 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3342 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3343 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3345 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3346 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3348 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3349 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3350 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3351 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3352 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3353 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3354 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3355 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3356 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3358 /* Commands for VRF */
3359 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3361 install_element(VIEW_NODE
, &show_frr_cmd
);
3362 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3363 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3364 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3365 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3366 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3367 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3368 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3369 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3370 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3371 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3372 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3373 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3374 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3375 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3376 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3377 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3378 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3379 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3380 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3381 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3382 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3383 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3384 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3385 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3386 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3387 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3389 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3390 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3392 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3393 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3394 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3395 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3397 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3398 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3399 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3400 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3402 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);