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 <(0-4294967295)$id|[<ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
1356 "Show Nexthop Groups\n"
1357 "Nexthop Group ID\n"
1360 VRF_FULL_CMD_HELP_STR
)
1363 struct zebra_vrf
*zvrf
= NULL
;
1367 return show_nexthop_group_id_cmd_helper(vty
, id
);
1377 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1378 struct zebra_vrf
*zvrf
;
1384 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1385 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1392 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1394 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1397 vty_out(vty
, "VRF %s specified does not exist", vrf_name
);
1401 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1406 DEFUN (no_ip_nht_default_route
,
1407 no_ip_nht_default_route_cmd
,
1408 "no ip nht resolve-via-default",
1411 "Filter Next Hop tracking route resolution\n"
1412 "Resolve via default route\n")
1414 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1419 if (!zvrf
->zebra_rnh_ip_default_route
)
1422 zvrf
->zebra_rnh_ip_default_route
= 0;
1423 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1427 DEFUN (ipv6_nht_default_route
,
1428 ipv6_nht_default_route_cmd
,
1429 "ipv6 nht resolve-via-default",
1431 "Filter Next Hop tracking route resolution\n"
1432 "Resolve via default route\n")
1434 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1439 if (zvrf
->zebra_rnh_ipv6_default_route
)
1442 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1443 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1447 DEFUN (no_ipv6_nht_default_route
,
1448 no_ipv6_nht_default_route_cmd
,
1449 "no ipv6 nht resolve-via-default",
1452 "Filter Next Hop tracking route resolution\n"
1453 "Resolve via default route\n")
1456 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1461 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1464 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1465 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1473 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1476 |A.B.C.D/M$prefix longer-prefixes\
1477 |supernets-only$supernets_only\
1480 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1481 |ospf$type_str (1-65535)$ospf_instance_id\
1483 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1486 |X:X::X:X/M$prefix longer-prefixes\
1488 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1493 "IP forwarding table\n"
1494 "IP routing table\n"
1495 VRF_FULL_CMD_HELP_STR
1496 "Show only routes with tag\n"
1498 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1499 "Show route matching the specified Network/Mask pair only\n"
1500 "Show supernet entries only\n"
1501 FRR_IP_REDIST_HELP_STR_ZEBRA
1502 "Open Shortest Path First (OSPFv2)\n"
1505 "IP forwarding table\n"
1506 "IP routing table\n"
1507 VRF_FULL_CMD_HELP_STR
1508 "Show only routes with tag\n"
1511 "Show route matching the specified Network/Mask pair only\n"
1512 FRR_IP6_REDIST_HELP_STR_ZEBRA
1515 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1520 type
= proto_redistnum(afi
, type_str
);
1522 vty_out(vty
, "Unknown route type\n");
1528 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1529 struct zebra_vrf
*zvrf
;
1530 struct route_table
*table
;
1532 if ((zvrf
= vrf
->info
) == NULL
1533 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1537 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1538 !!json
, tag
, prefix_str
? prefix
: NULL
,
1539 !!supernets_only
, type
, ospf_instance_id
);
1542 vrf_id_t vrf_id
= VRF_DEFAULT
;
1545 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1546 vrf
= vrf_lookup_by_id(vrf_id
);
1547 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1548 !!json
, tag
, prefix_str
? prefix
: NULL
,
1549 !!supernets_only
, type
, ospf_instance_id
);
1555 DEFPY (show_route_detail
,
1556 show_route_detail_cmd
,
1559 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1564 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1570 [json$json] [nexthop-group$ng]",
1573 "IPv6 forwarding table\n"
1574 "IP routing table\n"
1575 VRF_FULL_CMD_HELP_STR
1576 "Network in the IP routing table to display\n"
1577 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1579 "IPv6 forwarding table\n"
1580 "IPv6 routing table\n"
1581 VRF_FULL_CMD_HELP_STR
1585 "Nexthop Group Information\n")
1587 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1588 struct route_table
*table
;
1590 struct route_node
*rn
;
1591 bool use_fib
= !!fib
;
1593 bool network_found
= false;
1594 bool show_ng
= !!ng
;
1597 prefix_str
= address_str
;
1598 if (str2prefix(prefix_str
, &p
) < 0) {
1599 vty_out(vty
, "%% Malformed address\n");
1605 struct zebra_vrf
*zvrf
;
1607 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1608 if ((zvrf
= vrf
->info
) == NULL
1609 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1612 rn
= route_node_match(table
, &p
);
1615 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1616 route_unlock_node(rn
);
1620 dest
= rib_dest_from_rnode(rn
);
1621 if (use_fib
&& !dest
->selected_fib
) {
1622 route_unlock_node(rn
);
1626 network_found
= true;
1628 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1630 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1633 route_unlock_node(rn
);
1636 if (!network_found
) {
1638 vty_out(vty
, "{}\n");
1642 "%% Network not in FIB\n");
1645 "%% Network not in RIB\n");
1650 vrf_id_t vrf_id
= VRF_DEFAULT
;
1653 VRF_GET_ID(vrf_id
, vrf_name
, false);
1655 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1659 rn
= route_node_match(table
, &p
);
1661 dest
= rib_dest_from_rnode(rn
);
1663 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1664 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1666 vty_out(vty
, "{}\n");
1670 "%% Network not in FIB\n");
1673 "%% Network not in table\n");
1676 route_unlock_node(rn
);
1681 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1683 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1685 route_unlock_node(rn
);
1691 DEFPY (show_route_summary
,
1692 show_route_summary_cmd
,
1693 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1694 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
1698 "IP routing table\n"
1699 VRF_FULL_CMD_HELP_STR
1700 "Summary of all routes\n"
1701 "Table to display summary for\n"
1702 "The table number\n"
1706 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1707 struct route_table
*table
;
1708 bool uj
= use_json(argc
, argv
);
1711 table_id
= RT_TABLE_MAIN
;
1715 struct zebra_vrf
*zvrf
;
1717 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1718 if ((zvrf
= vrf
->info
) == NULL
)
1721 table
= zebra_vrf_lookup_table_with_table_id(
1722 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, table_id
);
1728 vty_show_ip_route_summary_prefix(vty
, table
,
1731 vty_show_ip_route_summary(vty
, table
, uj
);
1734 vrf_id_t vrf_id
= VRF_DEFAULT
;
1737 VRF_GET_ID(vrf_id
, vrf_name
, false);
1739 table
= zebra_vrf_lookup_table_with_table_id(afi
, SAFI_UNICAST
,
1745 vty_show_ip_route_summary_prefix(vty
, table
, uj
);
1747 vty_show_ip_route_summary(vty
, table
, uj
);
1753 static void vty_show_ip_route_summary(struct vty
*vty
,
1754 struct route_table
*table
, bool use_json
)
1756 struct route_node
*rn
;
1757 struct route_entry
*re
;
1758 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1759 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1760 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1761 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1764 json_object
*json_route_summary
= NULL
;
1765 json_object
*json_route_routes
= NULL
;
1767 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1768 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1771 json_route_summary
= json_object_new_object();
1772 json_route_routes
= json_object_new_array();
1773 json_object_object_add(json_route_summary
, "routes",
1777 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1778 RNODE_FOREACH_RE (rn
, re
) {
1779 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1780 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1782 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1784 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1786 rib_cnt
[re
->type
]++;
1788 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1789 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1792 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1794 fib_cnt
[re
->type
]++;
1799 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1801 zvrf_name(((rib_table_info_t
*)route_table_get_info(
1805 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1806 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1807 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1808 if (i
== ZEBRA_ROUTE_BGP
) {
1810 json_object
*json_route_ebgp
=
1811 json_object_new_object();
1813 json_object_int_add(
1814 json_route_ebgp
, "fib",
1815 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1816 json_object_int_add(
1817 json_route_ebgp
, "rib",
1818 rib_cnt
[ZEBRA_ROUTE_BGP
]);
1819 json_object_string_add(json_route_ebgp
,
1821 json_object_array_add(json_route_routes
,
1824 json_object
*json_route_ibgp
=
1825 json_object_new_object();
1827 json_object_int_add(
1828 json_route_ibgp
, "fib",
1829 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1830 json_object_int_add(
1831 json_route_ibgp
, "rib",
1832 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1833 json_object_string_add(json_route_ibgp
,
1835 json_object_array_add(json_route_routes
,
1838 vty_out(vty
, "%-20s %-20d %-20d \n",
1840 rib_cnt
[ZEBRA_ROUTE_BGP
],
1841 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1842 vty_out(vty
, "%-20s %-20d %-20d \n",
1844 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1845 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1849 json_object
*json_route_type
=
1850 json_object_new_object();
1852 json_object_int_add(json_route_type
,
1854 json_object_int_add(json_route_type
,
1856 json_object_string_add(
1857 json_route_type
, "type",
1858 zebra_route_string(i
));
1859 json_object_array_add(json_route_routes
,
1862 vty_out(vty
, "%-20s %-20d %-20d \n",
1863 zebra_route_string(i
),
1864 rib_cnt
[i
], fib_cnt
[i
]);
1870 json_object_int_add(json_route_summary
, "routesTotal",
1871 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1872 json_object_int_add(json_route_summary
, "routesTotalFib",
1873 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1875 vty_out(vty
, "%s\n",
1876 json_object_to_json_string_ext(
1877 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
1878 json_object_free(json_route_summary
);
1880 vty_out(vty
, "------\n");
1881 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1882 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1888 * Implementation of the ip route summary prefix command.
1890 * This command prints the primary prefixes that have been installed by various
1891 * protocols on the box.
1894 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1895 struct route_table
*table
,
1898 struct route_node
*rn
;
1899 struct route_entry
*re
;
1900 struct nexthop
*nexthop
;
1901 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1902 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1903 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1904 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1907 json_object
*json_route_summary
= NULL
;
1908 json_object
*json_route_routes
= NULL
;
1910 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1911 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1914 json_route_summary
= json_object_new_object();
1915 json_route_routes
= json_object_new_array();
1916 json_object_object_add(json_route_summary
, "prefixRoutes",
1920 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1921 RNODE_FOREACH_RE (rn
, re
) {
1924 * In case of ECMP, count only once.
1927 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1928 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1929 fib_cnt
[re
->type
]++;
1931 for (nexthop
= re
->nhe
->nhg
->nexthop
; (!cnt
&& nexthop
);
1932 nexthop
= nexthop
->next
) {
1934 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1935 rib_cnt
[re
->type
]++;
1936 if (re
->type
== ZEBRA_ROUTE_BGP
1937 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1938 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1939 if (CHECK_FLAG(re
->status
,
1940 ROUTE_ENTRY_INSTALLED
))
1941 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1947 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1948 "Prefix Routes", "FIB",
1949 zvrf_name(((rib_table_info_t
*)route_table_get_info(
1953 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1954 if (rib_cnt
[i
] > 0) {
1955 if (i
== ZEBRA_ROUTE_BGP
) {
1957 json_object
*json_route_ebgp
=
1958 json_object_new_object();
1960 json_object_int_add(
1961 json_route_ebgp
, "fib",
1962 fib_cnt
[ZEBRA_ROUTE_BGP
]
1963 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1964 json_object_int_add(
1965 json_route_ebgp
, "rib",
1966 rib_cnt
[ZEBRA_ROUTE_BGP
]
1967 - rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1968 json_object_string_add(json_route_ebgp
,
1970 json_object_array_add(json_route_routes
,
1973 json_object
*json_route_ibgp
=
1974 json_object_new_object();
1976 json_object_int_add(
1977 json_route_ibgp
, "fib",
1978 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1979 json_object_int_add(
1980 json_route_ibgp
, "rib",
1981 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
1982 json_object_string_add(json_route_ibgp
,
1984 json_object_array_add(json_route_routes
,
1987 vty_out(vty
, "%-20s %-20d %-20d \n",
1989 rib_cnt
[ZEBRA_ROUTE_BGP
]
1990 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1991 fib_cnt
[ZEBRA_ROUTE_BGP
]
1992 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1993 vty_out(vty
, "%-20s %-20d %-20d \n",
1995 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1996 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2000 json_object
*json_route_type
=
2001 json_object_new_object();
2003 json_object_int_add(json_route_type
,
2005 json_object_int_add(json_route_type
,
2007 json_object_string_add(
2008 json_route_type
, "type",
2009 zebra_route_string(i
));
2010 json_object_array_add(json_route_routes
,
2013 vty_out(vty
, "%-20s %-20d %-20d \n",
2014 zebra_route_string(i
),
2015 rib_cnt
[i
], fib_cnt
[i
]);
2021 json_object_int_add(json_route_summary
, "prefixRoutesTotal",
2022 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2023 json_object_int_add(json_route_summary
, "prefixRoutesTotalFib",
2024 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2026 vty_out(vty
, "%s\n",
2027 json_object_to_json_string_ext(
2028 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2029 json_object_free(json_route_summary
);
2031 vty_out(vty
, "------\n");
2032 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2033 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2039 * Show IPv6 mroute command.Used to dump
2040 * the Multicast routing table.
2042 DEFUN (show_ipv6_mroute
,
2043 show_ipv6_mroute_cmd
,
2044 "show ipv6 mroute [vrf NAME]",
2047 "IPv6 Multicast routing table\n"
2050 struct route_table
*table
;
2051 struct route_node
*rn
;
2052 struct route_entry
*re
;
2054 vrf_id_t vrf_id
= VRF_DEFAULT
;
2057 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
2059 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2063 /* Show all IPv6 route. */
2064 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2065 RNODE_FOREACH_RE (rn
, re
) {
2067 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2070 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2075 DEFUN (show_ipv6_mroute_vrf_all
,
2076 show_ipv6_mroute_vrf_all_cmd
,
2077 "show ipv6 mroute vrf all",
2080 "IPv6 Multicast routing table\n"
2081 VRF_ALL_CMD_HELP_STR
)
2083 struct route_table
*table
;
2084 struct route_node
*rn
;
2085 struct route_entry
*re
;
2087 struct zebra_vrf
*zvrf
;
2090 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2091 if ((zvrf
= vrf
->info
) == NULL
2092 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2095 /* Show all IPv6 route. */
2096 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2097 RNODE_FOREACH_RE (rn
, re
) {
2099 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2102 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2108 DEFUN (allow_external_route_update
,
2109 allow_external_route_update_cmd
,
2110 "allow-external-route-update",
2111 "Allow FRR routes to be overwritten by external processes\n")
2118 DEFUN (no_allow_external_route_update
,
2119 no_allow_external_route_update_cmd
,
2120 "no allow-external-route-update",
2122 "Allow FRR routes to be overwritten by external processes\n")
2137 struct zebra_vrf
*zvrf
;
2139 if (vrf_is_backend_netns())
2140 vty_out(vty
, "netns-based vrfs\n");
2142 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2143 if (!(zvrf
= vrf
->info
))
2145 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2148 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2149 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
2150 vty_out(vty
, "inactive");
2151 else if (zvrf_ns_name(zvrf
))
2152 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2153 zvrf_ns_name(zvrf
));
2155 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2157 if (vrf_is_user_cfged(vrf
))
2158 vty_out(vty
, " (configured)");
2165 DEFUN (default_vrf_vni_mapping
,
2166 default_vrf_vni_mapping_cmd
,
2167 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2168 "VNI corresponding to the DEFAULT VRF\n"
2170 "Prefix routes only \n")
2173 char err
[ERR_STR_SZ
];
2174 struct zebra_vrf
*zvrf
= NULL
;
2175 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2178 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2185 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2188 vty_out(vty
, "%s\n", err
);
2195 DEFUN (no_default_vrf_vni_mapping
,
2196 no_default_vrf_vni_mapping_cmd
,
2197 "no vni " CMD_VNI_RANGE
,
2199 "VNI corresponding to DEFAULT VRF\n"
2203 char err
[ERR_STR_SZ
];
2204 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2205 struct zebra_vrf
*zvrf
= NULL
;
2207 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2211 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2213 vty_out(vty
, "%s\n", err
);
2220 DEFUN (vrf_vni_mapping
,
2221 vrf_vni_mapping_cmd
,
2222 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2223 "VNI corresponding to tenant VRF\n"
2225 "prefix-routes-only\n")
2230 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2231 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2232 char err
[ERR_STR_SZ
];
2240 /* Mark as having FRR configuration */
2241 vrf_set_user_cfged(vrf
);
2242 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2245 vty_out(vty
, "%s\n", err
);
2252 DEFUN (no_vrf_vni_mapping
,
2253 no_vrf_vni_mapping_cmd
,
2254 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2256 "VNI corresponding to tenant VRF\n"
2258 "prefix-routes-only\n")
2262 char err
[ERR_STR_SZ
];
2263 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2265 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2273 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2274 ERR_STR_SZ
, filter
, 0);
2276 vty_out(vty
, "%s\n", err
);
2280 /* If no other FRR config for this VRF, mark accordingly. */
2281 if (!zebra_vrf_has_config(zvrf
))
2282 vrf_reset_user_cfged(vrf
);
2288 DEFUN (show_vrf_vni
,
2290 "show vrf vni [json]",
2297 struct zebra_vrf
*zvrf
;
2298 json_object
*json
= NULL
;
2299 json_object
*json_vrfs
= NULL
;
2300 bool uj
= use_json(argc
, argv
);
2303 json
= json_object_new_object();
2304 json_vrfs
= json_object_new_array();
2308 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2309 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2311 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2316 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2320 json_object_object_add(json
, "vrfs", json_vrfs
);
2321 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2322 json
, JSON_C_TO_STRING_PRETTY
));
2323 json_object_free(json
);
2329 DEFUN (show_evpn_global
,
2330 show_evpn_global_cmd
,
2336 bool uj
= use_json(argc
, argv
);
2338 zebra_vxlan_print_evpn(vty
, uj
);
2342 DEFUN (show_evpn_vni
,
2344 "show evpn vni [json]",
2347 "VxLAN Network Identifier\n"
2350 struct zebra_vrf
*zvrf
;
2351 bool uj
= use_json(argc
, argv
);
2353 zvrf
= zebra_vrf_get_evpn();
2354 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2358 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2359 "show evpn vni detail [json]",
2362 "VxLAN Network Identifier\n"
2363 "Detailed Information On Each VNI\n"
2366 struct zebra_vrf
*zvrf
;
2367 bool uj
= use_json(argc
, argv
);
2369 zvrf
= zebra_vrf_get_evpn();
2370 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2374 DEFUN (show_evpn_vni_vni
,
2375 show_evpn_vni_vni_cmd
,
2376 "show evpn vni " CMD_VNI_RANGE
"[json]",
2379 "VxLAN Network Identifier\n"
2383 struct zebra_vrf
*zvrf
;
2385 bool uj
= use_json(argc
, argv
);
2387 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2388 zvrf
= zebra_vrf_get_evpn();
2389 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2393 DEFUN (show_evpn_rmac_vni_mac
,
2394 show_evpn_rmac_vni_mac_cmd
,
2395 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2402 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2407 bool uj
= use_json(argc
, argv
);
2409 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2410 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2411 vty_out(vty
, "%% Malformed MAC address\n");
2414 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2418 DEFUN (show_evpn_rmac_vni
,
2419 show_evpn_rmac_vni_cmd
,
2420 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2429 bool uj
= use_json(argc
, argv
);
2431 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2432 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2437 DEFUN (show_evpn_rmac_vni_all
,
2438 show_evpn_rmac_vni_all_cmd
,
2439 "show evpn rmac vni all [json]",
2447 bool uj
= use_json(argc
, argv
);
2449 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2454 DEFUN (show_evpn_nh_vni_ip
,
2455 show_evpn_nh_vni_ip_cmd
,
2456 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2463 "Host address (ipv4 or ipv6)\n"
2468 bool uj
= use_json(argc
, argv
);
2470 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2471 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2473 vty_out(vty
, "%% Malformed Neighbor address\n");
2476 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2481 DEFUN (show_evpn_nh_vni
,
2482 show_evpn_nh_vni_cmd
,
2483 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2492 bool uj
= use_json(argc
, argv
);
2494 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2495 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2500 DEFUN (show_evpn_nh_vni_all
,
2501 show_evpn_nh_vni_all_cmd
,
2502 "show evpn next-hops vni all [json]",
2510 bool uj
= use_json(argc
, argv
);
2512 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2517 DEFUN (show_evpn_mac_vni
,
2518 show_evpn_mac_vni_cmd
,
2519 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2523 "VxLAN Network Identifier\n"
2527 struct zebra_vrf
*zvrf
;
2529 bool uj
= use_json(argc
, argv
);
2531 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2532 zvrf
= zebra_vrf_get_evpn();
2533 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2537 DEFUN (show_evpn_mac_vni_all
,
2538 show_evpn_mac_vni_all_cmd
,
2539 "show evpn mac vni all [json]",
2543 "VxLAN Network Identifier\n"
2547 struct zebra_vrf
*zvrf
;
2548 bool uj
= use_json(argc
, argv
);
2550 zvrf
= zebra_vrf_get_evpn();
2551 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2555 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2556 "show evpn mac vni all detail [json]",
2560 "VxLAN Network Identifier\n"
2562 "Detailed Information On Each VNI MAC\n"
2565 struct zebra_vrf
*zvrf
;
2566 bool uj
= use_json(argc
, argv
);
2568 zvrf
= zebra_vrf_get_evpn();
2569 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2573 DEFUN (show_evpn_mac_vni_all_vtep
,
2574 show_evpn_mac_vni_all_vtep_cmd
,
2575 "show evpn mac vni all vtep A.B.C.D [json]",
2579 "VxLAN Network Identifier\n"
2582 "Remote VTEP IP address\n"
2585 struct zebra_vrf
*zvrf
;
2586 struct in_addr vtep_ip
;
2587 bool uj
= use_json(argc
, argv
);
2589 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2591 vty_out(vty
, "%% Malformed VTEP IP address\n");
2594 zvrf
= zebra_vrf_get_evpn();
2595 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2601 DEFUN (show_evpn_mac_vni_mac
,
2602 show_evpn_mac_vni_mac_cmd
,
2603 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2607 "VxLAN Network Identifier\n"
2610 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2614 struct zebra_vrf
*zvrf
;
2617 bool uj
= use_json(argc
, argv
);
2619 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2620 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2621 vty_out(vty
, "%% Malformed MAC address");
2624 zvrf
= zebra_vrf_get_evpn();
2625 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2629 DEFUN (show_evpn_mac_vni_vtep
,
2630 show_evpn_mac_vni_vtep_cmd
,
2631 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2635 "VxLAN Network Identifier\n"
2638 "Remote VTEP IP address\n"
2641 struct zebra_vrf
*zvrf
;
2643 struct in_addr vtep_ip
;
2644 bool uj
= use_json(argc
, argv
);
2646 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2647 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2649 vty_out(vty
, "%% Malformed VTEP IP address\n");
2653 zvrf
= zebra_vrf_get_evpn();
2654 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2658 DEFPY (show_evpn_mac_vni_all_dad
,
2659 show_evpn_mac_vni_all_dad_cmd
,
2660 "show evpn mac vni all duplicate [json]",
2664 "VxLAN Network Identifier\n"
2666 "Duplicate address list\n"
2669 struct zebra_vrf
*zvrf
;
2670 bool uj
= use_json(argc
, argv
);
2672 zvrf
= zebra_vrf_get_evpn();
2673 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2678 DEFPY (show_evpn_mac_vni_dad
,
2679 show_evpn_mac_vni_dad_cmd
,
2680 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2684 "VxLAN Network Identifier\n"
2686 "Duplicate address list\n"
2689 struct zebra_vrf
*zvrf
;
2690 bool uj
= use_json(argc
, argv
);
2692 zvrf
= zebra_vrf_get_evpn();
2694 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2699 DEFPY (show_evpn_neigh_vni_dad
,
2700 show_evpn_neigh_vni_dad_cmd
,
2701 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2704 "ARP and ND cache\n"
2705 "VxLAN Network Identifier\n"
2707 "Duplicate address list\n"
2710 struct zebra_vrf
*zvrf
;
2711 bool uj
= use_json(argc
, argv
);
2713 zvrf
= zebra_vrf_get_evpn();
2714 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2718 DEFPY (show_evpn_neigh_vni_all_dad
,
2719 show_evpn_neigh_vni_all_dad_cmd
,
2720 "show evpn arp-cache vni all duplicate [json]",
2723 "ARP and ND cache\n"
2724 "VxLAN Network Identifier\n"
2726 "Duplicate address list\n"
2729 struct zebra_vrf
*zvrf
;
2730 bool uj
= use_json(argc
, argv
);
2732 zvrf
= zebra_vrf_get_evpn();
2733 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2738 DEFUN (show_evpn_neigh_vni
,
2739 show_evpn_neigh_vni_cmd
,
2740 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2743 "ARP and ND cache\n"
2744 "VxLAN Network Identifier\n"
2748 struct zebra_vrf
*zvrf
;
2750 bool uj
= use_json(argc
, argv
);
2752 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2753 zvrf
= zebra_vrf_get_evpn();
2754 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2758 DEFUN (show_evpn_neigh_vni_all
,
2759 show_evpn_neigh_vni_all_cmd
,
2760 "show evpn arp-cache vni all [json]",
2763 "ARP and ND cache\n"
2764 "VxLAN Network Identifier\n"
2768 struct zebra_vrf
*zvrf
;
2769 bool uj
= use_json(argc
, argv
);
2771 zvrf
= zebra_vrf_get_evpn();
2772 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2776 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2777 "show evpn arp-cache vni all detail [json]",
2780 "ARP and ND cache\n"
2781 "VxLAN Network Identifier\n"
2783 "Neighbor details for all vnis in detail\n" JSON_STR
)
2785 struct zebra_vrf
*zvrf
;
2786 bool uj
= use_json(argc
, argv
);
2788 zvrf
= zebra_vrf_get_evpn();
2789 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2793 DEFUN (show_evpn_neigh_vni_neigh
,
2794 show_evpn_neigh_vni_neigh_cmd
,
2795 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2798 "ARP and ND cache\n"
2799 "VxLAN Network Identifier\n"
2802 "Neighbor address (IPv4 or IPv6 address)\n"
2805 struct zebra_vrf
*zvrf
;
2808 bool uj
= use_json(argc
, argv
);
2810 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2811 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2813 vty_out(vty
, "%% Malformed Neighbor address\n");
2816 zvrf
= zebra_vrf_get_evpn();
2817 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2821 DEFUN (show_evpn_neigh_vni_vtep
,
2822 show_evpn_neigh_vni_vtep_cmd
,
2823 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2826 "ARP and ND cache\n"
2827 "VxLAN Network Identifier\n"
2830 "Remote VTEP IP address\n"
2833 struct zebra_vrf
*zvrf
;
2835 struct in_addr vtep_ip
;
2836 bool uj
= use_json(argc
, argv
);
2838 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2839 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2841 vty_out(vty
, "%% Malformed VTEP IP address\n");
2845 zvrf
= zebra_vrf_get_evpn();
2846 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2850 /* policy routing contexts */
2851 DEFUN (show_pbr_ipset
,
2853 "show pbr ipset [WORD]",
2855 "Policy-Based Routing\n"
2856 "IPset Context information\n"
2857 "IPset Name information\n")
2861 found
= argv_find(argv
, argc
, "WORD", &idx
);
2863 zebra_pbr_show_ipset_list(vty
, NULL
);
2865 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2869 /* policy routing contexts */
2870 DEFUN (show_pbr_iptable
,
2871 show_pbr_iptable_cmd
,
2872 "show pbr iptable [WORD]",
2874 "Policy-Based Routing\n"
2875 "IPtable Context information\n"
2876 "IPtable Name information\n")
2881 found
= argv_find(argv
, argc
, "WORD", &idx
);
2883 zebra_pbr_show_iptable(vty
, NULL
);
2885 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2889 DEFPY (clear_evpn_dup_addr
,
2890 clear_evpn_dup_addr_cmd
,
2891 "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>]>",
2894 "Duplicate address \n"
2895 "VxLAN Network Identifier\n"
2899 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2904 struct zebra_vrf
*zvrf
;
2905 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2906 int ret
= CMD_SUCCESS
;
2908 zvrf
= zebra_vrf_get_evpn();
2910 if (!is_zero_mac(&mac
->eth_addr
)) {
2911 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2915 if (sockunion_family(ip
) == AF_INET
) {
2916 host_ip
.ipa_type
= IPADDR_V4
;
2917 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2919 host_ip
.ipa_type
= IPADDR_V6
;
2920 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2921 sizeof(struct in6_addr
));
2923 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2927 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2930 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2936 /* Static ip route configuration write function. */
2937 static int zebra_ip_config(struct vty
*vty
)
2941 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2946 DEFUN (ip_zebra_import_table_distance
,
2947 ip_zebra_import_table_distance_cmd
,
2948 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2950 "import routes from non-main kernel table\n"
2951 "kernel routing table id\n"
2952 "Distance for imported routes\n"
2953 "Default distance value\n"
2954 "route-map for filtering\n"
2957 uint32_t table_id
= 0;
2959 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2960 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2962 strmatch(argv
[argc
- 2]->text
, "route-map")
2963 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2967 if (argc
== 7 || (argc
== 5 && !rmap
))
2968 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2970 if (!is_zebra_valid_kernel_table(table_id
)) {
2972 "Invalid routing table ID, %d. Must be in range 1-252\n",
2975 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2979 if (is_zebra_main_routing_table(table_id
)) {
2981 "Invalid routing table ID, %d. Must be non-default table\n",
2984 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2988 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2991 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2996 DEFUN_HIDDEN (zebra_packet_process
,
2997 zebra_packet_process_cmd
,
2998 "zebra zapi-packets (1-10000)",
3001 "Number of packets to process before relinquishing thread\n")
3003 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3005 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
3006 memory_order_relaxed
);
3011 DEFUN_HIDDEN (no_zebra_packet_process
,
3012 no_zebra_packet_process_cmd
,
3013 "no zebra zapi-packets [(1-10000)]",
3017 "Number of packets to process before relinquishing thread\n")
3019 atomic_store_explicit(&zrouter
.packets_to_process
,
3020 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
3021 memory_order_relaxed
);
3026 DEFUN_HIDDEN (zebra_workqueue_timer
,
3027 zebra_workqueue_timer_cmd
,
3028 "zebra work-queue (0-10000)",
3031 "Time in milliseconds\n")
3033 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3034 zrouter
.ribq
->spec
.hold
= timer
;
3039 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3040 no_zebra_workqueue_timer_cmd
,
3041 "no zebra work-queue [(0-10000)]",
3045 "Time in milliseconds\n")
3047 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3052 DEFUN (no_ip_zebra_import_table
,
3053 no_ip_zebra_import_table_cmd
,
3054 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3057 "import routes from non-main kernel table\n"
3058 "kernel routing table id\n"
3059 "Distance for imported routes\n"
3060 "Default distance value\n"
3061 "route-map for filtering\n"
3064 uint32_t table_id
= 0;
3065 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3067 if (!is_zebra_valid_kernel_table(table_id
)) {
3069 "Invalid routing table ID. Must be in range 1-252\n");
3073 if (is_zebra_main_routing_table(table_id
)) {
3075 "Invalid routing table ID, %d. Must be non-default table\n",
3080 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
3083 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
3086 static int config_write_protocol(struct vty
*vty
)
3089 vty_out(vty
, "allow-external-route-update\n");
3091 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3092 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
3094 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3095 vty_out(vty
, "zebra zapi-packets %u\n",
3096 zrouter
.packets_to_process
);
3098 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3100 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3101 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3102 ipv4_multicast_mode
== MCAST_URIB_ONLY
3104 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3106 : ipv4_multicast_mode
3107 == MCAST_MIX_MRIB_FIRST
3109 : ipv4_multicast_mode
3110 == MCAST_MIX_DISTANCE
3114 /* Include dataplane info */
3115 dplane_config_write_helper(vty
);
3129 " Route Route Neighbor LSP LSP\n");
3131 "VRF Installs Removals Updates Installs Removals\n");
3133 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3134 struct zebra_vrf
*zvrf
= vrf
->info
;
3136 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
3137 " %10" PRIu64
" %10" PRIu64
"\n",
3138 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3139 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3140 zvrf
->lsp_removals
);
3146 DEFUN (ip_forwarding
,
3150 "Turn on IP forwarding\n")
3156 ret
= ipforward_on();
3159 vty_out(vty
, "Can't turn on IP forwarding\n");
3160 return CMD_WARNING_CONFIG_FAILED
;
3166 DEFUN (no_ip_forwarding
,
3167 no_ip_forwarding_cmd
,
3171 "Turn off IP forwarding\n")
3177 ret
= ipforward_off();
3180 vty_out(vty
, "Can't turn off IP forwarding\n");
3181 return CMD_WARNING_CONFIG_FAILED
;
3187 /* Only display ip forwarding is enabled or not. */
3188 DEFUN (show_ip_forwarding
,
3189 show_ip_forwarding_cmd
,
3190 "show ip forwarding",
3193 "IP forwarding status\n")
3200 vty_out(vty
, "IP forwarding is off\n");
3202 vty_out(vty
, "IP forwarding is on\n");
3206 /* Only display ipv6 forwarding is enabled or not. */
3207 DEFUN (show_ipv6_forwarding
,
3208 show_ipv6_forwarding_cmd
,
3209 "show ipv6 forwarding",
3211 "IPv6 information\n"
3212 "Forwarding status\n")
3216 ret
= ipforward_ipv6();
3220 vty_out(vty
, "ipv6 forwarding is unknown\n");
3223 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3226 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3229 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3235 DEFUN (ipv6_forwarding
,
3236 ipv6_forwarding_cmd
,
3239 "Turn on IPv6 forwarding\n")
3243 ret
= ipforward_ipv6();
3245 ret
= ipforward_ipv6_on();
3248 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3249 return CMD_WARNING_CONFIG_FAILED
;
3255 DEFUN (no_ipv6_forwarding
,
3256 no_ipv6_forwarding_cmd
,
3257 "no ipv6 forwarding",
3260 "Turn off IPv6 forwarding\n")
3264 ret
= ipforward_ipv6();
3266 ret
= ipforward_ipv6_off();
3269 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3270 return CMD_WARNING_CONFIG_FAILED
;
3276 /* Display dataplane info */
3277 DEFUN (show_dataplane
,
3279 "show zebra dplane [detailed]",
3282 "Zebra dataplane information\n"
3283 "Detailed output\n")
3286 bool detailed
= false;
3288 if (argv_find(argv
, argc
, "detailed", &idx
))
3291 return dplane_show_helper(vty
, detailed
);
3294 /* Display dataplane providers info */
3295 DEFUN (show_dataplane_providers
,
3296 show_dataplane_providers_cmd
,
3297 "show zebra dplane providers [detailed]",
3300 "Zebra dataplane information\n"
3301 "Zebra dataplane provider information\n"
3302 "Detailed output\n")
3305 bool detailed
= false;
3307 if (argv_find(argv
, argc
, "detailed", &idx
))
3310 return dplane_show_provs_helper(vty
, detailed
);
3313 /* Configure dataplane incoming queue limit */
3314 DEFUN (zebra_dplane_queue_limit
,
3315 zebra_dplane_queue_limit_cmd
,
3316 "zebra dplane limit (0-10000)",
3319 "Limit incoming queued updates\n"
3320 "Number of queued updates\n")
3324 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3326 dplane_set_in_queue_limit(limit
, true);
3331 /* Reset dataplane queue limit to default value */
3332 DEFUN (no_zebra_dplane_queue_limit
,
3333 no_zebra_dplane_queue_limit_cmd
,
3334 "no zebra dplane limit [(0-10000)]",
3338 "Limit incoming queued updates\n"
3339 "Number of queued updates\n")
3341 dplane_set_in_queue_limit(0, false);
3346 DEFUN (zebra_show_routing_tables_summary
,
3347 zebra_show_routing_tables_summary_cmd
,
3348 "show zebra router table summary",
3351 "The Zebra Router Information\n"
3352 "Table Information about this Zebra Router\n"
3353 "Summary Information\n")
3355 zebra_router_show_table_summary(vty
);
3360 /* Table configuration write function. */
3361 static int config_write_table(struct vty
*vty
)
3366 /* IPForwarding configuration write function. */
3367 static int config_write_forwarding(struct vty
*vty
)
3369 /* FIXME: Find better place for that. */
3370 router_id_write(vty
);
3373 vty_out(vty
, "no ip forwarding\n");
3374 if (!ipforward_ipv6())
3375 vty_out(vty
, "no ipv6 forwarding\n");
3376 vty_out(vty
, "!\n");
3380 DEFUN_HIDDEN (show_frr
,
3386 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3387 vty_out(vty
, ".............................7777:..............................................\n");
3388 vty_out(vty
, ".............................777777,............................................\n");
3389 vty_out(vty
, "... .........................77777777,..........................................\n");
3390 vty_out(vty
, "............................=7777777777:........................................\n");
3391 vty_out(vty
, "........................:7777777777777777,......................................\n");
3392 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3393 vty_out(vty
, "...................I7777777777+.................................................\n");
3394 vty_out(vty
, "................,777777777?............ .......................................\n");
3395 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3396 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3397 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3398 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3399 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3400 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3401 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3402 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3403 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3404 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3405 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3406 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3407 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3408 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3409 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3410 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3411 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3412 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3413 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3414 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3415 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3416 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3417 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3418 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3419 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3420 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3421 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3422 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3423 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3424 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3425 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3426 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3427 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3428 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3429 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3430 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3431 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3432 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3433 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3434 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3435 vty_out(vty
, "................................~77777777...............=777777.................\n");
3436 vty_out(vty
, ".....................................:=?I................~777777................\n");
3437 vty_out(vty
, "..........................................................:777777,..............\n");
3438 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3443 /* IP node for static routes. */
3444 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3445 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3446 /* table node for routing tables. */
3447 static struct cmd_node table_node
= {TABLE_NODE
,
3448 "", /* This node has no interface. */
3450 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3451 "", /* This node has no interface. */
3455 void zebra_vty_init(void)
3457 /* Install configuration write function. */
3458 install_node(&table_node
, config_write_table
);
3459 install_node(&forwarding_node
, config_write_forwarding
);
3461 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3462 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3463 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3464 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3466 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3467 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3468 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3471 zebra_route_map_init();
3473 install_node(&ip_node
, zebra_ip_config
);
3474 install_node(&protocol_node
, config_write_protocol
);
3476 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3477 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3479 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3480 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3482 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3483 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3484 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3485 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3486 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3487 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3489 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3490 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3492 install_element(VIEW_NODE
, &show_vrf_cmd
);
3493 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3494 install_element(VIEW_NODE
, &show_route_cmd
);
3495 install_element(VIEW_NODE
, &show_route_table_cmd
);
3496 if (vrf_is_backend_netns())
3497 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3498 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3499 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3500 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3501 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3503 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3504 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3506 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3507 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3508 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3509 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3510 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3511 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3512 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3513 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3514 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3516 /* Commands for VRF */
3517 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3519 install_element(VIEW_NODE
, &show_frr_cmd
);
3520 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3521 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3522 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3523 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3524 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3525 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3526 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3527 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3528 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3529 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3530 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3531 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3532 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3533 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3534 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3535 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3536 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3537 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3538 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3539 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3540 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3541 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3542 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3543 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3544 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3545 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3547 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3548 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3550 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3551 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3552 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3553 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3555 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3556 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3557 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3558 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3560 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);