2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "zebra_memory.h"
35 #include "srcdest_table.h"
38 #include "zebra/zebra_router.h"
39 #include "zebra/zserv.h"
40 #include "zebra/zebra_vrf.h"
41 #include "zebra/zebra_mpls.h"
42 #include "zebra/zebra_rnh.h"
43 #include "zebra/redistribute.h"
44 #include "zebra/zebra_routemap.h"
46 #include "zebra/zebra_vxlan.h"
47 #ifndef VTYSH_EXTRACT_PL
48 #include "zebra/zebra_vty_clippy.c"
50 #include "zebra/zserv.h"
51 #include "zebra/router-id.h"
52 #include "zebra/ipforward.h"
53 #include "zebra/zebra_vxlan_private.h"
54 #include "zebra/zebra_pbr.h"
55 #include "zebra/zebra_nhg.h"
56 #include "zebra/interface.h"
58 extern int allow_delete
;
60 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
61 safi_t safi
, bool use_fib
, bool use_json
,
63 const struct prefix
*longer_prefix_p
,
64 bool supernets_only
, int type
,
65 unsigned short ospf_instance_id
);
66 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
67 int mcast
, bool use_fib
, bool show_ng
);
68 static void vty_show_ip_route_summary(struct vty
*vty
,
69 struct route_table
*table
, bool use_json
);
70 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
71 struct route_table
*table
,
74 DEFUN (ip_multicast_mode
,
75 ip_multicast_mode_cmd
,
76 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
79 "RPF lookup behavior\n"
80 "Lookup in unicast RIB only\n"
81 "Lookup in multicast RIB only\n"
82 "Try multicast RIB first, fall back to unicast RIB\n"
83 "Lookup both, use entry with lower distance\n"
84 "Lookup both, use entry with longer prefix\n")
86 char *mode
= argv
[3]->text
;
88 if (strmatch(mode
, "urib-only"))
89 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
90 else if (strmatch(mode
, "mrib-only"))
91 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
92 else if (strmatch(mode
, "mrib-then-urib"))
93 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
94 else if (strmatch(mode
, "lower-distance"))
95 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
96 else if (strmatch(mode
, "longer-prefix"))
97 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
99 vty_out(vty
, "Invalid mode specified\n");
100 return CMD_WARNING_CONFIG_FAILED
;
106 DEFUN (no_ip_multicast_mode
,
107 no_ip_multicast_mode_cmd
,
108 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
111 "Multicast options\n"
112 "RPF lookup behavior\n"
113 "Lookup in unicast RIB only\n"
114 "Lookup in multicast RIB only\n"
115 "Try multicast RIB first, fall back to unicast RIB\n"
116 "Lookup both, use entry with lower distance\n"
117 "Lookup both, use entry with longer prefix\n")
119 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
126 "show ip rpf [json]",
129 "Display RPF information for multicast source\n"
132 bool uj
= use_json(argc
, argv
);
133 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
134 false, uj
, 0, NULL
, false, 0, 0);
137 DEFUN (show_ip_rpf_addr
,
138 show_ip_rpf_addr_cmd
,
139 "show ip rpf A.B.C.D",
142 "Display RPF information for multicast source\n"
143 "IP multicast source address (e.g. 10.0.0.0)\n")
147 struct route_node
*rn
;
148 struct route_entry
*re
;
151 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
153 vty_out(vty
, "%% Malformed address\n");
157 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
160 vty_show_ip_route_detail(vty
, rn
, 1, false, false);
162 vty_out(vty
, "%% No match for RPF lookup\n");
167 static char re_status_output_char(struct route_entry
*re
, struct nexthop
*nhop
)
169 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
170 if (!CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
171 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
177 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
178 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
184 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
190 /* New RIB. Detailed information for IPv4 route. */
191 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
192 int mcast
, bool use_fib
, bool show_ng
)
194 struct route_entry
*re
;
195 struct nexthop
*nexthop
;
196 char buf
[SRCDEST2STR_BUFFER
];
197 struct zebra_vrf
*zvrf
;
200 dest
= rib_dest_from_rnode(rn
);
202 RNODE_FOREACH_RE (rn
, re
) {
204 * If re not selected for forwarding, skip re
205 * for "show ip/ipv6 fib <prefix>"
207 if (use_fib
&& re
!= dest
->selected_fib
)
210 const char *mcast_info
= "";
212 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
213 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
214 ? " using Multicast RIB"
215 : " using Unicast RIB";
218 vty_out(vty
, "Routing entry for %s%s\n",
219 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
220 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
222 vty_out(vty
, "[%d]", re
->instance
);
224 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
227 vty_out(vty
, ", tag %u", re
->tag
);
228 #if defined(SUPPORT_REALMS)
229 if (re
->tag
> 0 && re
->tag
<= 255)
230 vty_out(vty
, "(realm)");
234 vty_out(vty
, ", mtu %u", re
->mtu
);
235 if (re
->vrf_id
!= VRF_DEFAULT
) {
236 zvrf
= vrf_info_lookup(re
->vrf_id
);
237 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
239 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
240 vty_out(vty
, ", best");
246 uptime
= monotime(NULL
);
247 uptime
-= re
->uptime
;
248 tm
= gmtime(&uptime
);
250 vty_out(vty
, " Last update ");
252 if (uptime
< ONE_DAY_SECOND
)
253 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
255 else if (uptime
< ONE_WEEK_SECOND
)
256 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
259 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
260 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
262 vty_out(vty
, " ago\n");
265 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
267 for (ALL_NEXTHOPS_PTR(re
->nhe
->nhg
, nexthop
)) {
270 vty_out(vty
, " %c%s",
271 re_status_output_char(re
, nexthop
),
272 nexthop
->rparent
? " " : "");
274 switch (nexthop
->type
) {
275 case NEXTHOP_TYPE_IPV4
:
276 case NEXTHOP_TYPE_IPV4_IFINDEX
:
278 inet_ntoa(nexthop
->gate
.ipv4
));
279 if (nexthop
->ifindex
)
280 vty_out(vty
, ", via %s",
285 case NEXTHOP_TYPE_IPV6
:
286 case NEXTHOP_TYPE_IPV6_IFINDEX
:
288 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
290 if (nexthop
->ifindex
)
291 vty_out(vty
, ", via %s",
296 case NEXTHOP_TYPE_IFINDEX
:
297 vty_out(vty
, " directly connected, %s",
298 ifindex2ifname(nexthop
->ifindex
,
301 case NEXTHOP_TYPE_BLACKHOLE
:
302 vty_out(vty
, " unreachable");
303 switch (nexthop
->bh_type
) {
304 case BLACKHOLE_REJECT
:
305 vty_out(vty
, " (ICMP unreachable)");
307 case BLACKHOLE_ADMINPROHIB
:
309 " (ICMP admin-prohibited)");
312 vty_out(vty
, " (blackhole)");
314 case BLACKHOLE_UNSPEC
:
322 if ((re
->vrf_id
!= nexthop
->vrf_id
)
323 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
325 vrf_lookup_by_id(nexthop
->vrf_id
);
328 vty_out(vty
, "(vrf %s)", vrf
->name
);
330 vty_out(vty
, "(vrf UNKNOWN)");
333 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
334 vty_out(vty
, " (duplicate nexthop removed)");
336 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
337 vty_out(vty
, " inactive");
339 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
340 vty_out(vty
, " onlink");
342 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
343 vty_out(vty
, " (recursive)");
345 switch (nexthop
->type
) {
346 case NEXTHOP_TYPE_IPV4
:
347 case NEXTHOP_TYPE_IPV4_IFINDEX
:
348 if (nexthop
->src
.ipv4
.s_addr
) {
349 if (inet_ntop(AF_INET
,
351 addrstr
, sizeof addrstr
))
352 vty_out(vty
, ", src %s",
356 case NEXTHOP_TYPE_IPV6
:
357 case NEXTHOP_TYPE_IPV6_IFINDEX
:
358 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
360 if (inet_ntop(AF_INET6
,
362 addrstr
, sizeof addrstr
))
363 vty_out(vty
, ", src %s",
372 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
374 /* Label information */
375 if (nexthop
->nh_label
376 && nexthop
->nh_label
->num_labels
) {
377 vty_out(vty
, ", label %s",
379 nexthop
->nh_label
->num_labels
,
380 nexthop
->nh_label
->label
, buf
,
385 vty_out(vty
, ", weight %u", nexthop
->weight
);
393 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
394 struct route_entry
*re
, json_object
*json
,
397 struct nexthop
*nexthop
;
399 char buf
[SRCDEST2STR_BUFFER
];
400 json_object
*json_nexthops
= NULL
;
401 json_object
*json_nexthop
= NULL
;
402 json_object
*json_route
= NULL
;
403 json_object
*json_labels
= NULL
;
406 struct vrf
*vrf
= NULL
;
407 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
408 struct nexthop_group
*nhg
;
410 uptime
= monotime(NULL
);
411 uptime
-= re
->uptime
;
412 tm
= gmtime(&uptime
);
414 /* If showing fib information, use the fib view of the
418 nhg
= rib_active_nhg(re
);
423 json_route
= json_object_new_object();
424 json_nexthops
= json_object_new_array();
426 json_object_string_add(json_route
, "prefix",
427 srcdest_rnode2str(rn
, buf
, sizeof buf
));
428 json_object_string_add(json_route
, "protocol",
429 zebra_route_string(re
->type
));
432 json_object_int_add(json_route
, "instance",
436 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
437 vrf
= vrf_lookup_by_id(re
->vrf_id
);
438 json_object_string_add(json_route
, "vrfName",
442 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
443 json_object_boolean_true_add(json_route
, "selected");
445 if (dest
->selected_fib
== re
)
446 json_object_boolean_true_add(json_route
,
449 json_object_int_add(json_route
, "distance",
451 json_object_int_add(json_route
, "metric", re
->metric
);
453 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
454 json_object_boolean_true_add(json_route
, "installed");
456 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
457 json_object_boolean_true_add(json_route
, "failed");
459 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
460 json_object_boolean_true_add(json_route
, "queued");
463 json_object_int_add(json_route
, "tag", re
->tag
);
466 json_object_int_add(json_route
, "table", re
->table
);
468 json_object_int_add(json_route
, "internalStatus",
470 json_object_int_add(json_route
, "internalFlags",
472 json_object_int_add(json_route
, "internalNextHopNum",
473 nexthop_group_nexthop_num(re
->nhe
->nhg
));
474 json_object_int_add(json_route
, "internalNextHopActiveNum",
475 nexthop_group_active_nexthop_num(
477 if (uptime
< ONE_DAY_SECOND
)
478 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
480 else if (uptime
< ONE_WEEK_SECOND
)
481 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
484 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
485 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
488 json_object_string_add(json_route
, "uptime", buf
);
490 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
491 json_nexthop
= json_object_new_object();
493 json_object_int_add(json_nexthop
, "flags",
496 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
497 json_object_boolean_true_add(json_nexthop
,
500 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
501 json_object_boolean_true_add(json_nexthop
,
504 switch (nexthop
->type
) {
505 case NEXTHOP_TYPE_IPV4
:
506 case NEXTHOP_TYPE_IPV4_IFINDEX
:
507 json_object_string_add(
509 inet_ntoa(nexthop
->gate
.ipv4
));
510 json_object_string_add(json_nexthop
, "afi",
513 if (nexthop
->ifindex
) {
514 json_object_int_add(json_nexthop
,
517 json_object_string_add(
518 json_nexthop
, "interfaceName",
524 case NEXTHOP_TYPE_IPV6
:
525 case NEXTHOP_TYPE_IPV6_IFINDEX
:
526 json_object_string_add(
528 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
530 json_object_string_add(json_nexthop
, "afi",
533 if (nexthop
->ifindex
) {
534 json_object_int_add(json_nexthop
,
537 json_object_string_add(
538 json_nexthop
, "interfaceName",
545 case NEXTHOP_TYPE_IFINDEX
:
546 json_object_boolean_true_add(
547 json_nexthop
, "directlyConnected");
548 json_object_int_add(json_nexthop
,
551 json_object_string_add(
552 json_nexthop
, "interfaceName",
553 ifindex2ifname(nexthop
->ifindex
,
556 case NEXTHOP_TYPE_BLACKHOLE
:
557 json_object_boolean_true_add(json_nexthop
,
559 switch (nexthop
->bh_type
) {
560 case BLACKHOLE_REJECT
:
561 json_object_boolean_true_add(
562 json_nexthop
, "reject");
564 case BLACKHOLE_ADMINPROHIB
:
565 json_object_boolean_true_add(
570 json_object_boolean_true_add(
571 json_nexthop
, "blackhole");
573 case BLACKHOLE_UNSPEC
:
581 if ((nexthop
->vrf_id
!= re
->vrf_id
)
582 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
583 vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
584 json_object_string_add(json_nexthop
, "vrf",
587 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
588 json_object_boolean_true_add(json_nexthop
,
591 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
592 json_object_boolean_true_add(json_nexthop
,
595 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
596 json_object_boolean_true_add(json_nexthop
,
599 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
600 json_object_boolean_true_add(json_nexthop
,
603 switch (nexthop
->type
) {
604 case NEXTHOP_TYPE_IPV4
:
605 case NEXTHOP_TYPE_IPV4_IFINDEX
:
606 if (nexthop
->src
.ipv4
.s_addr
) {
607 if (inet_ntop(AF_INET
,
608 &nexthop
->src
.ipv4
, buf
,
610 json_object_string_add(
611 json_nexthop
, "source",
615 case NEXTHOP_TYPE_IPV6
:
616 case NEXTHOP_TYPE_IPV6_IFINDEX
:
617 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
619 if (inet_ntop(AF_INET6
,
620 &nexthop
->src
.ipv6
, buf
,
622 json_object_string_add(
623 json_nexthop
, "source",
631 if (nexthop
->nh_label
632 && nexthop
->nh_label
->num_labels
) {
633 json_labels
= json_object_new_array();
635 for (int label_index
= 0;
637 < nexthop
->nh_label
->num_labels
;
639 json_object_array_add(
642 nexthop
->nh_label
->label
645 json_object_object_add(json_nexthop
, "labels",
649 json_object_array_add(json_nexthops
, json_nexthop
);
652 json_object_object_add(json_route
, "nexthops", json_nexthops
);
653 json_object_array_add(json
, json_route
);
657 /* Nexthop information. */
658 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
659 if (nexthop
== nhg
->nexthop
) {
660 /* Prefix information. */
661 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
663 len
+= vty_out(vty
, "[%d]", re
->instance
);
666 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
669 re_status_output_char(re
, nexthop
),
670 srcdest_rnode2str(rn
, buf
, sizeof buf
));
672 /* Distance and metric display. */
673 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
674 (re
->distance
|| re
->metric
)) ||
675 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
676 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
679 vty_out(vty
, " %c%*c",
680 re_status_output_char(re
, nexthop
),
681 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
684 switch (nexthop
->type
) {
685 case NEXTHOP_TYPE_IPV4
:
686 case NEXTHOP_TYPE_IPV4_IFINDEX
:
687 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
688 if (nexthop
->ifindex
)
690 ifindex2ifname(nexthop
->ifindex
,
693 case NEXTHOP_TYPE_IPV6
:
694 case NEXTHOP_TYPE_IPV6_IFINDEX
:
695 vty_out(vty
, " via %s",
696 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
698 if (nexthop
->ifindex
)
700 ifindex2ifname(nexthop
->ifindex
,
704 case NEXTHOP_TYPE_IFINDEX
:
705 vty_out(vty
, " is directly connected, %s",
706 ifindex2ifname(nexthop
->ifindex
,
709 case NEXTHOP_TYPE_BLACKHOLE
:
710 vty_out(vty
, " unreachable");
711 switch (nexthop
->bh_type
) {
712 case BLACKHOLE_REJECT
:
713 vty_out(vty
, " (ICMP unreachable)");
715 case BLACKHOLE_ADMINPROHIB
:
716 vty_out(vty
, " (ICMP admin-prohibited)");
719 vty_out(vty
, " (blackhole)");
721 case BLACKHOLE_UNSPEC
:
729 if ((nexthop
->vrf_id
!= re
->vrf_id
)
730 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
731 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
734 vty_out(vty
, "(vrf %s)", vrf
->name
);
736 vty_out(vty
, "(vrf UNKNOWN)");
739 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
740 vty_out(vty
, " inactive");
742 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
743 vty_out(vty
, " onlink");
745 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
746 vty_out(vty
, " (recursive)");
748 switch (nexthop
->type
) {
749 case NEXTHOP_TYPE_IPV4
:
750 case NEXTHOP_TYPE_IPV4_IFINDEX
:
751 if (nexthop
->src
.ipv4
.s_addr
) {
752 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
754 vty_out(vty
, ", src %s", buf
);
757 case NEXTHOP_TYPE_IPV6
:
758 case NEXTHOP_TYPE_IPV6_IFINDEX
:
759 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
760 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
762 vty_out(vty
, ", src %s", buf
);
769 /* Label information */
770 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
771 vty_out(vty
, ", label %s",
772 mpls_label2str(nexthop
->nh_label
->num_labels
,
773 nexthop
->nh_label
->label
, buf
,
777 if (uptime
< ONE_DAY_SECOND
)
778 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
779 tm
->tm_min
, tm
->tm_sec
);
780 else if (uptime
< ONE_WEEK_SECOND
)
781 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
782 tm
->tm_hour
, tm
->tm_min
);
784 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
785 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
791 static void vty_show_ip_route_detail_json(struct vty
*vty
,
792 struct route_node
*rn
, bool use_fib
)
794 json_object
*json
= NULL
;
795 json_object
*json_prefix
= NULL
;
796 struct route_entry
*re
;
800 dest
= rib_dest_from_rnode(rn
);
802 json
= json_object_new_object();
803 json_prefix
= json_object_new_array();
805 RNODE_FOREACH_RE (rn
, re
) {
807 * If re not selected for forwarding, skip re
808 * for "show ip/ipv6 fib <prefix> json"
810 if (use_fib
&& re
!= dest
->selected_fib
)
812 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
815 prefix2str(&rn
->p
, buf
, sizeof(buf
));
816 json_object_object_add(json
, buf
, json_prefix
);
817 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
818 json
, JSON_C_TO_STRING_PRETTY
));
819 json_object_free(json
);
822 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
823 struct route_table
*table
, afi_t afi
,
824 bool use_fib
, route_tag_t tag
,
825 const struct prefix
*longer_prefix_p
,
826 bool supernets_only
, int type
,
827 unsigned short ospf_instance_id
, bool use_json
,
830 struct route_node
*rn
;
831 struct route_entry
*re
;
834 json_object
*json
= NULL
;
835 json_object
*json_prefix
= NULL
;
840 json
= json_object_new_object();
842 /* Show all routes. */
843 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
844 dest
= rib_dest_from_rnode(rn
);
846 RNODE_FOREACH_RE (rn
, re
) {
847 if (use_fib
&& re
!= dest
->selected_fib
)
850 if (tag
&& re
->tag
!= tag
)
854 && !prefix_match(longer_prefix_p
, &rn
->p
))
857 /* This can only be true when the afi is IPv4 */
858 if (supernets_only
) {
859 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
861 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
864 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
867 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
871 if (type
&& re
->type
!= type
)
875 && (re
->type
!= ZEBRA_ROUTE_OSPF
876 || re
->instance
!= ospf_instance_id
))
881 json_prefix
= json_object_new_array();
886 SHOW_ROUTE_V4_HEADER
);
889 SHOW_ROUTE_V6_HEADER
);
891 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
892 vty_out(vty
, "\nVRF %s table %u:\n",
893 zvrf_name(zvrf
), tableid
);
894 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
895 vty_out(vty
, "\nVRF %s:\n",
901 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
905 prefix2str(&rn
->p
, buf
, sizeof(buf
));
906 json_object_object_add(json
, buf
, json_prefix
);
912 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
913 JSON_C_TO_STRING_PRETTY
));
914 json_object_free(json
);
918 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
919 safi_t safi
, bool use_fib
, bool use_json
,
921 const struct prefix
*longer_prefix_p
,
922 bool supernets_only
, int type
,
923 unsigned short ospf_instance_id
)
925 struct route_table
*table
;
926 struct zebra_vrf
*zvrf
= NULL
;
928 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
930 vty_out(vty
, "{}\n");
932 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
936 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
938 vty_out(vty
, "{}\n");
940 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
944 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
947 vty_out(vty
, "{}\n");
951 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
952 longer_prefix_p
, supernets_only
, type
,
953 ospf_instance_id
, use_json
, 0);
958 DEFPY (show_route_table
,
959 show_route_table_cmd
,
960 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
966 "The table number to display, if available\n"
969 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
970 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
971 struct route_table
*t
;
973 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
975 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
976 0, 0, !!json
, table
);
981 DEFPY (show_route_table_vrf
,
982 show_route_table_vrf_cmd
,
983 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
989 "The table number to display, if available\n"
993 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
994 struct zebra_vrf
*zvrf
;
995 struct route_table
*t
;
996 vrf_id_t vrf_id
= VRF_DEFAULT
;
999 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1000 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1002 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
1004 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
1005 0, 0, !!json
, table
);
1010 DEFPY (show_route_all_table_vrf
,
1011 show_route_all_table_vrf_cmd
,
1012 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1016 "IP routing table\n"
1017 "Display all tables\n"
1018 VRF_FULL_CMD_HELP_STR
1021 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1022 struct zebra_vrf
*zvrf
= NULL
;
1023 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1024 struct zebra_router_table
*zrt
;
1027 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1028 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1031 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1032 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1034 if (zvrf
&& zvrf
!= info
->zvrf
)
1036 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1039 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
, false, 0,
1040 false, false, 0, 0, !!json
, zrt
->tableid
);
1047 "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name [<A.B.C.D|X:X::X:X>$addr]|vrf all$vrf_all]",
1051 "IP nexthop tracking table\n"
1052 "IP import check tracking table\n"
1058 VRF_ALL_CMD_HELP_STR
)
1060 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1061 vrf_id_t vrf_id
= VRF_DEFAULT
;
1062 struct prefix prefix
, *p
= NULL
;
1065 if (strcmp(type
, "nht") == 0)
1066 rtype
= RNH_NEXTHOP_TYPE
;
1068 rtype
= RNH_IMPORT_CHECK_TYPE
;
1072 struct zebra_vrf
*zvrf
;
1074 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1075 if ((zvrf
= vrf
->info
) != NULL
) {
1076 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1077 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1083 VRF_GET_ID(vrf_id
, vrf_name
, false);
1085 memset(&prefix
, 0, sizeof(prefix
));
1087 p
= sockunion2hostprefix(addr
, &prefix
);
1089 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1093 DEFUN (ip_nht_default_route
,
1094 ip_nht_default_route_cmd
,
1095 "ip nht resolve-via-default",
1097 "Filter Next Hop tracking route resolution\n"
1098 "Resolve via default route\n")
1100 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1105 if (zvrf
->zebra_rnh_ip_default_route
)
1108 zvrf
->zebra_rnh_ip_default_route
= 1;
1110 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1114 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1116 struct nexthop
*nexthop
= NULL
;
1117 struct nhg_connected
*rb_node_dep
= NULL
;
1118 char buf
[SRCDEST2STR_BUFFER
];
1120 struct vrf
*nhe_vrf
= vrf_lookup_by_id(nhe
->vrf_id
);
1122 vty_out(vty
, "ID: %u\n", nhe
->id
);
1123 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1126 vty_out(vty
, " VRF: %s\n", nhe_vrf
->name
);
1128 vty_out(vty
, " VRF: UNKNOWN\n");
1130 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_UNHASHABLE
))
1131 vty_out(vty
, " Duplicate - from kernel not hashable\n");
1133 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1134 vty_out(vty
, " Valid");
1135 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1136 vty_out(vty
, ", Installed");
1140 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1142 if (!zebra_nhg_depends_is_empty(nhe
)) {
1143 vty_out(vty
, " Depends:");
1144 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1145 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1150 for (ALL_NEXTHOPS_PTR(nhe
->nhg
, nexthop
)) {
1151 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1154 /* Make recursive nexthops a bit more clear */
1157 switch (nexthop
->type
) {
1158 case NEXTHOP_TYPE_IPV4
:
1159 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1160 vty_out(vty
, " %s", inet_ntoa(nexthop
->gate
.ipv4
));
1161 if (nexthop
->ifindex
)
1162 vty_out(vty
, ", %s",
1163 ifindex2ifname(nexthop
->ifindex
,
1166 case NEXTHOP_TYPE_IPV6
:
1167 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1169 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1171 if (nexthop
->ifindex
)
1172 vty_out(vty
, ", %s",
1173 ifindex2ifname(nexthop
->ifindex
,
1177 case NEXTHOP_TYPE_IFINDEX
:
1178 vty_out(vty
, " directly connected %s",
1179 ifindex2ifname(nexthop
->ifindex
,
1182 case NEXTHOP_TYPE_BLACKHOLE
:
1183 vty_out(vty
, " unreachable");
1184 switch (nexthop
->bh_type
) {
1185 case BLACKHOLE_REJECT
:
1186 vty_out(vty
, " (ICMP unreachable)");
1188 case BLACKHOLE_ADMINPROHIB
:
1189 vty_out(vty
, " (ICMP admin-prohibited)");
1191 case BLACKHOLE_NULL
:
1192 vty_out(vty
, " (blackhole)");
1194 case BLACKHOLE_UNSPEC
:
1202 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1205 vty_out(vty
, " (vrf %s)", vrf
->name
);
1207 vty_out(vty
, " (vrf UNKNOWN)");
1209 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1210 vty_out(vty
, " inactive");
1212 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1213 vty_out(vty
, " onlink");
1215 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1216 vty_out(vty
, " (recursive)");
1218 switch (nexthop
->type
) {
1219 case NEXTHOP_TYPE_IPV4
:
1220 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1221 if (nexthop
->src
.ipv4
.s_addr
) {
1222 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1224 vty_out(vty
, ", src %s", buf
);
1227 case NEXTHOP_TYPE_IPV6
:
1228 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1229 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1230 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1232 vty_out(vty
, ", src %s", buf
);
1239 /* Label information */
1240 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1241 vty_out(vty
, ", label %s",
1242 mpls_label2str(nexthop
->nh_label
->num_labels
,
1243 nexthop
->nh_label
->label
, buf
,
1247 if (nexthop
->weight
)
1248 vty_out(vty
, ", weight %u", nexthop
->weight
);
1253 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1254 vty_out(vty
, " Dependents:");
1255 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1257 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1264 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1266 struct nhg_hash_entry
*nhe
= NULL
;
1268 nhe
= zebra_nhg_lookup_id(id
);
1271 show_nexthop_group_out(vty
, nhe
);
1273 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1279 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1280 struct zebra_vrf
*zvrf
, afi_t afi
)
1282 struct list
*list
= hash_to_list(zrouter
.nhgs
);
1283 struct nhg_hash_entry
*nhe
= NULL
;
1284 struct listnode
*node
= NULL
;
1286 for (ALL_LIST_ELEMENTS_RO(list
, node
, nhe
)) {
1288 if (afi
&& nhe
->afi
!= afi
)
1291 if (nhe
->vrf_id
!= zvrf
->vrf
->vrf_id
)
1294 show_nexthop_group_out(vty
, nhe
);
1300 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1302 struct zebra_if
*zebra_if
= NULL
;
1303 struct nhg_connected
*rb_node_dep
= NULL
;
1305 zebra_if
= ifp
->info
;
1307 if (!if_nhg_dependents_is_empty(ifp
)) {
1308 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1310 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1313 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1318 DEFPY (show_interface_nexthop_group
,
1319 show_interface_nexthop_group_cmd
,
1320 "show interface [IFNAME$if_name] nexthop-group",
1322 "Interface status and configuration\n"
1324 "Show Nexthop Groups\n")
1326 struct vrf
*vrf
= NULL
;
1327 struct interface
*ifp
= NULL
;
1330 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1332 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1334 if_nexthop_group_dump_vty(vty
, ifp
);
1338 FOR_ALL_INTERFACES (vrf
, ifp
)
1339 if_nexthop_group_dump_vty(vty
, ifp
);
1345 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1352 DEFPY (show_nexthop_group
,
1353 show_nexthop_group_cmd
,
1354 "show nexthop-group rib <(0-4294967295)$id|[<ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
1356 "Show Nexthop Groups\n"
1358 "Nexthop Group ID\n"
1361 VRF_FULL_CMD_HELP_STR
)
1364 struct zebra_vrf
*zvrf
= NULL
;
1368 return show_nexthop_group_id_cmd_helper(vty
, id
);
1378 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1379 struct zebra_vrf
*zvrf
;
1385 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1386 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1393 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1395 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1398 vty_out(vty
, "VRF %s specified does not exist", vrf_name
);
1402 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1407 DEFUN (no_ip_nht_default_route
,
1408 no_ip_nht_default_route_cmd
,
1409 "no ip nht resolve-via-default",
1412 "Filter Next Hop tracking route resolution\n"
1413 "Resolve via default route\n")
1415 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1420 if (!zvrf
->zebra_rnh_ip_default_route
)
1423 zvrf
->zebra_rnh_ip_default_route
= 0;
1424 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1428 DEFUN (ipv6_nht_default_route
,
1429 ipv6_nht_default_route_cmd
,
1430 "ipv6 nht resolve-via-default",
1432 "Filter Next Hop tracking route resolution\n"
1433 "Resolve via default route\n")
1435 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1440 if (zvrf
->zebra_rnh_ipv6_default_route
)
1443 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1444 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1448 DEFUN (no_ipv6_nht_default_route
,
1449 no_ipv6_nht_default_route_cmd
,
1450 "no ipv6 nht resolve-via-default",
1453 "Filter Next Hop tracking route resolution\n"
1454 "Resolve via default route\n")
1457 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1462 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1465 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1466 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1474 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1477 |A.B.C.D/M$prefix longer-prefixes\
1478 |supernets-only$supernets_only\
1481 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1482 |ospf$type_str (1-65535)$ospf_instance_id\
1484 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1487 |X:X::X:X/M$prefix longer-prefixes\
1489 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1494 "IP forwarding table\n"
1495 "IP routing table\n"
1496 VRF_FULL_CMD_HELP_STR
1497 "Show only routes with tag\n"
1499 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1500 "Show route matching the specified Network/Mask pair only\n"
1501 "Show supernet entries only\n"
1502 FRR_IP_REDIST_HELP_STR_ZEBRA
1503 "Open Shortest Path First (OSPFv2)\n"
1506 "IP forwarding table\n"
1507 "IP routing table\n"
1508 VRF_FULL_CMD_HELP_STR
1509 "Show only routes with tag\n"
1512 "Show route matching the specified Network/Mask pair only\n"
1513 FRR_IP6_REDIST_HELP_STR_ZEBRA
1516 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1521 type
= proto_redistnum(afi
, type_str
);
1523 vty_out(vty
, "Unknown route type\n");
1529 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1530 struct zebra_vrf
*zvrf
;
1531 struct route_table
*table
;
1533 if ((zvrf
= vrf
->info
) == NULL
1534 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1538 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1539 !!json
, tag
, prefix_str
? prefix
: NULL
,
1540 !!supernets_only
, type
, ospf_instance_id
);
1543 vrf_id_t vrf_id
= VRF_DEFAULT
;
1546 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1547 vrf
= vrf_lookup_by_id(vrf_id
);
1548 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1549 !!json
, tag
, prefix_str
? prefix
: NULL
,
1550 !!supernets_only
, type
, ospf_instance_id
);
1556 DEFPY (show_route_detail
,
1557 show_route_detail_cmd
,
1560 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1565 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1571 [json$json] [nexthop-group$ng]",
1574 "IPv6 forwarding table\n"
1575 "IP routing table\n"
1576 VRF_FULL_CMD_HELP_STR
1577 "Network in the IP routing table to display\n"
1578 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1580 "IPv6 forwarding table\n"
1581 "IPv6 routing table\n"
1582 VRF_FULL_CMD_HELP_STR
1586 "Nexthop Group Information\n")
1588 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1589 struct route_table
*table
;
1591 struct route_node
*rn
;
1592 bool use_fib
= !!fib
;
1594 bool network_found
= false;
1595 bool show_ng
= !!ng
;
1598 prefix_str
= address_str
;
1599 if (str2prefix(prefix_str
, &p
) < 0) {
1600 vty_out(vty
, "%% Malformed address\n");
1606 struct zebra_vrf
*zvrf
;
1608 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1609 if ((zvrf
= vrf
->info
) == NULL
1610 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1613 rn
= route_node_match(table
, &p
);
1616 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1617 route_unlock_node(rn
);
1621 dest
= rib_dest_from_rnode(rn
);
1622 if (use_fib
&& !dest
->selected_fib
) {
1623 route_unlock_node(rn
);
1627 network_found
= true;
1629 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1631 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1634 route_unlock_node(rn
);
1637 if (!network_found
) {
1639 vty_out(vty
, "{}\n");
1643 "%% Network not in FIB\n");
1646 "%% Network not in RIB\n");
1651 vrf_id_t vrf_id
= VRF_DEFAULT
;
1654 VRF_GET_ID(vrf_id
, vrf_name
, false);
1656 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1660 rn
= route_node_match(table
, &p
);
1662 dest
= rib_dest_from_rnode(rn
);
1664 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1665 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1667 vty_out(vty
, "{}\n");
1671 "%% Network not in FIB\n");
1674 "%% Network not in table\n");
1677 route_unlock_node(rn
);
1682 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1684 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1686 route_unlock_node(rn
);
1692 DEFPY (show_route_summary
,
1693 show_route_summary_cmd
,
1694 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1695 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
1699 "IP routing table\n"
1700 VRF_FULL_CMD_HELP_STR
1701 "Summary of all routes\n"
1702 "Table to display summary for\n"
1703 "The table number\n"
1707 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1708 struct route_table
*table
;
1709 bool uj
= use_json(argc
, argv
);
1712 table_id
= RT_TABLE_MAIN
;
1716 struct zebra_vrf
*zvrf
;
1718 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1719 if ((zvrf
= vrf
->info
) == NULL
)
1722 table
= zebra_vrf_lookup_table_with_table_id(
1723 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, table_id
);
1729 vty_show_ip_route_summary_prefix(vty
, table
,
1732 vty_show_ip_route_summary(vty
, table
, uj
);
1735 vrf_id_t vrf_id
= VRF_DEFAULT
;
1738 VRF_GET_ID(vrf_id
, vrf_name
, false);
1740 table
= zebra_vrf_lookup_table_with_table_id(afi
, SAFI_UNICAST
,
1746 vty_show_ip_route_summary_prefix(vty
, table
, uj
);
1748 vty_show_ip_route_summary(vty
, table
, uj
);
1754 static void vty_show_ip_route_summary(struct vty
*vty
,
1755 struct route_table
*table
, bool use_json
)
1757 struct route_node
*rn
;
1758 struct route_entry
*re
;
1759 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1760 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1761 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1762 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1765 json_object
*json_route_summary
= NULL
;
1766 json_object
*json_route_routes
= NULL
;
1768 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1769 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1772 json_route_summary
= json_object_new_object();
1773 json_route_routes
= json_object_new_array();
1774 json_object_object_add(json_route_summary
, "routes",
1778 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1779 RNODE_FOREACH_RE (rn
, re
) {
1780 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1781 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1783 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1785 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1787 rib_cnt
[re
->type
]++;
1789 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1790 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1793 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1795 fib_cnt
[re
->type
]++;
1800 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1802 zvrf_name(((rib_table_info_t
*)route_table_get_info(
1806 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1807 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1808 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1809 if (i
== ZEBRA_ROUTE_BGP
) {
1811 json_object
*json_route_ebgp
=
1812 json_object_new_object();
1814 json_object_int_add(
1815 json_route_ebgp
, "fib",
1816 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1817 json_object_int_add(
1818 json_route_ebgp
, "rib",
1819 rib_cnt
[ZEBRA_ROUTE_BGP
]);
1820 json_object_string_add(json_route_ebgp
,
1822 json_object_array_add(json_route_routes
,
1825 json_object
*json_route_ibgp
=
1826 json_object_new_object();
1828 json_object_int_add(
1829 json_route_ibgp
, "fib",
1830 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1831 json_object_int_add(
1832 json_route_ibgp
, "rib",
1833 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1834 json_object_string_add(json_route_ibgp
,
1836 json_object_array_add(json_route_routes
,
1839 vty_out(vty
, "%-20s %-20d %-20d \n",
1841 rib_cnt
[ZEBRA_ROUTE_BGP
],
1842 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1843 vty_out(vty
, "%-20s %-20d %-20d \n",
1845 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1846 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1850 json_object
*json_route_type
=
1851 json_object_new_object();
1853 json_object_int_add(json_route_type
,
1855 json_object_int_add(json_route_type
,
1857 json_object_string_add(
1858 json_route_type
, "type",
1859 zebra_route_string(i
));
1860 json_object_array_add(json_route_routes
,
1863 vty_out(vty
, "%-20s %-20d %-20d \n",
1864 zebra_route_string(i
),
1865 rib_cnt
[i
], fib_cnt
[i
]);
1871 json_object_int_add(json_route_summary
, "routesTotal",
1872 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1873 json_object_int_add(json_route_summary
, "routesTotalFib",
1874 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1876 vty_out(vty
, "%s\n",
1877 json_object_to_json_string_ext(
1878 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
1879 json_object_free(json_route_summary
);
1881 vty_out(vty
, "------\n");
1882 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1883 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1889 * Implementation of the ip route summary prefix command.
1891 * This command prints the primary prefixes that have been installed by various
1892 * protocols on the box.
1895 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1896 struct route_table
*table
,
1899 struct route_node
*rn
;
1900 struct route_entry
*re
;
1901 struct nexthop
*nexthop
;
1902 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1903 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1904 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1905 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1908 json_object
*json_route_summary
= NULL
;
1909 json_object
*json_route_routes
= NULL
;
1911 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1912 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1915 json_route_summary
= json_object_new_object();
1916 json_route_routes
= json_object_new_array();
1917 json_object_object_add(json_route_summary
, "prefixRoutes",
1921 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1922 RNODE_FOREACH_RE (rn
, re
) {
1925 * In case of ECMP, count only once.
1928 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1929 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1930 fib_cnt
[re
->type
]++;
1932 for (nexthop
= re
->nhe
->nhg
->nexthop
; (!cnt
&& nexthop
);
1933 nexthop
= nexthop
->next
) {
1935 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1936 rib_cnt
[re
->type
]++;
1937 if (re
->type
== ZEBRA_ROUTE_BGP
1938 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1939 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1940 if (CHECK_FLAG(re
->status
,
1941 ROUTE_ENTRY_INSTALLED
))
1942 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1948 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1949 "Prefix Routes", "FIB",
1950 zvrf_name(((rib_table_info_t
*)route_table_get_info(
1954 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1955 if (rib_cnt
[i
] > 0) {
1956 if (i
== ZEBRA_ROUTE_BGP
) {
1958 json_object
*json_route_ebgp
=
1959 json_object_new_object();
1961 json_object_int_add(
1962 json_route_ebgp
, "fib",
1963 fib_cnt
[ZEBRA_ROUTE_BGP
]
1964 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1965 json_object_int_add(
1966 json_route_ebgp
, "rib",
1967 rib_cnt
[ZEBRA_ROUTE_BGP
]
1968 - rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1969 json_object_string_add(json_route_ebgp
,
1971 json_object_array_add(json_route_routes
,
1974 json_object
*json_route_ibgp
=
1975 json_object_new_object();
1977 json_object_int_add(
1978 json_route_ibgp
, "fib",
1979 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1980 json_object_int_add(
1981 json_route_ibgp
, "rib",
1982 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1983 json_object_string_add(json_route_ibgp
,
1985 json_object_array_add(json_route_routes
,
1988 vty_out(vty
, "%-20s %-20d %-20d \n",
1990 rib_cnt
[ZEBRA_ROUTE_BGP
]
1991 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1992 fib_cnt
[ZEBRA_ROUTE_BGP
]
1993 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1994 vty_out(vty
, "%-20s %-20d %-20d \n",
1996 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1997 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2001 json_object
*json_route_type
=
2002 json_object_new_object();
2004 json_object_int_add(json_route_type
,
2006 json_object_int_add(json_route_type
,
2008 json_object_string_add(
2009 json_route_type
, "type",
2010 zebra_route_string(i
));
2011 json_object_array_add(json_route_routes
,
2014 vty_out(vty
, "%-20s %-20d %-20d \n",
2015 zebra_route_string(i
),
2016 rib_cnt
[i
], fib_cnt
[i
]);
2022 json_object_int_add(json_route_summary
, "prefixRoutesTotal",
2023 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2024 json_object_int_add(json_route_summary
, "prefixRoutesTotalFib",
2025 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2027 vty_out(vty
, "%s\n",
2028 json_object_to_json_string_ext(
2029 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2030 json_object_free(json_route_summary
);
2032 vty_out(vty
, "------\n");
2033 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2034 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2040 * Show IPv6 mroute command.Used to dump
2041 * the Multicast routing table.
2043 DEFUN (show_ipv6_mroute
,
2044 show_ipv6_mroute_cmd
,
2045 "show ipv6 mroute [vrf NAME]",
2048 "IPv6 Multicast routing table\n"
2051 struct route_table
*table
;
2052 struct route_node
*rn
;
2053 struct route_entry
*re
;
2055 vrf_id_t vrf_id
= VRF_DEFAULT
;
2058 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
2060 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2064 /* Show all IPv6 route. */
2065 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2066 RNODE_FOREACH_RE (rn
, re
) {
2068 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2071 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2076 DEFUN (show_ipv6_mroute_vrf_all
,
2077 show_ipv6_mroute_vrf_all_cmd
,
2078 "show ipv6 mroute vrf all",
2081 "IPv6 Multicast routing table\n"
2082 VRF_ALL_CMD_HELP_STR
)
2084 struct route_table
*table
;
2085 struct route_node
*rn
;
2086 struct route_entry
*re
;
2088 struct zebra_vrf
*zvrf
;
2091 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2092 if ((zvrf
= vrf
->info
) == NULL
2093 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2096 /* Show all IPv6 route. */
2097 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2098 RNODE_FOREACH_RE (rn
, re
) {
2100 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2103 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2109 DEFUN (allow_external_route_update
,
2110 allow_external_route_update_cmd
,
2111 "allow-external-route-update",
2112 "Allow FRR routes to be overwritten by external processes\n")
2119 DEFUN (no_allow_external_route_update
,
2120 no_allow_external_route_update_cmd
,
2121 "no allow-external-route-update",
2123 "Allow FRR routes to be overwritten by external processes\n")
2138 struct zebra_vrf
*zvrf
;
2140 if (vrf_is_backend_netns())
2141 vty_out(vty
, "netns-based vrfs\n");
2143 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2144 if (!(zvrf
= vrf
->info
))
2146 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2149 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2150 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
2151 vty_out(vty
, "inactive");
2152 else if (zvrf_ns_name(zvrf
))
2153 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2154 zvrf_ns_name(zvrf
));
2156 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2158 if (vrf_is_user_cfged(vrf
))
2159 vty_out(vty
, " (configured)");
2166 DEFUN (default_vrf_vni_mapping
,
2167 default_vrf_vni_mapping_cmd
,
2168 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2169 "VNI corresponding to the DEFAULT VRF\n"
2171 "Prefix routes only \n")
2174 char err
[ERR_STR_SZ
];
2175 struct zebra_vrf
*zvrf
= NULL
;
2176 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2179 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2186 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2189 vty_out(vty
, "%s\n", err
);
2196 DEFUN (no_default_vrf_vni_mapping
,
2197 no_default_vrf_vni_mapping_cmd
,
2198 "no vni " CMD_VNI_RANGE
,
2200 "VNI corresponding to DEFAULT VRF\n"
2204 char err
[ERR_STR_SZ
];
2205 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2206 struct zebra_vrf
*zvrf
= NULL
;
2208 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2212 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2214 vty_out(vty
, "%s\n", err
);
2221 DEFUN (vrf_vni_mapping
,
2222 vrf_vni_mapping_cmd
,
2223 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2224 "VNI corresponding to tenant VRF\n"
2226 "prefix-routes-only\n")
2231 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2232 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2233 char err
[ERR_STR_SZ
];
2241 /* Mark as having FRR configuration */
2242 vrf_set_user_cfged(vrf
);
2243 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2246 vty_out(vty
, "%s\n", err
);
2253 DEFUN (no_vrf_vni_mapping
,
2254 no_vrf_vni_mapping_cmd
,
2255 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2257 "VNI corresponding to tenant VRF\n"
2259 "prefix-routes-only\n")
2263 char err
[ERR_STR_SZ
];
2264 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2266 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2274 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2275 ERR_STR_SZ
, filter
, 0);
2277 vty_out(vty
, "%s\n", err
);
2281 /* If no other FRR config for this VRF, mark accordingly. */
2282 if (!zebra_vrf_has_config(zvrf
))
2283 vrf_reset_user_cfged(vrf
);
2289 DEFUN (show_vrf_vni
,
2291 "show vrf vni [json]",
2298 struct zebra_vrf
*zvrf
;
2299 json_object
*json
= NULL
;
2300 json_object
*json_vrfs
= NULL
;
2301 bool uj
= use_json(argc
, argv
);
2304 json
= json_object_new_object();
2305 json_vrfs
= json_object_new_array();
2309 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2310 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2312 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2317 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2321 json_object_object_add(json
, "vrfs", json_vrfs
);
2322 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2323 json
, JSON_C_TO_STRING_PRETTY
));
2324 json_object_free(json
);
2330 DEFUN (show_evpn_global
,
2331 show_evpn_global_cmd
,
2337 bool uj
= use_json(argc
, argv
);
2339 zebra_vxlan_print_evpn(vty
, uj
);
2343 DEFUN (show_evpn_vni
,
2345 "show evpn vni [json]",
2348 "VxLAN Network Identifier\n"
2351 struct zebra_vrf
*zvrf
;
2352 bool uj
= use_json(argc
, argv
);
2354 zvrf
= zebra_vrf_get_evpn();
2355 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2359 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2360 "show evpn vni detail [json]",
2363 "VxLAN Network Identifier\n"
2364 "Detailed Information On Each VNI\n"
2367 struct zebra_vrf
*zvrf
;
2368 bool uj
= use_json(argc
, argv
);
2370 zvrf
= zebra_vrf_get_evpn();
2371 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2375 DEFUN (show_evpn_vni_vni
,
2376 show_evpn_vni_vni_cmd
,
2377 "show evpn vni " CMD_VNI_RANGE
"[json]",
2380 "VxLAN Network Identifier\n"
2384 struct zebra_vrf
*zvrf
;
2386 bool uj
= use_json(argc
, argv
);
2388 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2389 zvrf
= zebra_vrf_get_evpn();
2390 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2394 DEFUN (show_evpn_rmac_vni_mac
,
2395 show_evpn_rmac_vni_mac_cmd
,
2396 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2403 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2408 bool uj
= use_json(argc
, argv
);
2410 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2411 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2412 vty_out(vty
, "%% Malformed MAC address\n");
2415 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2419 DEFUN (show_evpn_rmac_vni
,
2420 show_evpn_rmac_vni_cmd
,
2421 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2430 bool uj
= use_json(argc
, argv
);
2432 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2433 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2438 DEFUN (show_evpn_rmac_vni_all
,
2439 show_evpn_rmac_vni_all_cmd
,
2440 "show evpn rmac vni all [json]",
2448 bool uj
= use_json(argc
, argv
);
2450 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2455 DEFUN (show_evpn_nh_vni_ip
,
2456 show_evpn_nh_vni_ip_cmd
,
2457 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2464 "Host address (ipv4 or ipv6)\n"
2469 bool uj
= use_json(argc
, argv
);
2471 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2472 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2474 vty_out(vty
, "%% Malformed Neighbor address\n");
2477 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2482 DEFUN (show_evpn_nh_vni
,
2483 show_evpn_nh_vni_cmd
,
2484 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2493 bool uj
= use_json(argc
, argv
);
2495 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2496 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2501 DEFUN (show_evpn_nh_vni_all
,
2502 show_evpn_nh_vni_all_cmd
,
2503 "show evpn next-hops vni all [json]",
2511 bool uj
= use_json(argc
, argv
);
2513 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2518 DEFUN (show_evpn_mac_vni
,
2519 show_evpn_mac_vni_cmd
,
2520 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2524 "VxLAN Network Identifier\n"
2528 struct zebra_vrf
*zvrf
;
2530 bool uj
= use_json(argc
, argv
);
2532 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2533 zvrf
= zebra_vrf_get_evpn();
2534 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2538 DEFUN (show_evpn_mac_vni_all
,
2539 show_evpn_mac_vni_all_cmd
,
2540 "show evpn mac vni all [json]",
2544 "VxLAN Network Identifier\n"
2548 struct zebra_vrf
*zvrf
;
2549 bool uj
= use_json(argc
, argv
);
2551 zvrf
= zebra_vrf_get_evpn();
2552 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2556 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2557 "show evpn mac vni all detail [json]",
2561 "VxLAN Network Identifier\n"
2563 "Detailed Information On Each VNI MAC\n"
2566 struct zebra_vrf
*zvrf
;
2567 bool uj
= use_json(argc
, argv
);
2569 zvrf
= zebra_vrf_get_evpn();
2570 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2574 DEFUN (show_evpn_mac_vni_all_vtep
,
2575 show_evpn_mac_vni_all_vtep_cmd
,
2576 "show evpn mac vni all vtep A.B.C.D [json]",
2580 "VxLAN Network Identifier\n"
2583 "Remote VTEP IP address\n"
2586 struct zebra_vrf
*zvrf
;
2587 struct in_addr vtep_ip
;
2588 bool uj
= use_json(argc
, argv
);
2590 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2592 vty_out(vty
, "%% Malformed VTEP IP address\n");
2595 zvrf
= zebra_vrf_get_evpn();
2596 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2602 DEFUN (show_evpn_mac_vni_mac
,
2603 show_evpn_mac_vni_mac_cmd
,
2604 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2608 "VxLAN Network Identifier\n"
2611 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2615 struct zebra_vrf
*zvrf
;
2618 bool uj
= use_json(argc
, argv
);
2620 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2621 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2622 vty_out(vty
, "%% Malformed MAC address");
2625 zvrf
= zebra_vrf_get_evpn();
2626 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2630 DEFUN (show_evpn_mac_vni_vtep
,
2631 show_evpn_mac_vni_vtep_cmd
,
2632 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2636 "VxLAN Network Identifier\n"
2639 "Remote VTEP IP address\n"
2642 struct zebra_vrf
*zvrf
;
2644 struct in_addr vtep_ip
;
2645 bool uj
= use_json(argc
, argv
);
2647 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2648 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2650 vty_out(vty
, "%% Malformed VTEP IP address\n");
2654 zvrf
= zebra_vrf_get_evpn();
2655 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2659 DEFPY (show_evpn_mac_vni_all_dad
,
2660 show_evpn_mac_vni_all_dad_cmd
,
2661 "show evpn mac vni all duplicate [json]",
2665 "VxLAN Network Identifier\n"
2667 "Duplicate address list\n"
2670 struct zebra_vrf
*zvrf
;
2671 bool uj
= use_json(argc
, argv
);
2673 zvrf
= zebra_vrf_get_evpn();
2674 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2679 DEFPY (show_evpn_mac_vni_dad
,
2680 show_evpn_mac_vni_dad_cmd
,
2681 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2685 "VxLAN Network Identifier\n"
2687 "Duplicate address list\n"
2690 struct zebra_vrf
*zvrf
;
2691 bool uj
= use_json(argc
, argv
);
2693 zvrf
= zebra_vrf_get_evpn();
2695 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2700 DEFPY (show_evpn_neigh_vni_dad
,
2701 show_evpn_neigh_vni_dad_cmd
,
2702 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2705 "ARP and ND cache\n"
2706 "VxLAN Network Identifier\n"
2708 "Duplicate address list\n"
2711 struct zebra_vrf
*zvrf
;
2712 bool uj
= use_json(argc
, argv
);
2714 zvrf
= zebra_vrf_get_evpn();
2715 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2719 DEFPY (show_evpn_neigh_vni_all_dad
,
2720 show_evpn_neigh_vni_all_dad_cmd
,
2721 "show evpn arp-cache vni all duplicate [json]",
2724 "ARP and ND cache\n"
2725 "VxLAN Network Identifier\n"
2727 "Duplicate address list\n"
2730 struct zebra_vrf
*zvrf
;
2731 bool uj
= use_json(argc
, argv
);
2733 zvrf
= zebra_vrf_get_evpn();
2734 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2739 DEFUN (show_evpn_neigh_vni
,
2740 show_evpn_neigh_vni_cmd
,
2741 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2744 "ARP and ND cache\n"
2745 "VxLAN Network Identifier\n"
2749 struct zebra_vrf
*zvrf
;
2751 bool uj
= use_json(argc
, argv
);
2753 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2754 zvrf
= zebra_vrf_get_evpn();
2755 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2759 DEFUN (show_evpn_neigh_vni_all
,
2760 show_evpn_neigh_vni_all_cmd
,
2761 "show evpn arp-cache vni all [json]",
2764 "ARP and ND cache\n"
2765 "VxLAN Network Identifier\n"
2769 struct zebra_vrf
*zvrf
;
2770 bool uj
= use_json(argc
, argv
);
2772 zvrf
= zebra_vrf_get_evpn();
2773 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2777 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2778 "show evpn arp-cache vni all detail [json]",
2781 "ARP and ND cache\n"
2782 "VxLAN Network Identifier\n"
2784 "Neighbor details for all vnis in detail\n" JSON_STR
)
2786 struct zebra_vrf
*zvrf
;
2787 bool uj
= use_json(argc
, argv
);
2789 zvrf
= zebra_vrf_get_evpn();
2790 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2794 DEFUN (show_evpn_neigh_vni_neigh
,
2795 show_evpn_neigh_vni_neigh_cmd
,
2796 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2799 "ARP and ND cache\n"
2800 "VxLAN Network Identifier\n"
2803 "Neighbor address (IPv4 or IPv6 address)\n"
2806 struct zebra_vrf
*zvrf
;
2809 bool uj
= use_json(argc
, argv
);
2811 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2812 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2814 vty_out(vty
, "%% Malformed Neighbor address\n");
2817 zvrf
= zebra_vrf_get_evpn();
2818 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2822 DEFUN (show_evpn_neigh_vni_vtep
,
2823 show_evpn_neigh_vni_vtep_cmd
,
2824 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2827 "ARP and ND cache\n"
2828 "VxLAN Network Identifier\n"
2831 "Remote VTEP IP address\n"
2834 struct zebra_vrf
*zvrf
;
2836 struct in_addr vtep_ip
;
2837 bool uj
= use_json(argc
, argv
);
2839 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2840 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2842 vty_out(vty
, "%% Malformed VTEP IP address\n");
2846 zvrf
= zebra_vrf_get_evpn();
2847 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2851 /* policy routing contexts */
2852 DEFUN (show_pbr_ipset
,
2854 "show pbr ipset [WORD]",
2856 "Policy-Based Routing\n"
2857 "IPset Context information\n"
2858 "IPset Name information\n")
2862 found
= argv_find(argv
, argc
, "WORD", &idx
);
2864 zebra_pbr_show_ipset_list(vty
, NULL
);
2866 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2870 /* policy routing contexts */
2871 DEFUN (show_pbr_iptable
,
2872 show_pbr_iptable_cmd
,
2873 "show pbr iptable [WORD]",
2875 "Policy-Based Routing\n"
2876 "IPtable Context information\n"
2877 "IPtable Name information\n")
2882 found
= argv_find(argv
, argc
, "WORD", &idx
);
2884 zebra_pbr_show_iptable(vty
, NULL
);
2886 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2890 DEFPY (clear_evpn_dup_addr
,
2891 clear_evpn_dup_addr_cmd
,
2892 "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>]>",
2895 "Duplicate address \n"
2896 "VxLAN Network Identifier\n"
2900 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2905 struct zebra_vrf
*zvrf
;
2906 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2907 int ret
= CMD_SUCCESS
;
2909 zvrf
= zebra_vrf_get_evpn();
2911 if (!is_zero_mac(&mac
->eth_addr
)) {
2912 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2916 if (sockunion_family(ip
) == AF_INET
) {
2917 host_ip
.ipa_type
= IPADDR_V4
;
2918 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2920 host_ip
.ipa_type
= IPADDR_V6
;
2921 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2922 sizeof(struct in6_addr
));
2924 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2928 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2931 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2937 /* Static ip route configuration write function. */
2938 static int zebra_ip_config(struct vty
*vty
)
2942 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2947 DEFUN (ip_zebra_import_table_distance
,
2948 ip_zebra_import_table_distance_cmd
,
2949 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2951 "import routes from non-main kernel table\n"
2952 "kernel routing table id\n"
2953 "Distance for imported routes\n"
2954 "Default distance value\n"
2955 "route-map for filtering\n"
2958 uint32_t table_id
= 0;
2960 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2961 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2963 strmatch(argv
[argc
- 2]->text
, "route-map")
2964 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2968 if (argc
== 7 || (argc
== 5 && !rmap
))
2969 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2971 if (!is_zebra_valid_kernel_table(table_id
)) {
2973 "Invalid routing table ID, %d. Must be in range 1-252\n",
2976 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2980 if (is_zebra_main_routing_table(table_id
)) {
2982 "Invalid routing table ID, %d. Must be non-default table\n",
2985 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2989 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2992 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2997 DEFUN_HIDDEN (zebra_packet_process
,
2998 zebra_packet_process_cmd
,
2999 "zebra zapi-packets (1-10000)",
3002 "Number of packets to process before relinquishing thread\n")
3004 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3006 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
3007 memory_order_relaxed
);
3012 DEFUN_HIDDEN (no_zebra_packet_process
,
3013 no_zebra_packet_process_cmd
,
3014 "no zebra zapi-packets [(1-10000)]",
3018 "Number of packets to process before relinquishing thread\n")
3020 atomic_store_explicit(&zrouter
.packets_to_process
,
3021 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
3022 memory_order_relaxed
);
3027 DEFUN_HIDDEN (zebra_workqueue_timer
,
3028 zebra_workqueue_timer_cmd
,
3029 "zebra work-queue (0-10000)",
3032 "Time in milliseconds\n")
3034 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3035 zrouter
.ribq
->spec
.hold
= timer
;
3040 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3041 no_zebra_workqueue_timer_cmd
,
3042 "no zebra work-queue [(0-10000)]",
3046 "Time in milliseconds\n")
3048 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3053 DEFUN (no_ip_zebra_import_table
,
3054 no_ip_zebra_import_table_cmd
,
3055 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3058 "import routes from non-main kernel table\n"
3059 "kernel routing table id\n"
3060 "Distance for imported routes\n"
3061 "Default distance value\n"
3062 "route-map for filtering\n"
3065 uint32_t table_id
= 0;
3066 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3068 if (!is_zebra_valid_kernel_table(table_id
)) {
3070 "Invalid routing table ID. Must be in range 1-252\n");
3074 if (is_zebra_main_routing_table(table_id
)) {
3076 "Invalid routing table ID, %d. Must be non-default table\n",
3081 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
3084 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
3087 static int config_write_protocol(struct vty
*vty
)
3090 vty_out(vty
, "allow-external-route-update\n");
3092 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3093 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
3095 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3096 vty_out(vty
, "zebra zapi-packets %u\n",
3097 zrouter
.packets_to_process
);
3099 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3101 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3102 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3103 ipv4_multicast_mode
== MCAST_URIB_ONLY
3105 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3107 : ipv4_multicast_mode
3108 == MCAST_MIX_MRIB_FIRST
3110 : ipv4_multicast_mode
3111 == MCAST_MIX_DISTANCE
3115 /* Include dataplane info */
3116 dplane_config_write_helper(vty
);
3130 " Route Route Neighbor LSP LSP\n");
3132 "VRF Installs Removals Updates Installs Removals\n");
3134 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3135 struct zebra_vrf
*zvrf
= vrf
->info
;
3137 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
3138 " %10" PRIu64
" %10" PRIu64
"\n",
3139 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3140 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3141 zvrf
->lsp_removals
);
3147 DEFUN (ip_forwarding
,
3151 "Turn on IP forwarding\n")
3157 ret
= ipforward_on();
3160 vty_out(vty
, "Can't turn on IP forwarding\n");
3161 return CMD_WARNING_CONFIG_FAILED
;
3167 DEFUN (no_ip_forwarding
,
3168 no_ip_forwarding_cmd
,
3172 "Turn off IP forwarding\n")
3178 ret
= ipforward_off();
3181 vty_out(vty
, "Can't turn off IP forwarding\n");
3182 return CMD_WARNING_CONFIG_FAILED
;
3188 /* Only display ip forwarding is enabled or not. */
3189 DEFUN (show_ip_forwarding
,
3190 show_ip_forwarding_cmd
,
3191 "show ip forwarding",
3194 "IP forwarding status\n")
3201 vty_out(vty
, "IP forwarding is off\n");
3203 vty_out(vty
, "IP forwarding is on\n");
3207 /* Only display ipv6 forwarding is enabled or not. */
3208 DEFUN (show_ipv6_forwarding
,
3209 show_ipv6_forwarding_cmd
,
3210 "show ipv6 forwarding",
3212 "IPv6 information\n"
3213 "Forwarding status\n")
3217 ret
= ipforward_ipv6();
3221 vty_out(vty
, "ipv6 forwarding is unknown\n");
3224 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3227 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3230 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3236 DEFUN (ipv6_forwarding
,
3237 ipv6_forwarding_cmd
,
3240 "Turn on IPv6 forwarding\n")
3244 ret
= ipforward_ipv6();
3246 ret
= ipforward_ipv6_on();
3249 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3250 return CMD_WARNING_CONFIG_FAILED
;
3256 DEFUN (no_ipv6_forwarding
,
3257 no_ipv6_forwarding_cmd
,
3258 "no ipv6 forwarding",
3261 "Turn off IPv6 forwarding\n")
3265 ret
= ipforward_ipv6();
3267 ret
= ipforward_ipv6_off();
3270 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3271 return CMD_WARNING_CONFIG_FAILED
;
3277 /* Display dataplane info */
3278 DEFUN (show_dataplane
,
3280 "show zebra dplane [detailed]",
3283 "Zebra dataplane information\n"
3284 "Detailed output\n")
3287 bool detailed
= false;
3289 if (argv_find(argv
, argc
, "detailed", &idx
))
3292 return dplane_show_helper(vty
, detailed
);
3295 /* Display dataplane providers info */
3296 DEFUN (show_dataplane_providers
,
3297 show_dataplane_providers_cmd
,
3298 "show zebra dplane providers [detailed]",
3301 "Zebra dataplane information\n"
3302 "Zebra dataplane provider information\n"
3303 "Detailed output\n")
3306 bool detailed
= false;
3308 if (argv_find(argv
, argc
, "detailed", &idx
))
3311 return dplane_show_provs_helper(vty
, detailed
);
3314 /* Configure dataplane incoming queue limit */
3315 DEFUN (zebra_dplane_queue_limit
,
3316 zebra_dplane_queue_limit_cmd
,
3317 "zebra dplane limit (0-10000)",
3320 "Limit incoming queued updates\n"
3321 "Number of queued updates\n")
3325 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3327 dplane_set_in_queue_limit(limit
, true);
3332 /* Reset dataplane queue limit to default value */
3333 DEFUN (no_zebra_dplane_queue_limit
,
3334 no_zebra_dplane_queue_limit_cmd
,
3335 "no zebra dplane limit [(0-10000)]",
3339 "Limit incoming queued updates\n"
3340 "Number of queued updates\n")
3342 dplane_set_in_queue_limit(0, false);
3347 DEFUN (zebra_show_routing_tables_summary
,
3348 zebra_show_routing_tables_summary_cmd
,
3349 "show zebra router table summary",
3352 "The Zebra Router Information\n"
3353 "Table Information about this Zebra Router\n"
3354 "Summary Information\n")
3356 zebra_router_show_table_summary(vty
);
3361 /* Table configuration write function. */
3362 static int config_write_table(struct vty
*vty
)
3367 /* IPForwarding configuration write function. */
3368 static int config_write_forwarding(struct vty
*vty
)
3370 /* FIXME: Find better place for that. */
3371 router_id_write(vty
);
3374 vty_out(vty
, "no ip forwarding\n");
3375 if (!ipforward_ipv6())
3376 vty_out(vty
, "no ipv6 forwarding\n");
3377 vty_out(vty
, "!\n");
3381 DEFUN_HIDDEN (show_frr
,
3387 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3388 vty_out(vty
, ".............................7777:..............................................\n");
3389 vty_out(vty
, ".............................777777,............................................\n");
3390 vty_out(vty
, "... .........................77777777,..........................................\n");
3391 vty_out(vty
, "............................=7777777777:........................................\n");
3392 vty_out(vty
, "........................:7777777777777777,......................................\n");
3393 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3394 vty_out(vty
, "...................I7777777777+.................................................\n");
3395 vty_out(vty
, "................,777777777?............ .......................................\n");
3396 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3397 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3398 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3399 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3400 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3401 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3402 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3403 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3404 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3405 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3406 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3407 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3408 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3409 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3410 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3411 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3412 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3413 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3414 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3415 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3416 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3417 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3418 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3419 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3420 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3421 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3422 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3423 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3424 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3425 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3426 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3427 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3428 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3429 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3430 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3431 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3432 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3433 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3434 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3435 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3436 vty_out(vty
, "................................~77777777...............=777777.................\n");
3437 vty_out(vty
, ".....................................:=?I................~777777................\n");
3438 vty_out(vty
, "..........................................................:777777,..............\n");
3439 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3444 /* IP node for static routes. */
3445 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3446 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3447 /* table node for routing tables. */
3448 static struct cmd_node table_node
= {TABLE_NODE
,
3449 "", /* This node has no interface. */
3451 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3452 "", /* This node has no interface. */
3456 void zebra_vty_init(void)
3458 /* Install configuration write function. */
3459 install_node(&table_node
, config_write_table
);
3460 install_node(&forwarding_node
, config_write_forwarding
);
3462 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3463 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3464 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3465 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3467 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3468 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3469 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3472 zebra_route_map_init();
3474 install_node(&ip_node
, zebra_ip_config
);
3475 install_node(&protocol_node
, config_write_protocol
);
3477 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3478 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3480 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3481 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3483 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3484 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3485 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3486 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3487 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3488 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3490 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3491 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3493 install_element(VIEW_NODE
, &show_vrf_cmd
);
3494 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3495 install_element(VIEW_NODE
, &show_route_cmd
);
3496 install_element(VIEW_NODE
, &show_route_table_cmd
);
3497 if (vrf_is_backend_netns())
3498 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3499 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3500 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3501 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3502 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3504 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3505 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3507 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3508 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3509 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3510 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3511 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3512 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3513 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3514 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3515 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3517 /* Commands for VRF */
3518 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3520 install_element(VIEW_NODE
, &show_frr_cmd
);
3521 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3522 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3523 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3524 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3525 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3526 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3527 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3528 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3529 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3530 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3531 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3532 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3533 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3534 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3535 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3536 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3537 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3538 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3539 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3540 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3541 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3542 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3543 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3544 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3545 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3546 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3548 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3549 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3551 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3552 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3553 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3554 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3556 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3557 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3558 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3559 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3561 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);