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"
56 extern int allow_delete
;
58 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
59 safi_t safi
, bool use_fib
, bool use_json
,
61 const struct prefix
*longer_prefix_p
,
62 bool supernets_only
, int type
,
63 unsigned short ospf_instance_id
);
64 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
65 int mcast
, bool use_fib
);
66 static void vty_show_ip_route_summary(struct vty
*vty
,
67 struct route_table
*table
);
68 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
69 struct route_table
*table
);
71 DEFUN (ip_multicast_mode
,
72 ip_multicast_mode_cmd
,
73 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
76 "RPF lookup behavior\n"
77 "Lookup in unicast RIB only\n"
78 "Lookup in multicast RIB only\n"
79 "Try multicast RIB first, fall back to unicast RIB\n"
80 "Lookup both, use entry with lower distance\n"
81 "Lookup both, use entry with longer prefix\n")
83 char *mode
= argv
[3]->text
;
85 if (strmatch(mode
, "urib-only"))
86 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
87 else if (strmatch(mode
, "mrib-only"))
88 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
89 else if (strmatch(mode
, "mrib-then-urib"))
90 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
91 else if (strmatch(mode
, "lower-distance"))
92 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
93 else if (strmatch(mode
, "longer-prefix"))
94 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
96 vty_out(vty
, "Invalid mode specified\n");
97 return CMD_WARNING_CONFIG_FAILED
;
103 DEFUN (no_ip_multicast_mode
,
104 no_ip_multicast_mode_cmd
,
105 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
108 "Multicast options\n"
109 "RPF lookup behavior\n"
110 "Lookup in unicast RIB only\n"
111 "Lookup in multicast RIB only\n"
112 "Try multicast RIB first, fall back to unicast RIB\n"
113 "Lookup both, use entry with lower distance\n"
114 "Lookup both, use entry with longer prefix\n")
116 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
123 "show ip rpf [json]",
126 "Display RPF information for multicast source\n"
129 bool uj
= use_json(argc
, argv
);
130 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
131 false, uj
, 0, NULL
, false, 0, 0);
134 DEFUN (show_ip_rpf_addr
,
135 show_ip_rpf_addr_cmd
,
136 "show ip rpf A.B.C.D",
139 "Display RPF information for multicast source\n"
140 "IP multicast source address (e.g. 10.0.0.0)\n")
144 struct route_node
*rn
;
145 struct route_entry
*re
;
148 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
150 vty_out(vty
, "%% Malformed address\n");
154 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
157 vty_show_ip_route_detail(vty
, rn
, 1, false);
159 vty_out(vty
, "%% No match for RPF lookup\n");
164 static char re_status_output_char(struct route_entry
*re
, struct nexthop
*nhop
)
166 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
167 if (!CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
168 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
174 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
175 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
181 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
187 /* New RIB. Detailed information for IPv4 route. */
188 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
189 int mcast
, bool use_fib
)
191 struct route_entry
*re
;
192 struct nexthop
*nexthop
;
193 char buf
[SRCDEST2STR_BUFFER
];
194 struct zebra_vrf
*zvrf
;
197 dest
= rib_dest_from_rnode(rn
);
199 RNODE_FOREACH_RE (rn
, re
) {
201 * If re not selected for forwarding, skip re
202 * for "show ip/ipv6 fib <prefix>"
204 if (use_fib
&& re
!= dest
->selected_fib
)
207 const char *mcast_info
= "";
209 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
210 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
211 ? " using Multicast RIB"
212 : " using Unicast RIB";
215 vty_out(vty
, "Routing entry for %s%s\n",
216 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
217 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
219 vty_out(vty
, "[%d]", re
->instance
);
221 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
224 vty_out(vty
, ", tag %u", re
->tag
);
225 #if defined(SUPPORT_REALMS)
226 if (re
->tag
> 0 && re
->tag
<= 255)
227 vty_out(vty
, "(realm)");
231 vty_out(vty
, ", mtu %u", re
->mtu
);
232 if (re
->vrf_id
!= VRF_DEFAULT
) {
233 zvrf
= vrf_info_lookup(re
->vrf_id
);
234 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
236 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
237 vty_out(vty
, ", best");
243 uptime
= monotime(NULL
);
244 uptime
-= re
->uptime
;
245 tm
= gmtime(&uptime
);
247 vty_out(vty
, " Last update ");
249 if (uptime
< ONE_DAY_SECOND
)
250 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
252 else if (uptime
< ONE_WEEK_SECOND
)
253 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
256 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
257 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
259 vty_out(vty
, " ago\n");
261 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
264 vty_out(vty
, " %c%s",
265 re_status_output_char(re
, nexthop
),
266 nexthop
->rparent
? " " : "");
268 switch (nexthop
->type
) {
269 case NEXTHOP_TYPE_IPV4
:
270 case NEXTHOP_TYPE_IPV4_IFINDEX
:
272 inet_ntoa(nexthop
->gate
.ipv4
));
273 if (nexthop
->ifindex
)
274 vty_out(vty
, ", via %s",
279 case NEXTHOP_TYPE_IPV6
:
280 case NEXTHOP_TYPE_IPV6_IFINDEX
:
282 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
284 if (nexthop
->ifindex
)
285 vty_out(vty
, ", via %s",
290 case NEXTHOP_TYPE_IFINDEX
:
291 vty_out(vty
, " directly connected, %s",
292 ifindex2ifname(nexthop
->ifindex
,
295 case NEXTHOP_TYPE_BLACKHOLE
:
296 vty_out(vty
, " unreachable");
297 switch (nexthop
->bh_type
) {
298 case BLACKHOLE_REJECT
:
299 vty_out(vty
, " (ICMP unreachable)");
301 case BLACKHOLE_ADMINPROHIB
:
303 " (ICMP admin-prohibited)");
306 vty_out(vty
, " (blackhole)");
308 case BLACKHOLE_UNSPEC
:
316 if ((re
->vrf_id
!= nexthop
->vrf_id
)
317 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
319 vrf_lookup_by_id(nexthop
->vrf_id
);
322 vty_out(vty
, "(vrf %s)", vrf
->name
);
324 vty_out(vty
, "(vrf UNKNOWN)");
327 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
328 vty_out(vty
, " (duplicate nexthop removed)");
330 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
331 vty_out(vty
, " inactive");
333 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
334 vty_out(vty
, " onlink");
336 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
337 vty_out(vty
, " (recursive)");
339 switch (nexthop
->type
) {
340 case NEXTHOP_TYPE_IPV4
:
341 case NEXTHOP_TYPE_IPV4_IFINDEX
:
342 if (nexthop
->src
.ipv4
.s_addr
) {
343 if (inet_ntop(AF_INET
,
345 addrstr
, sizeof addrstr
))
346 vty_out(vty
, ", src %s",
350 case NEXTHOP_TYPE_IPV6
:
351 case NEXTHOP_TYPE_IPV6_IFINDEX
:
352 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
354 if (inet_ntop(AF_INET6
,
356 addrstr
, sizeof addrstr
))
357 vty_out(vty
, ", src %s",
366 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
368 /* Label information */
369 if (nexthop
->nh_label
370 && nexthop
->nh_label
->num_labels
) {
371 vty_out(vty
, ", label %s",
373 nexthop
->nh_label
->num_labels
,
374 nexthop
->nh_label
->label
, buf
,
384 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
385 struct route_entry
*re
, json_object
*json
,
388 struct nexthop
*nexthop
;
390 char buf
[SRCDEST2STR_BUFFER
];
391 json_object
*json_nexthops
= NULL
;
392 json_object
*json_nexthop
= NULL
;
393 json_object
*json_route
= NULL
;
394 json_object
*json_labels
= NULL
;
397 struct vrf
*vrf
= NULL
;
398 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
399 struct nexthop_group
*nhg
;
401 uptime
= monotime(NULL
);
402 uptime
-= re
->uptime
;
403 tm
= gmtime(&uptime
);
405 /* If showing fib information, use the fib view of the
409 nhg
= rib_active_nhg(re
);
414 json_route
= json_object_new_object();
415 json_nexthops
= json_object_new_array();
417 json_object_string_add(json_route
, "prefix",
418 srcdest_rnode2str(rn
, buf
, sizeof buf
));
419 json_object_string_add(json_route
, "protocol",
420 zebra_route_string(re
->type
));
423 json_object_int_add(json_route
, "instance",
427 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
428 vrf
= vrf_lookup_by_id(re
->vrf_id
);
429 json_object_string_add(json_route
, "vrfName",
433 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
434 json_object_boolean_true_add(json_route
, "selected");
436 if (dest
->selected_fib
== re
)
437 json_object_boolean_true_add(json_route
,
440 json_object_int_add(json_route
, "distance",
442 json_object_int_add(json_route
, "metric", re
->metric
);
444 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
445 json_object_boolean_true_add(json_route
, "installed");
447 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
448 json_object_boolean_true_add(json_route
, "failed");
450 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
451 json_object_boolean_true_add(json_route
, "queued");
454 json_object_int_add(json_route
, "tag", re
->tag
);
457 json_object_int_add(json_route
, "table", re
->table
);
459 json_object_int_add(json_route
, "internalStatus",
461 json_object_int_add(json_route
, "internalFlags",
463 json_object_int_add(json_route
, "internalNextHopNum",
465 json_object_int_add(json_route
, "internalNextHopActiveNum",
466 re
->nexthop_active_num
);
467 if (uptime
< ONE_DAY_SECOND
)
468 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
470 else if (uptime
< ONE_WEEK_SECOND
)
471 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
474 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
475 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
478 json_object_string_add(json_route
, "uptime", buf
);
480 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
481 json_nexthop
= json_object_new_object();
483 json_object_int_add(json_nexthop
, "flags",
486 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
487 json_object_boolean_true_add(json_nexthop
,
490 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
491 json_object_boolean_true_add(json_nexthop
,
494 switch (nexthop
->type
) {
495 case NEXTHOP_TYPE_IPV4
:
496 case NEXTHOP_TYPE_IPV4_IFINDEX
:
497 json_object_string_add(
499 inet_ntoa(nexthop
->gate
.ipv4
));
500 json_object_string_add(json_nexthop
, "afi",
503 if (nexthop
->ifindex
) {
504 json_object_int_add(json_nexthop
,
507 json_object_string_add(
508 json_nexthop
, "interfaceName",
514 case NEXTHOP_TYPE_IPV6
:
515 case NEXTHOP_TYPE_IPV6_IFINDEX
:
516 json_object_string_add(
518 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
520 json_object_string_add(json_nexthop
, "afi",
523 if (nexthop
->ifindex
) {
524 json_object_int_add(json_nexthop
,
527 json_object_string_add(
528 json_nexthop
, "interfaceName",
535 case NEXTHOP_TYPE_IFINDEX
:
536 json_object_boolean_true_add(
537 json_nexthop
, "directlyConnected");
538 json_object_int_add(json_nexthop
,
541 json_object_string_add(
542 json_nexthop
, "interfaceName",
543 ifindex2ifname(nexthop
->ifindex
,
546 case NEXTHOP_TYPE_BLACKHOLE
:
547 json_object_boolean_true_add(json_nexthop
,
549 switch (nexthop
->bh_type
) {
550 case BLACKHOLE_REJECT
:
551 json_object_boolean_true_add(
552 json_nexthop
, "reject");
554 case BLACKHOLE_ADMINPROHIB
:
555 json_object_boolean_true_add(
560 json_object_boolean_true_add(
561 json_nexthop
, "blackhole");
563 case BLACKHOLE_UNSPEC
:
571 if ((nexthop
->vrf_id
!= re
->vrf_id
)
572 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
573 vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
574 json_object_string_add(json_nexthop
, "vrf",
577 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
578 json_object_boolean_true_add(json_nexthop
,
581 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
582 json_object_boolean_true_add(json_nexthop
,
585 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
586 json_object_boolean_true_add(json_nexthop
,
589 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
590 json_object_boolean_true_add(json_nexthop
,
593 switch (nexthop
->type
) {
594 case NEXTHOP_TYPE_IPV4
:
595 case NEXTHOP_TYPE_IPV4_IFINDEX
:
596 if (nexthop
->src
.ipv4
.s_addr
) {
597 if (inet_ntop(AF_INET
,
598 &nexthop
->src
.ipv4
, buf
,
600 json_object_string_add(
601 json_nexthop
, "source",
605 case NEXTHOP_TYPE_IPV6
:
606 case NEXTHOP_TYPE_IPV6_IFINDEX
:
607 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
609 if (inet_ntop(AF_INET6
,
610 &nexthop
->src
.ipv6
, buf
,
612 json_object_string_add(
613 json_nexthop
, "source",
621 if (nexthop
->nh_label
622 && nexthop
->nh_label
->num_labels
) {
623 json_labels
= json_object_new_array();
625 for (int label_index
= 0;
627 < nexthop
->nh_label
->num_labels
;
629 json_object_array_add(
632 nexthop
->nh_label
->label
635 json_object_object_add(json_nexthop
, "labels",
639 json_object_array_add(json_nexthops
, json_nexthop
);
642 json_object_object_add(json_route
, "nexthops", json_nexthops
);
643 json_object_array_add(json
, json_route
);
647 /* Nexthop information. */
648 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
649 if (nexthop
== nhg
->nexthop
) {
650 /* Prefix information. */
651 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
653 len
+= vty_out(vty
, "[%d]", re
->instance
);
656 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
659 re_status_output_char(re
, nexthop
),
660 srcdest_rnode2str(rn
, buf
, sizeof buf
));
662 /* Distance and metric display. */
663 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
664 (re
->distance
|| re
->metric
)) ||
665 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
666 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
669 vty_out(vty
, " %c%*c",
670 re_status_output_char(re
, nexthop
),
671 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
674 switch (nexthop
->type
) {
675 case NEXTHOP_TYPE_IPV4
:
676 case NEXTHOP_TYPE_IPV4_IFINDEX
:
677 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
678 if (nexthop
->ifindex
)
680 ifindex2ifname(nexthop
->ifindex
,
683 case NEXTHOP_TYPE_IPV6
:
684 case NEXTHOP_TYPE_IPV6_IFINDEX
:
685 vty_out(vty
, " via %s",
686 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
688 if (nexthop
->ifindex
)
690 ifindex2ifname(nexthop
->ifindex
,
694 case NEXTHOP_TYPE_IFINDEX
:
695 vty_out(vty
, " is directly connected, %s",
696 ifindex2ifname(nexthop
->ifindex
,
699 case NEXTHOP_TYPE_BLACKHOLE
:
700 vty_out(vty
, " unreachable");
701 switch (nexthop
->bh_type
) {
702 case BLACKHOLE_REJECT
:
703 vty_out(vty
, " (ICMP unreachable)");
705 case BLACKHOLE_ADMINPROHIB
:
706 vty_out(vty
, " (ICMP admin-prohibited)");
709 vty_out(vty
, " (blackhole)");
711 case BLACKHOLE_UNSPEC
:
719 if ((nexthop
->vrf_id
!= re
->vrf_id
)
720 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
721 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
724 vty_out(vty
, "(vrf %s)", vrf
->name
);
726 vty_out(vty
, "(vrf UNKNOWN)");
729 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
730 vty_out(vty
, " inactive");
732 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
733 vty_out(vty
, " onlink");
735 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
736 vty_out(vty
, " (recursive)");
738 switch (nexthop
->type
) {
739 case NEXTHOP_TYPE_IPV4
:
740 case NEXTHOP_TYPE_IPV4_IFINDEX
:
741 if (nexthop
->src
.ipv4
.s_addr
) {
742 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
744 vty_out(vty
, ", src %s", buf
);
747 case NEXTHOP_TYPE_IPV6
:
748 case NEXTHOP_TYPE_IPV6_IFINDEX
:
749 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
750 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
752 vty_out(vty
, ", src %s", buf
);
759 /* Label information */
760 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
761 vty_out(vty
, ", label %s",
762 mpls_label2str(nexthop
->nh_label
->num_labels
,
763 nexthop
->nh_label
->label
, buf
,
767 if (uptime
< ONE_DAY_SECOND
)
768 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
769 tm
->tm_min
, tm
->tm_sec
);
770 else if (uptime
< ONE_WEEK_SECOND
)
771 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
772 tm
->tm_hour
, tm
->tm_min
);
774 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
775 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
781 static void vty_show_ip_route_detail_json(struct vty
*vty
,
782 struct route_node
*rn
, bool use_fib
)
784 json_object
*json
= NULL
;
785 json_object
*json_prefix
= NULL
;
786 struct route_entry
*re
;
790 dest
= rib_dest_from_rnode(rn
);
792 json
= json_object_new_object();
793 json_prefix
= json_object_new_array();
795 RNODE_FOREACH_RE (rn
, re
) {
797 * If re not selected for forwarding, skip re
798 * for "show ip/ipv6 fib <prefix> json"
800 if (use_fib
&& re
!= dest
->selected_fib
)
802 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
805 prefix2str(&rn
->p
, buf
, sizeof(buf
));
806 json_object_object_add(json
, buf
, json_prefix
);
807 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
808 json
, JSON_C_TO_STRING_PRETTY
));
809 json_object_free(json
);
812 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
813 struct route_table
*table
, afi_t afi
,
814 bool use_fib
, route_tag_t tag
,
815 const struct prefix
*longer_prefix_p
,
816 bool supernets_only
, int type
,
817 unsigned short ospf_instance_id
, bool use_json
,
820 struct route_node
*rn
;
821 struct route_entry
*re
;
824 json_object
*json
= NULL
;
825 json_object
*json_prefix
= NULL
;
830 json
= json_object_new_object();
832 /* Show all routes. */
833 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
834 dest
= rib_dest_from_rnode(rn
);
836 RNODE_FOREACH_RE (rn
, re
) {
837 if (use_fib
&& re
!= dest
->selected_fib
)
840 if (tag
&& re
->tag
!= tag
)
844 && !prefix_match(longer_prefix_p
, &rn
->p
))
847 /* This can only be true when the afi is IPv4 */
848 if (supernets_only
) {
849 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
851 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
854 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
857 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
861 if (type
&& re
->type
!= type
)
865 && (re
->type
!= ZEBRA_ROUTE_OSPF
866 || re
->instance
!= ospf_instance_id
))
871 json_prefix
= json_object_new_array();
876 SHOW_ROUTE_V4_HEADER
);
879 SHOW_ROUTE_V6_HEADER
);
881 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
882 vty_out(vty
, "\nVRF %s table %u:\n",
883 zvrf_name(zvrf
), tableid
);
884 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
885 vty_out(vty
, "\nVRF %s:\n",
891 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
895 prefix2str(&rn
->p
, buf
, sizeof(buf
));
896 json_object_object_add(json
, buf
, json_prefix
);
902 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
903 JSON_C_TO_STRING_PRETTY
));
904 json_object_free(json
);
908 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
909 safi_t safi
, bool use_fib
, bool use_json
,
911 const struct prefix
*longer_prefix_p
,
912 bool supernets_only
, int type
,
913 unsigned short ospf_instance_id
)
915 struct route_table
*table
;
916 struct zebra_vrf
*zvrf
= NULL
;
918 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
920 vty_out(vty
, "{}\n");
922 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
926 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
928 vty_out(vty
, "{}\n");
930 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
934 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
937 vty_out(vty
, "{}\n");
941 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
942 longer_prefix_p
, supernets_only
, type
,
943 ospf_instance_id
, use_json
, 0);
948 DEFPY (show_route_table
,
949 show_route_table_cmd
,
950 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
956 "The table number to display, if available\n"
959 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
960 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
961 struct route_table
*t
;
963 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
965 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
966 0, 0, !!json
, table
);
971 DEFPY (show_route_table_vrf
,
972 show_route_table_vrf_cmd
,
973 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
979 "The table number to display, if available\n"
983 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
984 struct zebra_vrf
*zvrf
;
985 struct route_table
*t
;
986 vrf_id_t vrf_id
= VRF_DEFAULT
;
989 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
990 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
992 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
994 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
995 0, 0, !!json
, table
);
1000 DEFPY (show_route_all_table_vrf
,
1001 show_route_all_table_vrf_cmd
,
1002 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1006 "IP routing table\n"
1007 "Display all tables\n"
1008 VRF_FULL_CMD_HELP_STR
1011 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1012 struct zebra_vrf
*zvrf
= NULL
;
1013 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1014 struct zebra_router_table
*zrt
;
1017 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1018 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1021 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1022 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1024 if (zvrf
&& zvrf
!= info
->zvrf
)
1026 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1029 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
,
1030 false, 0, false, false,
1031 0, 0, !!json
, zrt
->tableid
);
1038 "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]",
1042 "IP nexthop tracking table\n"
1043 "IP import check tracking table\n"
1049 VRF_ALL_CMD_HELP_STR
)
1051 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1052 vrf_id_t vrf_id
= VRF_DEFAULT
;
1053 struct prefix prefix
, *p
= NULL
;
1056 if (strcmp(type
, "nht") == 0)
1057 rtype
= RNH_NEXTHOP_TYPE
;
1059 rtype
= RNH_IMPORT_CHECK_TYPE
;
1063 struct zebra_vrf
*zvrf
;
1065 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1066 if ((zvrf
= vrf
->info
) != NULL
) {
1067 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1068 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1074 VRF_GET_ID(vrf_id
, vrf_name
, false);
1076 memset(&prefix
, 0, sizeof(prefix
));
1078 p
= sockunion2hostprefix(addr
, &prefix
);
1080 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1084 DEFUN (ip_nht_default_route
,
1085 ip_nht_default_route_cmd
,
1086 "ip nht resolve-via-default",
1088 "Filter Next Hop tracking route resolution\n"
1089 "Resolve via default route\n")
1091 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1096 if (zvrf
->zebra_rnh_ip_default_route
)
1099 zvrf
->zebra_rnh_ip_default_route
= 1;
1101 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1105 DEFUN (no_ip_nht_default_route
,
1106 no_ip_nht_default_route_cmd
,
1107 "no ip nht resolve-via-default",
1110 "Filter Next Hop tracking route resolution\n"
1111 "Resolve via default route\n")
1113 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1118 if (!zvrf
->zebra_rnh_ip_default_route
)
1121 zvrf
->zebra_rnh_ip_default_route
= 0;
1122 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1126 DEFUN (ipv6_nht_default_route
,
1127 ipv6_nht_default_route_cmd
,
1128 "ipv6 nht resolve-via-default",
1130 "Filter Next Hop tracking route resolution\n"
1131 "Resolve via default route\n")
1133 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1138 if (zvrf
->zebra_rnh_ipv6_default_route
)
1141 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1142 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1146 DEFUN (no_ipv6_nht_default_route
,
1147 no_ipv6_nht_default_route_cmd
,
1148 "no ipv6 nht resolve-via-default",
1151 "Filter Next Hop tracking route resolution\n"
1152 "Resolve via default route\n")
1155 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1160 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1163 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1164 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1172 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1175 |A.B.C.D/M$prefix longer-prefixes\
1176 |supernets-only$supernets_only\
1179 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1180 |ospf$type_str (1-65535)$ospf_instance_id\
1182 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1185 |X:X::X:X/M$prefix longer-prefixes\
1187 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1192 "IP forwarding table\n"
1193 "IP routing table\n"
1194 VRF_FULL_CMD_HELP_STR
1195 "Show only routes with tag\n"
1197 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1198 "Show route matching the specified Network/Mask pair only\n"
1199 "Show supernet entries only\n"
1200 FRR_IP_REDIST_HELP_STR_ZEBRA
1201 "Open Shortest Path First (OSPFv2)\n"
1204 "IP forwarding table\n"
1205 "IP routing table\n"
1206 VRF_FULL_CMD_HELP_STR
1207 "Show only routes with tag\n"
1210 "Show route matching the specified Network/Mask pair only\n"
1211 FRR_IP6_REDIST_HELP_STR_ZEBRA
1214 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1219 type
= proto_redistnum(afi
, type_str
);
1221 vty_out(vty
, "Unknown route type\n");
1227 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1228 struct zebra_vrf
*zvrf
;
1229 struct route_table
*table
;
1231 if ((zvrf
= vrf
->info
) == NULL
1232 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1236 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1237 !!json
, tag
, prefix_str
? prefix
: NULL
,
1238 !!supernets_only
, type
, ospf_instance_id
);
1241 vrf_id_t vrf_id
= VRF_DEFAULT
;
1244 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1245 vrf
= vrf_lookup_by_id(vrf_id
);
1246 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1247 !!json
, tag
, prefix_str
? prefix
: NULL
,
1248 !!supernets_only
, type
, ospf_instance_id
);
1254 DEFPY (show_route_detail
,
1255 show_route_detail_cmd
,
1258 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1263 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1272 "IPv6 forwarding table\n"
1273 "IP routing table\n"
1274 VRF_FULL_CMD_HELP_STR
1275 "Network in the IP routing table to display\n"
1276 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1278 "IPv6 forwarding table\n"
1279 "IPv6 routing table\n"
1280 VRF_FULL_CMD_HELP_STR
1285 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1286 struct route_table
*table
;
1288 struct route_node
*rn
;
1289 bool use_fib
= !!fib
;
1291 bool network_found
= false;
1294 prefix_str
= address_str
;
1295 if (str2prefix(prefix_str
, &p
) < 0) {
1296 vty_out(vty
, "%% Malformed address\n");
1302 struct zebra_vrf
*zvrf
;
1304 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1305 if ((zvrf
= vrf
->info
) == NULL
1306 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1309 rn
= route_node_match(table
, &p
);
1312 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1313 route_unlock_node(rn
);
1317 dest
= rib_dest_from_rnode(rn
);
1318 if (use_fib
&& !dest
->selected_fib
) {
1319 route_unlock_node(rn
);
1323 network_found
= true;
1325 vty_show_ip_route_detail_json(vty
, rn
,
1328 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1330 route_unlock_node(rn
);
1333 if (!network_found
) {
1335 vty_out(vty
, "{}\n");
1339 "%% Network not in FIB\n");
1342 "%% Network not in RIB\n");
1347 vrf_id_t vrf_id
= VRF_DEFAULT
;
1350 VRF_GET_ID(vrf_id
, vrf_name
, false);
1352 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1356 rn
= route_node_match(table
, &p
);
1358 dest
= rib_dest_from_rnode(rn
);
1360 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1361 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1363 vty_out(vty
, "{}\n");
1367 "%% Network not in FIB\n");
1370 "%% Network not in table\n");
1373 route_unlock_node(rn
);
1378 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1380 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1382 route_unlock_node(rn
);
1388 DEFPY (show_route_summary
,
1389 show_route_summary_cmd
,
1390 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1391 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1395 "IP routing table\n"
1396 VRF_FULL_CMD_HELP_STR
1397 "Summary of all routes\n"
1398 "Table to display summary for\n"
1399 "The table number\n"
1402 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1403 struct route_table
*table
;
1406 table_id
= RT_TABLE_MAIN
;
1410 struct zebra_vrf
*zvrf
;
1412 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1413 if ((zvrf
= vrf
->info
) == NULL
)
1416 table
= zebra_vrf_table_with_table_id(afi
,
1424 vty_show_ip_route_summary_prefix(vty
, table
);
1426 vty_show_ip_route_summary(vty
, table
);
1429 vrf_id_t vrf_id
= VRF_DEFAULT
;
1432 VRF_GET_ID(vrf_id
, vrf_name
, false);
1434 table
= zebra_vrf_table_with_table_id(afi
,
1441 vty_show_ip_route_summary_prefix(vty
, table
);
1443 vty_show_ip_route_summary(vty
, table
);
1449 static void vty_show_ip_route_summary(struct vty
*vty
,
1450 struct route_table
*table
)
1452 struct route_node
*rn
;
1453 struct route_entry
*re
;
1454 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1455 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1456 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1457 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1461 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1462 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1463 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1464 RNODE_FOREACH_RE (rn
, re
) {
1465 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1466 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1468 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1470 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1472 rib_cnt
[re
->type
]++;
1474 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1475 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1478 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1480 fib_cnt
[re
->type
]++;
1484 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1485 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1487 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1488 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1489 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1490 if (i
== ZEBRA_ROUTE_BGP
) {
1491 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1492 rib_cnt
[ZEBRA_ROUTE_BGP
],
1493 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1494 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1495 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1496 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1498 vty_out(vty
, "%-20s %-20d %-20d \n",
1499 zebra_route_string(i
), rib_cnt
[i
],
1504 vty_out(vty
, "------\n");
1505 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1506 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1511 * Implementation of the ip route summary prefix command.
1513 * This command prints the primary prefixes that have been installed by various
1514 * protocols on the box.
1517 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1518 struct route_table
*table
)
1520 struct route_node
*rn
;
1521 struct route_entry
*re
;
1522 struct nexthop
*nexthop
;
1523 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1524 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1525 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1526 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1530 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1531 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1532 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1533 RNODE_FOREACH_RE (rn
, re
) {
1536 * In case of ECMP, count only once.
1539 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1540 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1541 fib_cnt
[re
->type
]++;
1543 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1544 nexthop
= nexthop
->next
) {
1546 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1547 rib_cnt
[re
->type
]++;
1548 if (re
->type
== ZEBRA_ROUTE_BGP
1549 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1550 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1551 if (CHECK_FLAG(re
->status
,
1552 ROUTE_ENTRY_INSTALLED
))
1553 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1558 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1559 "Prefix Routes", "FIB",
1560 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1562 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1563 if (rib_cnt
[i
] > 0) {
1564 if (i
== ZEBRA_ROUTE_BGP
) {
1565 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1566 rib_cnt
[ZEBRA_ROUTE_BGP
]
1567 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1568 fib_cnt
[ZEBRA_ROUTE_BGP
]
1569 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1570 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1571 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1572 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1574 vty_out(vty
, "%-20s %-20d %-20d \n",
1575 zebra_route_string(i
), rib_cnt
[i
],
1580 vty_out(vty
, "------\n");
1581 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1582 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1587 * Show IPv6 mroute command.Used to dump
1588 * the Multicast routing table.
1590 DEFUN (show_ipv6_mroute
,
1591 show_ipv6_mroute_cmd
,
1592 "show ipv6 mroute [vrf NAME]",
1595 "IPv6 Multicast routing table\n"
1598 struct route_table
*table
;
1599 struct route_node
*rn
;
1600 struct route_entry
*re
;
1602 vrf_id_t vrf_id
= VRF_DEFAULT
;
1605 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1607 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1611 /* Show all IPv6 route. */
1612 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1613 RNODE_FOREACH_RE (rn
, re
) {
1615 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1618 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1623 DEFUN (show_ipv6_mroute_vrf_all
,
1624 show_ipv6_mroute_vrf_all_cmd
,
1625 "show ipv6 mroute vrf all",
1628 "IPv6 Multicast routing table\n"
1629 VRF_ALL_CMD_HELP_STR
)
1631 struct route_table
*table
;
1632 struct route_node
*rn
;
1633 struct route_entry
*re
;
1635 struct zebra_vrf
*zvrf
;
1638 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1639 if ((zvrf
= vrf
->info
) == NULL
1640 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1643 /* Show all IPv6 route. */
1644 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1645 RNODE_FOREACH_RE (rn
, re
) {
1647 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1650 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1656 DEFUN (allow_external_route_update
,
1657 allow_external_route_update_cmd
,
1658 "allow-external-route-update",
1659 "Allow FRR routes to be overwritten by external processes\n")
1666 DEFUN (no_allow_external_route_update
,
1667 no_allow_external_route_update_cmd
,
1668 "no allow-external-route-update",
1670 "Allow FRR routes to be overwritten by external processes\n")
1685 struct zebra_vrf
*zvrf
;
1687 if (vrf_is_backend_netns())
1688 vty_out(vty
, "netns-based vrfs\n");
1690 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1691 if (!(zvrf
= vrf
->info
))
1693 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1696 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1697 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1698 vty_out(vty
, "inactive");
1699 else if (zvrf_ns_name(zvrf
))
1700 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1701 zvrf_ns_name(zvrf
));
1703 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1705 if (vrf_is_user_cfged(vrf
))
1706 vty_out(vty
, " (configured)");
1713 DEFUN (default_vrf_vni_mapping
,
1714 default_vrf_vni_mapping_cmd
,
1715 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1716 "VNI corresponding to the DEFAULT VRF\n"
1718 "Prefix routes only \n")
1721 char err
[ERR_STR_SZ
];
1722 struct zebra_vrf
*zvrf
= NULL
;
1723 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1726 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1733 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1736 vty_out(vty
, "%s\n", err
);
1743 DEFUN (no_default_vrf_vni_mapping
,
1744 no_default_vrf_vni_mapping_cmd
,
1745 "no vni " CMD_VNI_RANGE
,
1747 "VNI corresponding to DEFAULT VRF\n"
1751 char err
[ERR_STR_SZ
];
1752 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1753 struct zebra_vrf
*zvrf
= NULL
;
1755 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1759 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1761 vty_out(vty
, "%s\n", err
);
1768 DEFUN (vrf_vni_mapping
,
1769 vrf_vni_mapping_cmd
,
1770 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1771 "VNI corresponding to tenant VRF\n"
1773 "prefix-routes-only\n")
1778 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1779 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1780 char err
[ERR_STR_SZ
];
1788 /* Mark as having FRR configuration */
1789 vrf_set_user_cfged(vrf
);
1790 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1793 vty_out(vty
, "%s\n", err
);
1800 DEFUN (no_vrf_vni_mapping
,
1801 no_vrf_vni_mapping_cmd
,
1802 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1804 "VNI corresponding to tenant VRF\n"
1806 "prefix-routes-only\n")
1810 char err
[ERR_STR_SZ
];
1811 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1813 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1821 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1822 ERR_STR_SZ
, filter
, 0);
1824 vty_out(vty
, "%s\n", err
);
1828 /* If no other FRR config for this VRF, mark accordingly. */
1829 if (!zebra_vrf_has_config(zvrf
))
1830 vrf_reset_user_cfged(vrf
);
1836 DEFUN (show_vrf_vni
,
1838 "show vrf vni [json]",
1845 struct zebra_vrf
*zvrf
;
1846 json_object
*json
= NULL
;
1847 json_object
*json_vrfs
= NULL
;
1848 bool uj
= use_json(argc
, argv
);
1851 json
= json_object_new_object();
1852 json_vrfs
= json_object_new_array();
1856 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1857 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1859 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1864 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1868 json_object_object_add(json
, "vrfs", json_vrfs
);
1869 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1870 json
, JSON_C_TO_STRING_PRETTY
));
1871 json_object_free(json
);
1877 DEFUN (show_evpn_global
,
1878 show_evpn_global_cmd
,
1884 bool uj
= use_json(argc
, argv
);
1886 zebra_vxlan_print_evpn(vty
, uj
);
1890 DEFUN (show_evpn_vni
,
1892 "show evpn vni [json]",
1895 "VxLAN Network Identifier\n"
1898 struct zebra_vrf
*zvrf
;
1899 bool uj
= use_json(argc
, argv
);
1901 zvrf
= zebra_vrf_get_evpn();
1902 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1906 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1907 "show evpn vni detail [json]",
1910 "VxLAN Network Identifier\n"
1911 "Detailed Information On Each VNI\n"
1914 struct zebra_vrf
*zvrf
;
1915 bool uj
= use_json(argc
, argv
);
1917 zvrf
= zebra_vrf_get_evpn();
1918 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1922 DEFUN (show_evpn_vni_vni
,
1923 show_evpn_vni_vni_cmd
,
1924 "show evpn vni " CMD_VNI_RANGE
"[json]",
1927 "VxLAN Network Identifier\n"
1931 struct zebra_vrf
*zvrf
;
1933 bool uj
= use_json(argc
, argv
);
1935 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1936 zvrf
= zebra_vrf_get_evpn();
1937 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1941 DEFUN (show_evpn_rmac_vni_mac
,
1942 show_evpn_rmac_vni_mac_cmd
,
1943 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1950 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1955 bool uj
= use_json(argc
, argv
);
1957 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1958 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1959 vty_out(vty
, "%% Malformed MAC address\n");
1962 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1966 DEFUN (show_evpn_rmac_vni
,
1967 show_evpn_rmac_vni_cmd
,
1968 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1977 bool uj
= use_json(argc
, argv
);
1979 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1980 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1985 DEFUN (show_evpn_rmac_vni_all
,
1986 show_evpn_rmac_vni_all_cmd
,
1987 "show evpn rmac vni all [json]",
1995 bool uj
= use_json(argc
, argv
);
1997 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2002 DEFUN (show_evpn_nh_vni_ip
,
2003 show_evpn_nh_vni_ip_cmd
,
2004 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2011 "Host address (ipv4 or ipv6)\n"
2016 bool uj
= use_json(argc
, argv
);
2018 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2019 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2021 vty_out(vty
, "%% Malformed Neighbor address\n");
2024 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2029 DEFUN (show_evpn_nh_vni
,
2030 show_evpn_nh_vni_cmd
,
2031 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2040 bool uj
= use_json(argc
, argv
);
2042 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2043 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2048 DEFUN (show_evpn_nh_vni_all
,
2049 show_evpn_nh_vni_all_cmd
,
2050 "show evpn next-hops vni all [json]",
2058 bool uj
= use_json(argc
, argv
);
2060 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2065 DEFUN (show_evpn_mac_vni
,
2066 show_evpn_mac_vni_cmd
,
2067 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2071 "VxLAN Network Identifier\n"
2075 struct zebra_vrf
*zvrf
;
2077 bool uj
= use_json(argc
, argv
);
2079 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2080 zvrf
= zebra_vrf_get_evpn();
2081 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2085 DEFUN (show_evpn_mac_vni_all
,
2086 show_evpn_mac_vni_all_cmd
,
2087 "show evpn mac vni all [json]",
2091 "VxLAN Network Identifier\n"
2095 struct zebra_vrf
*zvrf
;
2096 bool uj
= use_json(argc
, argv
);
2098 zvrf
= zebra_vrf_get_evpn();
2099 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2103 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2104 "show evpn mac vni all detail [json]",
2108 "VxLAN Network Identifier\n"
2110 "Detailed Information On Each VNI MAC\n"
2113 struct zebra_vrf
*zvrf
;
2114 bool uj
= use_json(argc
, argv
);
2116 zvrf
= zebra_vrf_get_evpn();
2117 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2121 DEFUN (show_evpn_mac_vni_all_vtep
,
2122 show_evpn_mac_vni_all_vtep_cmd
,
2123 "show evpn mac vni all vtep A.B.C.D [json]",
2127 "VxLAN Network Identifier\n"
2130 "Remote VTEP IP address\n"
2133 struct zebra_vrf
*zvrf
;
2134 struct in_addr vtep_ip
;
2135 bool uj
= use_json(argc
, argv
);
2137 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2139 vty_out(vty
, "%% Malformed VTEP IP address\n");
2142 zvrf
= zebra_vrf_get_evpn();
2143 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2149 DEFUN (show_evpn_mac_vni_mac
,
2150 show_evpn_mac_vni_mac_cmd
,
2151 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2155 "VxLAN Network Identifier\n"
2158 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2162 struct zebra_vrf
*zvrf
;
2165 bool uj
= use_json(argc
, argv
);
2167 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2168 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2169 vty_out(vty
, "%% Malformed MAC address");
2172 zvrf
= zebra_vrf_get_evpn();
2173 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2177 DEFUN (show_evpn_mac_vni_vtep
,
2178 show_evpn_mac_vni_vtep_cmd
,
2179 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2183 "VxLAN Network Identifier\n"
2186 "Remote VTEP IP address\n"
2189 struct zebra_vrf
*zvrf
;
2191 struct in_addr vtep_ip
;
2192 bool uj
= use_json(argc
, argv
);
2194 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2195 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2197 vty_out(vty
, "%% Malformed VTEP IP address\n");
2201 zvrf
= zebra_vrf_get_evpn();
2202 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2206 DEFPY (show_evpn_mac_vni_all_dad
,
2207 show_evpn_mac_vni_all_dad_cmd
,
2208 "show evpn mac vni all duplicate [json]",
2212 "VxLAN Network Identifier\n"
2214 "Duplicate address list\n"
2217 struct zebra_vrf
*zvrf
;
2218 bool uj
= use_json(argc
, argv
);
2220 zvrf
= zebra_vrf_get_evpn();
2221 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2226 DEFPY (show_evpn_mac_vni_dad
,
2227 show_evpn_mac_vni_dad_cmd
,
2228 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2232 "VxLAN Network Identifier\n"
2234 "Duplicate address list\n"
2237 struct zebra_vrf
*zvrf
;
2238 bool uj
= use_json(argc
, argv
);
2240 zvrf
= zebra_vrf_get_evpn();
2242 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2247 DEFPY (show_evpn_neigh_vni_dad
,
2248 show_evpn_neigh_vni_dad_cmd
,
2249 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2252 "ARP and ND cache\n"
2253 "VxLAN Network Identifier\n"
2255 "Duplicate address list\n"
2258 struct zebra_vrf
*zvrf
;
2259 bool uj
= use_json(argc
, argv
);
2261 zvrf
= zebra_vrf_get_evpn();
2262 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2266 DEFPY (show_evpn_neigh_vni_all_dad
,
2267 show_evpn_neigh_vni_all_dad_cmd
,
2268 "show evpn arp-cache vni all duplicate [json]",
2271 "ARP and ND cache\n"
2272 "VxLAN Network Identifier\n"
2274 "Duplicate address list\n"
2277 struct zebra_vrf
*zvrf
;
2278 bool uj
= use_json(argc
, argv
);
2280 zvrf
= zebra_vrf_get_evpn();
2281 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2286 DEFUN (show_evpn_neigh_vni
,
2287 show_evpn_neigh_vni_cmd
,
2288 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2291 "ARP and ND cache\n"
2292 "VxLAN Network Identifier\n"
2296 struct zebra_vrf
*zvrf
;
2298 bool uj
= use_json(argc
, argv
);
2300 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2301 zvrf
= zebra_vrf_get_evpn();
2302 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2306 DEFUN (show_evpn_neigh_vni_all
,
2307 show_evpn_neigh_vni_all_cmd
,
2308 "show evpn arp-cache vni all [json]",
2311 "ARP and ND cache\n"
2312 "VxLAN Network Identifier\n"
2316 struct zebra_vrf
*zvrf
;
2317 bool uj
= use_json(argc
, argv
);
2319 zvrf
= zebra_vrf_get_evpn();
2320 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2324 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2325 "show evpn arp-cache vni all detail [json]",
2328 "ARP and ND cache\n"
2329 "VxLAN Network Identifier\n"
2331 "Neighbor details for all vnis in detail\n" JSON_STR
)
2333 struct zebra_vrf
*zvrf
;
2334 bool uj
= use_json(argc
, argv
);
2336 zvrf
= zebra_vrf_get_evpn();
2337 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2341 DEFUN (show_evpn_neigh_vni_neigh
,
2342 show_evpn_neigh_vni_neigh_cmd
,
2343 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2346 "ARP and ND cache\n"
2347 "VxLAN Network Identifier\n"
2350 "Neighbor address (IPv4 or IPv6 address)\n"
2353 struct zebra_vrf
*zvrf
;
2356 bool uj
= use_json(argc
, argv
);
2358 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2359 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2361 vty_out(vty
, "%% Malformed Neighbor address\n");
2364 zvrf
= zebra_vrf_get_evpn();
2365 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2369 DEFUN (show_evpn_neigh_vni_vtep
,
2370 show_evpn_neigh_vni_vtep_cmd
,
2371 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2374 "ARP and ND cache\n"
2375 "VxLAN Network Identifier\n"
2378 "Remote VTEP IP address\n"
2381 struct zebra_vrf
*zvrf
;
2383 struct in_addr vtep_ip
;
2384 bool uj
= use_json(argc
, argv
);
2386 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2387 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2389 vty_out(vty
, "%% Malformed VTEP IP address\n");
2393 zvrf
= zebra_vrf_get_evpn();
2394 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2398 /* policy routing contexts */
2399 DEFUN (show_pbr_ipset
,
2401 "show pbr ipset [WORD]",
2403 "Policy-Based Routing\n"
2404 "IPset Context information\n"
2405 "IPset Name information\n")
2409 found
= argv_find(argv
, argc
, "WORD", &idx
);
2411 zebra_pbr_show_ipset_list(vty
, NULL
);
2413 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2417 /* policy routing contexts */
2418 DEFUN (show_pbr_iptable
,
2419 show_pbr_iptable_cmd
,
2420 "show pbr iptable [WORD]",
2422 "Policy-Based Routing\n"
2423 "IPtable Context information\n"
2424 "IPtable Name information\n")
2429 found
= argv_find(argv
, argc
, "WORD", &idx
);
2431 zebra_pbr_show_iptable(vty
, NULL
);
2433 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2437 DEFPY (clear_evpn_dup_addr
,
2438 clear_evpn_dup_addr_cmd
,
2439 "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>]>",
2442 "Duplicate address \n"
2443 "VxLAN Network Identifier\n"
2447 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2452 struct zebra_vrf
*zvrf
;
2453 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2454 int ret
= CMD_SUCCESS
;
2456 zvrf
= zebra_vrf_get_evpn();
2458 if (!is_zero_mac(&mac
->eth_addr
)) {
2459 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2463 if (sockunion_family(ip
) == AF_INET
) {
2464 host_ip
.ipa_type
= IPADDR_V4
;
2465 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2467 host_ip
.ipa_type
= IPADDR_V6
;
2468 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2469 sizeof(struct in6_addr
));
2471 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2475 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2478 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2484 /* Static ip route configuration write function. */
2485 static int zebra_ip_config(struct vty
*vty
)
2489 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2494 DEFUN (ip_zebra_import_table_distance
,
2495 ip_zebra_import_table_distance_cmd
,
2496 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2498 "import routes from non-main kernel table\n"
2499 "kernel routing table id\n"
2500 "Distance for imported routes\n"
2501 "Default distance value\n"
2502 "route-map for filtering\n"
2505 uint32_t table_id
= 0;
2507 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2508 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2510 strmatch(argv
[argc
- 2]->text
, "route-map")
2511 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2515 if (argc
== 7 || (argc
== 5 && !rmap
))
2516 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2518 if (!is_zebra_valid_kernel_table(table_id
)) {
2520 "Invalid routing table ID, %d. Must be in range 1-252\n",
2523 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2527 if (is_zebra_main_routing_table(table_id
)) {
2529 "Invalid routing table ID, %d. Must be non-default table\n",
2532 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2536 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2539 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2544 DEFUN_HIDDEN (zebra_packet_process
,
2545 zebra_packet_process_cmd
,
2546 "zebra zapi-packets (1-10000)",
2549 "Number of packets to process before relinquishing thread\n")
2551 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2553 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2554 memory_order_relaxed
);
2559 DEFUN_HIDDEN (no_zebra_packet_process
,
2560 no_zebra_packet_process_cmd
,
2561 "no zebra zapi-packets [(1-10000)]",
2565 "Number of packets to process before relinquishing thread\n")
2567 atomic_store_explicit(&zrouter
.packets_to_process
,
2568 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2569 memory_order_relaxed
);
2574 DEFUN_HIDDEN (zebra_workqueue_timer
,
2575 zebra_workqueue_timer_cmd
,
2576 "zebra work-queue (0-10000)",
2579 "Time in milliseconds\n")
2581 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2582 zrouter
.ribq
->spec
.hold
= timer
;
2587 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2588 no_zebra_workqueue_timer_cmd
,
2589 "no zebra work-queue [(0-10000)]",
2593 "Time in milliseconds\n")
2595 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2600 DEFUN (no_ip_zebra_import_table
,
2601 no_ip_zebra_import_table_cmd
,
2602 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2605 "import routes from non-main kernel table\n"
2606 "kernel routing table id\n"
2607 "Distance for imported routes\n"
2608 "Default distance value\n"
2609 "route-map for filtering\n"
2612 uint32_t table_id
= 0;
2613 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2615 if (!is_zebra_valid_kernel_table(table_id
)) {
2617 "Invalid routing table ID. Must be in range 1-252\n");
2621 if (is_zebra_main_routing_table(table_id
)) {
2623 "Invalid routing table ID, %d. Must be non-default table\n",
2628 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2631 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2634 static int config_write_protocol(struct vty
*vty
)
2637 vty_out(vty
, "allow-external-route-update\n");
2639 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2640 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2642 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2643 vty_out(vty
, "zebra zapi-packets %u\n",
2644 zrouter
.packets_to_process
);
2646 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2648 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2649 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2650 ipv4_multicast_mode
== MCAST_URIB_ONLY
2652 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2654 : ipv4_multicast_mode
2655 == MCAST_MIX_MRIB_FIRST
2657 : ipv4_multicast_mode
2658 == MCAST_MIX_DISTANCE
2662 /* Include dataplane info */
2663 dplane_config_write_helper(vty
);
2677 " Route Route Neighbor LSP LSP\n");
2679 "VRF Installs Removals Updates Installs Removals\n");
2681 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2682 struct zebra_vrf
*zvrf
= vrf
->info
;
2684 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2685 " %10" PRIu64
" %10" PRIu64
"\n",
2686 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2687 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2688 zvrf
->lsp_removals
);
2694 DEFUN (ip_forwarding
,
2698 "Turn on IP forwarding\n")
2704 ret
= ipforward_on();
2707 vty_out(vty
, "Can't turn on IP forwarding\n");
2708 return CMD_WARNING_CONFIG_FAILED
;
2714 DEFUN (no_ip_forwarding
,
2715 no_ip_forwarding_cmd
,
2719 "Turn off IP forwarding\n")
2725 ret
= ipforward_off();
2728 vty_out(vty
, "Can't turn off IP forwarding\n");
2729 return CMD_WARNING_CONFIG_FAILED
;
2735 /* Only display ip forwarding is enabled or not. */
2736 DEFUN (show_ip_forwarding
,
2737 show_ip_forwarding_cmd
,
2738 "show ip forwarding",
2741 "IP forwarding status\n")
2748 vty_out(vty
, "IP forwarding is off\n");
2750 vty_out(vty
, "IP forwarding is on\n");
2754 /* Only display ipv6 forwarding is enabled or not. */
2755 DEFUN (show_ipv6_forwarding
,
2756 show_ipv6_forwarding_cmd
,
2757 "show ipv6 forwarding",
2759 "IPv6 information\n"
2760 "Forwarding status\n")
2764 ret
= ipforward_ipv6();
2768 vty_out(vty
, "ipv6 forwarding is unknown\n");
2771 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2774 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2777 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2783 DEFUN (ipv6_forwarding
,
2784 ipv6_forwarding_cmd
,
2787 "Turn on IPv6 forwarding\n")
2791 ret
= ipforward_ipv6();
2793 ret
= ipforward_ipv6_on();
2796 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2797 return CMD_WARNING_CONFIG_FAILED
;
2803 DEFUN (no_ipv6_forwarding
,
2804 no_ipv6_forwarding_cmd
,
2805 "no ipv6 forwarding",
2808 "Turn off IPv6 forwarding\n")
2812 ret
= ipforward_ipv6();
2814 ret
= ipforward_ipv6_off();
2817 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2818 return CMD_WARNING_CONFIG_FAILED
;
2824 /* Display dataplane info */
2825 DEFUN (show_dataplane
,
2827 "show zebra dplane [detailed]",
2830 "Zebra dataplane information\n"
2831 "Detailed output\n")
2834 bool detailed
= false;
2836 if (argv_find(argv
, argc
, "detailed", &idx
))
2839 return dplane_show_helper(vty
, detailed
);
2842 /* Display dataplane providers info */
2843 DEFUN (show_dataplane_providers
,
2844 show_dataplane_providers_cmd
,
2845 "show zebra dplane providers [detailed]",
2848 "Zebra dataplane information\n"
2849 "Zebra dataplane provider information\n"
2850 "Detailed output\n")
2853 bool detailed
= false;
2855 if (argv_find(argv
, argc
, "detailed", &idx
))
2858 return dplane_show_provs_helper(vty
, detailed
);
2861 /* Configure dataplane incoming queue limit */
2862 DEFUN (zebra_dplane_queue_limit
,
2863 zebra_dplane_queue_limit_cmd
,
2864 "zebra dplane limit (0-10000)",
2867 "Limit incoming queued updates\n"
2868 "Number of queued updates\n")
2872 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2874 dplane_set_in_queue_limit(limit
, true);
2879 /* Reset dataplane queue limit to default value */
2880 DEFUN (no_zebra_dplane_queue_limit
,
2881 no_zebra_dplane_queue_limit_cmd
,
2882 "no zebra dplane limit [(0-10000)]",
2886 "Limit incoming queued updates\n"
2887 "Number of queued updates\n")
2889 dplane_set_in_queue_limit(0, false);
2894 DEFUN (zebra_show_routing_tables_summary
,
2895 zebra_show_routing_tables_summary_cmd
,
2896 "show zebra router table summary",
2899 "The Zebra Router Information\n"
2900 "Table Information about this Zebra Router\n"
2901 "Summary Information\n")
2903 zebra_router_show_table_summary(vty
);
2908 /* Table configuration write function. */
2909 static int config_write_table(struct vty
*vty
)
2914 /* IPForwarding configuration write function. */
2915 static int config_write_forwarding(struct vty
*vty
)
2917 /* FIXME: Find better place for that. */
2918 router_id_write(vty
);
2921 vty_out(vty
, "no ip forwarding\n");
2922 if (!ipforward_ipv6())
2923 vty_out(vty
, "no ipv6 forwarding\n");
2924 vty_out(vty
, "!\n");
2928 DEFUN_HIDDEN (show_frr
,
2934 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
2935 vty_out(vty
, ".............................7777:..............................................\n");
2936 vty_out(vty
, ".............................777777,............................................\n");
2937 vty_out(vty
, "... .........................77777777,..........................................\n");
2938 vty_out(vty
, "............................=7777777777:........................................\n");
2939 vty_out(vty
, "........................:7777777777777777,......................................\n");
2940 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
2941 vty_out(vty
, "...................I7777777777+.................................................\n");
2942 vty_out(vty
, "................,777777777?............ .......................................\n");
2943 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
2944 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
2945 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
2946 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
2947 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
2948 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
2949 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
2950 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
2951 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
2952 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
2953 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
2954 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
2955 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
2956 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
2957 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
2958 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
2959 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
2960 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
2961 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
2962 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
2963 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
2964 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
2965 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
2966 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
2967 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
2968 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
2969 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
2970 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
2971 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
2972 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
2973 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
2974 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
2975 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
2976 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
2977 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
2978 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
2979 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
2980 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
2981 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
2982 vty_out(vty
, "............................~777777777777..............+777777..................\n");
2983 vty_out(vty
, "................................~77777777...............=777777.................\n");
2984 vty_out(vty
, ".....................................:=?I................~777777................\n");
2985 vty_out(vty
, "..........................................................:777777,..............\n");
2986 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
2991 /* IP node for static routes. */
2992 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2993 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2994 /* table node for routing tables. */
2995 static struct cmd_node table_node
= {TABLE_NODE
,
2996 "", /* This node has no interface. */
2998 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2999 "", /* This node has no interface. */
3003 void zebra_vty_init(void)
3005 /* Install configuration write function. */
3006 install_node(&table_node
, config_write_table
);
3007 install_node(&forwarding_node
, config_write_forwarding
);
3009 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3010 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3011 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3012 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3014 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3015 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3016 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3019 zebra_route_map_init();
3021 install_node(&ip_node
, zebra_ip_config
);
3022 install_node(&protocol_node
, config_write_protocol
);
3024 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3025 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3027 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3028 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3030 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3031 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3032 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3033 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3034 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3035 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3037 install_element(VIEW_NODE
, &show_vrf_cmd
);
3038 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3039 install_element(VIEW_NODE
, &show_route_cmd
);
3040 install_element(VIEW_NODE
, &show_route_table_cmd
);
3041 if (vrf_is_backend_netns())
3042 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3043 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3044 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3045 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3046 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3048 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3049 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3051 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3052 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3053 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3054 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3055 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3056 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3057 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3058 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3059 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3061 /* Commands for VRF */
3062 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3064 install_element(VIEW_NODE
, &show_frr_cmd
);
3065 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3066 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3067 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3068 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3069 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3070 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3071 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3072 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3073 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3074 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3075 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3076 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3077 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3078 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3079 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3080 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3081 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3082 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3083 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3084 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3085 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3086 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3087 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3088 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3089 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3090 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3092 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3093 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3095 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3096 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3097 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3098 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3100 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3101 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3102 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3103 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3105 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);