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
, false, 0,
1030 false, false, 0, 0, !!json
, zrt
->tableid
);
1037 "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]",
1041 "IP nexthop tracking table\n"
1042 "IP import check tracking table\n"
1048 VRF_ALL_CMD_HELP_STR
)
1050 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1051 vrf_id_t vrf_id
= VRF_DEFAULT
;
1052 struct prefix prefix
, *p
= NULL
;
1055 if (strcmp(type
, "nht") == 0)
1056 rtype
= RNH_NEXTHOP_TYPE
;
1058 rtype
= RNH_IMPORT_CHECK_TYPE
;
1062 struct zebra_vrf
*zvrf
;
1064 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1065 if ((zvrf
= vrf
->info
) != NULL
) {
1066 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1067 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1073 VRF_GET_ID(vrf_id
, vrf_name
, false);
1075 memset(&prefix
, 0, sizeof(prefix
));
1077 p
= sockunion2hostprefix(addr
, &prefix
);
1079 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1083 DEFUN (ip_nht_default_route
,
1084 ip_nht_default_route_cmd
,
1085 "ip nht resolve-via-default",
1087 "Filter Next Hop tracking route resolution\n"
1088 "Resolve via default route\n")
1090 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1095 if (zvrf
->zebra_rnh_ip_default_route
)
1098 zvrf
->zebra_rnh_ip_default_route
= 1;
1100 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1104 DEFUN (no_ip_nht_default_route
,
1105 no_ip_nht_default_route_cmd
,
1106 "no ip nht resolve-via-default",
1109 "Filter Next Hop tracking route resolution\n"
1110 "Resolve via default route\n")
1112 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1117 if (!zvrf
->zebra_rnh_ip_default_route
)
1120 zvrf
->zebra_rnh_ip_default_route
= 0;
1121 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1125 DEFUN (ipv6_nht_default_route
,
1126 ipv6_nht_default_route_cmd
,
1127 "ipv6 nht resolve-via-default",
1129 "Filter Next Hop tracking route resolution\n"
1130 "Resolve via default route\n")
1132 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1137 if (zvrf
->zebra_rnh_ipv6_default_route
)
1140 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1141 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1145 DEFUN (no_ipv6_nht_default_route
,
1146 no_ipv6_nht_default_route_cmd
,
1147 "no ipv6 nht resolve-via-default",
1150 "Filter Next Hop tracking route resolution\n"
1151 "Resolve via default route\n")
1154 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1159 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1162 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1163 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1171 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1174 |A.B.C.D/M$prefix longer-prefixes\
1175 |supernets-only$supernets_only\
1178 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1179 |ospf$type_str (1-65535)$ospf_instance_id\
1181 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1184 |X:X::X:X/M$prefix longer-prefixes\
1186 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1191 "IP forwarding table\n"
1192 "IP routing table\n"
1193 VRF_FULL_CMD_HELP_STR
1194 "Show only routes with tag\n"
1196 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1197 "Show route matching the specified Network/Mask pair only\n"
1198 "Show supernet entries only\n"
1199 FRR_IP_REDIST_HELP_STR_ZEBRA
1200 "Open Shortest Path First (OSPFv2)\n"
1203 "IP forwarding table\n"
1204 "IP routing table\n"
1205 VRF_FULL_CMD_HELP_STR
1206 "Show only routes with tag\n"
1209 "Show route matching the specified Network/Mask pair only\n"
1210 FRR_IP6_REDIST_HELP_STR_ZEBRA
1213 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1218 type
= proto_redistnum(afi
, type_str
);
1220 vty_out(vty
, "Unknown route type\n");
1226 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1227 struct zebra_vrf
*zvrf
;
1228 struct route_table
*table
;
1230 if ((zvrf
= vrf
->info
) == NULL
1231 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1235 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1236 !!json
, tag
, prefix_str
? prefix
: NULL
,
1237 !!supernets_only
, type
, ospf_instance_id
);
1240 vrf_id_t vrf_id
= VRF_DEFAULT
;
1243 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1244 vrf
= vrf_lookup_by_id(vrf_id
);
1245 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1246 !!json
, tag
, prefix_str
? prefix
: NULL
,
1247 !!supernets_only
, type
, ospf_instance_id
);
1253 DEFPY (show_route_detail
,
1254 show_route_detail_cmd
,
1257 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1262 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1271 "IPv6 forwarding table\n"
1272 "IP routing table\n"
1273 VRF_FULL_CMD_HELP_STR
1274 "Network in the IP routing table to display\n"
1275 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1277 "IPv6 forwarding table\n"
1278 "IPv6 routing table\n"
1279 VRF_FULL_CMD_HELP_STR
1284 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1285 struct route_table
*table
;
1287 struct route_node
*rn
;
1288 bool use_fib
= !!fib
;
1290 bool network_found
= false;
1293 prefix_str
= address_str
;
1294 if (str2prefix(prefix_str
, &p
) < 0) {
1295 vty_out(vty
, "%% Malformed address\n");
1301 struct zebra_vrf
*zvrf
;
1303 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1304 if ((zvrf
= vrf
->info
) == NULL
1305 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1308 rn
= route_node_match(table
, &p
);
1311 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1312 route_unlock_node(rn
);
1316 dest
= rib_dest_from_rnode(rn
);
1317 if (use_fib
&& !dest
->selected_fib
) {
1318 route_unlock_node(rn
);
1322 network_found
= true;
1324 vty_show_ip_route_detail_json(vty
, rn
,
1327 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1329 route_unlock_node(rn
);
1332 if (!network_found
) {
1334 vty_out(vty
, "{}\n");
1338 "%% Network not in FIB\n");
1341 "%% Network not in RIB\n");
1346 vrf_id_t vrf_id
= VRF_DEFAULT
;
1349 VRF_GET_ID(vrf_id
, vrf_name
, false);
1351 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1355 rn
= route_node_match(table
, &p
);
1357 dest
= rib_dest_from_rnode(rn
);
1359 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1360 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1362 vty_out(vty
, "{}\n");
1366 "%% Network not in FIB\n");
1369 "%% Network not in table\n");
1372 route_unlock_node(rn
);
1377 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1379 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1381 route_unlock_node(rn
);
1387 DEFPY (show_route_summary
,
1388 show_route_summary_cmd
,
1389 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1390 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1394 "IP routing table\n"
1395 VRF_FULL_CMD_HELP_STR
1396 "Summary of all routes\n"
1397 "Table to display summary for\n"
1398 "The table number\n"
1401 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1402 struct route_table
*table
;
1405 table_id
= RT_TABLE_MAIN
;
1409 struct zebra_vrf
*zvrf
;
1411 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1412 if ((zvrf
= vrf
->info
) == NULL
)
1415 table
= zebra_vrf_table_with_table_id(afi
,
1423 vty_show_ip_route_summary_prefix(vty
, table
);
1425 vty_show_ip_route_summary(vty
, table
);
1428 vrf_id_t vrf_id
= VRF_DEFAULT
;
1431 VRF_GET_ID(vrf_id
, vrf_name
, false);
1433 table
= zebra_vrf_table_with_table_id(afi
,
1440 vty_show_ip_route_summary_prefix(vty
, table
);
1442 vty_show_ip_route_summary(vty
, table
);
1448 static void vty_show_ip_route_summary(struct vty
*vty
,
1449 struct route_table
*table
)
1451 struct route_node
*rn
;
1452 struct route_entry
*re
;
1453 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1454 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1455 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1456 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1460 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1461 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1462 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1463 RNODE_FOREACH_RE (rn
, re
) {
1464 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1465 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1467 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1469 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1471 rib_cnt
[re
->type
]++;
1473 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1474 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1477 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1479 fib_cnt
[re
->type
]++;
1483 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1484 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1486 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1487 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1488 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1489 if (i
== ZEBRA_ROUTE_BGP
) {
1490 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1491 rib_cnt
[ZEBRA_ROUTE_BGP
],
1492 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1493 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1494 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1495 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1497 vty_out(vty
, "%-20s %-20d %-20d \n",
1498 zebra_route_string(i
), rib_cnt
[i
],
1503 vty_out(vty
, "------\n");
1504 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1505 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1510 * Implementation of the ip route summary prefix command.
1512 * This command prints the primary prefixes that have been installed by various
1513 * protocols on the box.
1516 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1517 struct route_table
*table
)
1519 struct route_node
*rn
;
1520 struct route_entry
*re
;
1521 struct nexthop
*nexthop
;
1522 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1523 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1524 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1525 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1529 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1530 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1531 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1532 RNODE_FOREACH_RE (rn
, re
) {
1535 * In case of ECMP, count only once.
1538 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1539 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1540 fib_cnt
[re
->type
]++;
1542 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1543 nexthop
= nexthop
->next
) {
1545 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1546 rib_cnt
[re
->type
]++;
1547 if (re
->type
== ZEBRA_ROUTE_BGP
1548 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1549 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1550 if (CHECK_FLAG(re
->status
,
1551 ROUTE_ENTRY_INSTALLED
))
1552 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1557 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1558 "Prefix Routes", "FIB",
1559 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1561 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1562 if (rib_cnt
[i
] > 0) {
1563 if (i
== ZEBRA_ROUTE_BGP
) {
1564 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1565 rib_cnt
[ZEBRA_ROUTE_BGP
]
1566 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1567 fib_cnt
[ZEBRA_ROUTE_BGP
]
1568 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1569 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1570 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1571 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1573 vty_out(vty
, "%-20s %-20d %-20d \n",
1574 zebra_route_string(i
), rib_cnt
[i
],
1579 vty_out(vty
, "------\n");
1580 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1581 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1586 * Show IPv6 mroute command.Used to dump
1587 * the Multicast routing table.
1589 DEFUN (show_ipv6_mroute
,
1590 show_ipv6_mroute_cmd
,
1591 "show ipv6 mroute [vrf NAME]",
1594 "IPv6 Multicast routing table\n"
1597 struct route_table
*table
;
1598 struct route_node
*rn
;
1599 struct route_entry
*re
;
1601 vrf_id_t vrf_id
= VRF_DEFAULT
;
1604 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1606 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1610 /* Show all IPv6 route. */
1611 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1612 RNODE_FOREACH_RE (rn
, re
) {
1614 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1617 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1622 DEFUN (show_ipv6_mroute_vrf_all
,
1623 show_ipv6_mroute_vrf_all_cmd
,
1624 "show ipv6 mroute vrf all",
1627 "IPv6 Multicast routing table\n"
1628 VRF_ALL_CMD_HELP_STR
)
1630 struct route_table
*table
;
1631 struct route_node
*rn
;
1632 struct route_entry
*re
;
1634 struct zebra_vrf
*zvrf
;
1637 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1638 if ((zvrf
= vrf
->info
) == NULL
1639 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1642 /* Show all IPv6 route. */
1643 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1644 RNODE_FOREACH_RE (rn
, re
) {
1646 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1649 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1655 DEFUN (allow_external_route_update
,
1656 allow_external_route_update_cmd
,
1657 "allow-external-route-update",
1658 "Allow FRR routes to be overwritten by external processes\n")
1665 DEFUN (no_allow_external_route_update
,
1666 no_allow_external_route_update_cmd
,
1667 "no allow-external-route-update",
1669 "Allow FRR routes to be overwritten by external processes\n")
1684 struct zebra_vrf
*zvrf
;
1686 if (vrf_is_backend_netns())
1687 vty_out(vty
, "netns-based vrfs\n");
1689 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1690 if (!(zvrf
= vrf
->info
))
1692 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1695 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1696 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1697 vty_out(vty
, "inactive");
1698 else if (zvrf_ns_name(zvrf
))
1699 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1700 zvrf_ns_name(zvrf
));
1702 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1704 if (vrf_is_user_cfged(vrf
))
1705 vty_out(vty
, " (configured)");
1712 DEFUN (default_vrf_vni_mapping
,
1713 default_vrf_vni_mapping_cmd
,
1714 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1715 "VNI corresponding to the DEFAULT VRF\n"
1717 "Prefix routes only \n")
1720 char err
[ERR_STR_SZ
];
1721 struct zebra_vrf
*zvrf
= NULL
;
1722 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1725 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1732 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1735 vty_out(vty
, "%s\n", err
);
1742 DEFUN (no_default_vrf_vni_mapping
,
1743 no_default_vrf_vni_mapping_cmd
,
1744 "no vni " CMD_VNI_RANGE
,
1746 "VNI corresponding to DEFAULT VRF\n"
1750 char err
[ERR_STR_SZ
];
1751 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1752 struct zebra_vrf
*zvrf
= NULL
;
1754 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1758 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1760 vty_out(vty
, "%s\n", err
);
1767 DEFUN (vrf_vni_mapping
,
1768 vrf_vni_mapping_cmd
,
1769 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1770 "VNI corresponding to tenant VRF\n"
1772 "prefix-routes-only\n")
1777 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1778 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1779 char err
[ERR_STR_SZ
];
1787 /* Mark as having FRR configuration */
1788 vrf_set_user_cfged(vrf
);
1789 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1792 vty_out(vty
, "%s\n", err
);
1799 DEFUN (no_vrf_vni_mapping
,
1800 no_vrf_vni_mapping_cmd
,
1801 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1803 "VNI corresponding to tenant VRF\n"
1805 "prefix-routes-only\n")
1809 char err
[ERR_STR_SZ
];
1810 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1812 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1820 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1821 ERR_STR_SZ
, filter
, 0);
1823 vty_out(vty
, "%s\n", err
);
1827 /* If no other FRR config for this VRF, mark accordingly. */
1828 if (!zebra_vrf_has_config(zvrf
))
1829 vrf_reset_user_cfged(vrf
);
1835 DEFUN (show_vrf_vni
,
1837 "show vrf vni [json]",
1844 struct zebra_vrf
*zvrf
;
1845 json_object
*json
= NULL
;
1846 json_object
*json_vrfs
= NULL
;
1847 bool uj
= use_json(argc
, argv
);
1850 json
= json_object_new_object();
1851 json_vrfs
= json_object_new_array();
1855 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1856 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1858 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1863 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1867 json_object_object_add(json
, "vrfs", json_vrfs
);
1868 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1869 json
, JSON_C_TO_STRING_PRETTY
));
1870 json_object_free(json
);
1876 DEFUN (show_evpn_global
,
1877 show_evpn_global_cmd
,
1883 bool uj
= use_json(argc
, argv
);
1885 zebra_vxlan_print_evpn(vty
, uj
);
1889 DEFUN (show_evpn_vni
,
1891 "show evpn vni [json]",
1894 "VxLAN Network Identifier\n"
1897 struct zebra_vrf
*zvrf
;
1898 bool uj
= use_json(argc
, argv
);
1900 zvrf
= zebra_vrf_get_evpn();
1901 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1905 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1906 "show evpn vni detail [json]",
1909 "VxLAN Network Identifier\n"
1910 "Detailed Information On Each VNI\n"
1913 struct zebra_vrf
*zvrf
;
1914 bool uj
= use_json(argc
, argv
);
1916 zvrf
= zebra_vrf_get_evpn();
1917 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1921 DEFUN (show_evpn_vni_vni
,
1922 show_evpn_vni_vni_cmd
,
1923 "show evpn vni " CMD_VNI_RANGE
"[json]",
1926 "VxLAN Network Identifier\n"
1930 struct zebra_vrf
*zvrf
;
1932 bool uj
= use_json(argc
, argv
);
1934 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1935 zvrf
= zebra_vrf_get_evpn();
1936 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1940 DEFUN (show_evpn_rmac_vni_mac
,
1941 show_evpn_rmac_vni_mac_cmd
,
1942 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1949 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1954 bool uj
= use_json(argc
, argv
);
1956 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1957 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1958 vty_out(vty
, "%% Malformed MAC address\n");
1961 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1965 DEFUN (show_evpn_rmac_vni
,
1966 show_evpn_rmac_vni_cmd
,
1967 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1976 bool uj
= use_json(argc
, argv
);
1978 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1979 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1984 DEFUN (show_evpn_rmac_vni_all
,
1985 show_evpn_rmac_vni_all_cmd
,
1986 "show evpn rmac vni all [json]",
1994 bool uj
= use_json(argc
, argv
);
1996 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2001 DEFUN (show_evpn_nh_vni_ip
,
2002 show_evpn_nh_vni_ip_cmd
,
2003 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2010 "Host address (ipv4 or ipv6)\n"
2015 bool uj
= use_json(argc
, argv
);
2017 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2018 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2020 vty_out(vty
, "%% Malformed Neighbor address\n");
2023 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2028 DEFUN (show_evpn_nh_vni
,
2029 show_evpn_nh_vni_cmd
,
2030 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2039 bool uj
= use_json(argc
, argv
);
2041 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2042 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2047 DEFUN (show_evpn_nh_vni_all
,
2048 show_evpn_nh_vni_all_cmd
,
2049 "show evpn next-hops vni all [json]",
2057 bool uj
= use_json(argc
, argv
);
2059 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2064 DEFUN (show_evpn_mac_vni
,
2065 show_evpn_mac_vni_cmd
,
2066 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2070 "VxLAN Network Identifier\n"
2074 struct zebra_vrf
*zvrf
;
2076 bool uj
= use_json(argc
, argv
);
2078 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2079 zvrf
= zebra_vrf_get_evpn();
2080 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2084 DEFUN (show_evpn_mac_vni_all
,
2085 show_evpn_mac_vni_all_cmd
,
2086 "show evpn mac vni all [json]",
2090 "VxLAN Network Identifier\n"
2094 struct zebra_vrf
*zvrf
;
2095 bool uj
= use_json(argc
, argv
);
2097 zvrf
= zebra_vrf_get_evpn();
2098 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2102 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2103 "show evpn mac vni all detail [json]",
2107 "VxLAN Network Identifier\n"
2109 "Detailed Information On Each VNI MAC\n"
2112 struct zebra_vrf
*zvrf
;
2113 bool uj
= use_json(argc
, argv
);
2115 zvrf
= zebra_vrf_get_evpn();
2116 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2120 DEFUN (show_evpn_mac_vni_all_vtep
,
2121 show_evpn_mac_vni_all_vtep_cmd
,
2122 "show evpn mac vni all vtep A.B.C.D [json]",
2126 "VxLAN Network Identifier\n"
2129 "Remote VTEP IP address\n"
2132 struct zebra_vrf
*zvrf
;
2133 struct in_addr vtep_ip
;
2134 bool uj
= use_json(argc
, argv
);
2136 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2138 vty_out(vty
, "%% Malformed VTEP IP address\n");
2141 zvrf
= zebra_vrf_get_evpn();
2142 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2148 DEFUN (show_evpn_mac_vni_mac
,
2149 show_evpn_mac_vni_mac_cmd
,
2150 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2154 "VxLAN Network Identifier\n"
2157 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2161 struct zebra_vrf
*zvrf
;
2164 bool uj
= use_json(argc
, argv
);
2166 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2167 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2168 vty_out(vty
, "%% Malformed MAC address");
2171 zvrf
= zebra_vrf_get_evpn();
2172 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2176 DEFUN (show_evpn_mac_vni_vtep
,
2177 show_evpn_mac_vni_vtep_cmd
,
2178 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2182 "VxLAN Network Identifier\n"
2185 "Remote VTEP IP address\n"
2188 struct zebra_vrf
*zvrf
;
2190 struct in_addr vtep_ip
;
2191 bool uj
= use_json(argc
, argv
);
2193 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2194 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2196 vty_out(vty
, "%% Malformed VTEP IP address\n");
2200 zvrf
= zebra_vrf_get_evpn();
2201 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2205 DEFPY (show_evpn_mac_vni_all_dad
,
2206 show_evpn_mac_vni_all_dad_cmd
,
2207 "show evpn mac vni all duplicate [json]",
2211 "VxLAN Network Identifier\n"
2213 "Duplicate address list\n"
2216 struct zebra_vrf
*zvrf
;
2217 bool uj
= use_json(argc
, argv
);
2219 zvrf
= zebra_vrf_get_evpn();
2220 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2225 DEFPY (show_evpn_mac_vni_dad
,
2226 show_evpn_mac_vni_dad_cmd
,
2227 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2231 "VxLAN Network Identifier\n"
2233 "Duplicate address list\n"
2236 struct zebra_vrf
*zvrf
;
2237 bool uj
= use_json(argc
, argv
);
2239 zvrf
= zebra_vrf_get_evpn();
2241 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2246 DEFPY (show_evpn_neigh_vni_dad
,
2247 show_evpn_neigh_vni_dad_cmd
,
2248 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2251 "ARP and ND cache\n"
2252 "VxLAN Network Identifier\n"
2254 "Duplicate address list\n"
2257 struct zebra_vrf
*zvrf
;
2258 bool uj
= use_json(argc
, argv
);
2260 zvrf
= zebra_vrf_get_evpn();
2261 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2265 DEFPY (show_evpn_neigh_vni_all_dad
,
2266 show_evpn_neigh_vni_all_dad_cmd
,
2267 "show evpn arp-cache vni all duplicate [json]",
2270 "ARP and ND cache\n"
2271 "VxLAN Network Identifier\n"
2273 "Duplicate address list\n"
2276 struct zebra_vrf
*zvrf
;
2277 bool uj
= use_json(argc
, argv
);
2279 zvrf
= zebra_vrf_get_evpn();
2280 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2285 DEFUN (show_evpn_neigh_vni
,
2286 show_evpn_neigh_vni_cmd
,
2287 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2290 "ARP and ND cache\n"
2291 "VxLAN Network Identifier\n"
2295 struct zebra_vrf
*zvrf
;
2297 bool uj
= use_json(argc
, argv
);
2299 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2300 zvrf
= zebra_vrf_get_evpn();
2301 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2305 DEFUN (show_evpn_neigh_vni_all
,
2306 show_evpn_neigh_vni_all_cmd
,
2307 "show evpn arp-cache vni all [json]",
2310 "ARP and ND cache\n"
2311 "VxLAN Network Identifier\n"
2315 struct zebra_vrf
*zvrf
;
2316 bool uj
= use_json(argc
, argv
);
2318 zvrf
= zebra_vrf_get_evpn();
2319 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2323 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2324 "show evpn arp-cache vni all detail [json]",
2327 "ARP and ND cache\n"
2328 "VxLAN Network Identifier\n"
2330 "Neighbor details for all vnis in detail\n" JSON_STR
)
2332 struct zebra_vrf
*zvrf
;
2333 bool uj
= use_json(argc
, argv
);
2335 zvrf
= zebra_vrf_get_evpn();
2336 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2340 DEFUN (show_evpn_neigh_vni_neigh
,
2341 show_evpn_neigh_vni_neigh_cmd
,
2342 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2345 "ARP and ND cache\n"
2346 "VxLAN Network Identifier\n"
2349 "Neighbor address (IPv4 or IPv6 address)\n"
2352 struct zebra_vrf
*zvrf
;
2355 bool uj
= use_json(argc
, argv
);
2357 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2358 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2360 vty_out(vty
, "%% Malformed Neighbor address\n");
2363 zvrf
= zebra_vrf_get_evpn();
2364 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2368 DEFUN (show_evpn_neigh_vni_vtep
,
2369 show_evpn_neigh_vni_vtep_cmd
,
2370 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2373 "ARP and ND cache\n"
2374 "VxLAN Network Identifier\n"
2377 "Remote VTEP IP address\n"
2380 struct zebra_vrf
*zvrf
;
2382 struct in_addr vtep_ip
;
2383 bool uj
= use_json(argc
, argv
);
2385 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2386 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2388 vty_out(vty
, "%% Malformed VTEP IP address\n");
2392 zvrf
= zebra_vrf_get_evpn();
2393 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2397 /* policy routing contexts */
2398 DEFUN (show_pbr_ipset
,
2400 "show pbr ipset [WORD]",
2402 "Policy-Based Routing\n"
2403 "IPset Context information\n"
2404 "IPset Name information\n")
2408 found
= argv_find(argv
, argc
, "WORD", &idx
);
2410 zebra_pbr_show_ipset_list(vty
, NULL
);
2412 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2416 /* policy routing contexts */
2417 DEFUN (show_pbr_iptable
,
2418 show_pbr_iptable_cmd
,
2419 "show pbr iptable [WORD]",
2421 "Policy-Based Routing\n"
2422 "IPtable Context information\n"
2423 "IPtable Name information\n")
2428 found
= argv_find(argv
, argc
, "WORD", &idx
);
2430 zebra_pbr_show_iptable(vty
, NULL
);
2432 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2436 DEFPY (clear_evpn_dup_addr
,
2437 clear_evpn_dup_addr_cmd
,
2438 "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>]>",
2441 "Duplicate address \n"
2442 "VxLAN Network Identifier\n"
2446 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2451 struct zebra_vrf
*zvrf
;
2452 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2453 int ret
= CMD_SUCCESS
;
2455 zvrf
= zebra_vrf_get_evpn();
2457 if (!is_zero_mac(&mac
->eth_addr
)) {
2458 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2462 if (sockunion_family(ip
) == AF_INET
) {
2463 host_ip
.ipa_type
= IPADDR_V4
;
2464 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2466 host_ip
.ipa_type
= IPADDR_V6
;
2467 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2468 sizeof(struct in6_addr
));
2470 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2474 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2477 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2483 /* Static ip route configuration write function. */
2484 static int zebra_ip_config(struct vty
*vty
)
2488 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2493 DEFUN (ip_zebra_import_table_distance
,
2494 ip_zebra_import_table_distance_cmd
,
2495 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2497 "import routes from non-main kernel table\n"
2498 "kernel routing table id\n"
2499 "Distance for imported routes\n"
2500 "Default distance value\n"
2501 "route-map for filtering\n"
2504 uint32_t table_id
= 0;
2506 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2507 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2509 strmatch(argv
[argc
- 2]->text
, "route-map")
2510 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2514 if (argc
== 7 || (argc
== 5 && !rmap
))
2515 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2517 if (!is_zebra_valid_kernel_table(table_id
)) {
2519 "Invalid routing table ID, %d. Must be in range 1-252\n",
2522 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2526 if (is_zebra_main_routing_table(table_id
)) {
2528 "Invalid routing table ID, %d. Must be non-default table\n",
2531 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2535 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2538 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2543 DEFUN_HIDDEN (zebra_packet_process
,
2544 zebra_packet_process_cmd
,
2545 "zebra zapi-packets (1-10000)",
2548 "Number of packets to process before relinquishing thread\n")
2550 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2552 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2553 memory_order_relaxed
);
2558 DEFUN_HIDDEN (no_zebra_packet_process
,
2559 no_zebra_packet_process_cmd
,
2560 "no zebra zapi-packets [(1-10000)]",
2564 "Number of packets to process before relinquishing thread\n")
2566 atomic_store_explicit(&zrouter
.packets_to_process
,
2567 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2568 memory_order_relaxed
);
2573 DEFUN_HIDDEN (zebra_workqueue_timer
,
2574 zebra_workqueue_timer_cmd
,
2575 "zebra work-queue (0-10000)",
2578 "Time in milliseconds\n")
2580 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2581 zrouter
.ribq
->spec
.hold
= timer
;
2586 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2587 no_zebra_workqueue_timer_cmd
,
2588 "no zebra work-queue [(0-10000)]",
2592 "Time in milliseconds\n")
2594 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2599 DEFUN (no_ip_zebra_import_table
,
2600 no_ip_zebra_import_table_cmd
,
2601 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2604 "import routes from non-main kernel table\n"
2605 "kernel routing table id\n"
2606 "Distance for imported routes\n"
2607 "Default distance value\n"
2608 "route-map for filtering\n"
2611 uint32_t table_id
= 0;
2612 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2614 if (!is_zebra_valid_kernel_table(table_id
)) {
2616 "Invalid routing table ID. Must be in range 1-252\n");
2620 if (is_zebra_main_routing_table(table_id
)) {
2622 "Invalid routing table ID, %d. Must be non-default table\n",
2627 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2630 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2633 static int config_write_protocol(struct vty
*vty
)
2636 vty_out(vty
, "allow-external-route-update\n");
2638 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2639 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2641 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2642 vty_out(vty
, "zebra zapi-packets %u\n",
2643 zrouter
.packets_to_process
);
2645 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2647 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2648 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2649 ipv4_multicast_mode
== MCAST_URIB_ONLY
2651 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2653 : ipv4_multicast_mode
2654 == MCAST_MIX_MRIB_FIRST
2656 : ipv4_multicast_mode
2657 == MCAST_MIX_DISTANCE
2661 /* Include dataplane info */
2662 dplane_config_write_helper(vty
);
2676 " Route Route Neighbor LSP LSP\n");
2678 "VRF Installs Removals Updates Installs Removals\n");
2680 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2681 struct zebra_vrf
*zvrf
= vrf
->info
;
2683 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2684 " %10" PRIu64
" %10" PRIu64
"\n",
2685 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2686 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2687 zvrf
->lsp_removals
);
2693 DEFUN (ip_forwarding
,
2697 "Turn on IP forwarding\n")
2703 ret
= ipforward_on();
2706 vty_out(vty
, "Can't turn on IP forwarding\n");
2707 return CMD_WARNING_CONFIG_FAILED
;
2713 DEFUN (no_ip_forwarding
,
2714 no_ip_forwarding_cmd
,
2718 "Turn off IP forwarding\n")
2724 ret
= ipforward_off();
2727 vty_out(vty
, "Can't turn off IP forwarding\n");
2728 return CMD_WARNING_CONFIG_FAILED
;
2734 /* Only display ip forwarding is enabled or not. */
2735 DEFUN (show_ip_forwarding
,
2736 show_ip_forwarding_cmd
,
2737 "show ip forwarding",
2740 "IP forwarding status\n")
2747 vty_out(vty
, "IP forwarding is off\n");
2749 vty_out(vty
, "IP forwarding is on\n");
2753 /* Only display ipv6 forwarding is enabled or not. */
2754 DEFUN (show_ipv6_forwarding
,
2755 show_ipv6_forwarding_cmd
,
2756 "show ipv6 forwarding",
2758 "IPv6 information\n"
2759 "Forwarding status\n")
2763 ret
= ipforward_ipv6();
2767 vty_out(vty
, "ipv6 forwarding is unknown\n");
2770 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2773 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2776 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2782 DEFUN (ipv6_forwarding
,
2783 ipv6_forwarding_cmd
,
2786 "Turn on IPv6 forwarding\n")
2790 ret
= ipforward_ipv6();
2792 ret
= ipforward_ipv6_on();
2795 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2796 return CMD_WARNING_CONFIG_FAILED
;
2802 DEFUN (no_ipv6_forwarding
,
2803 no_ipv6_forwarding_cmd
,
2804 "no ipv6 forwarding",
2807 "Turn off IPv6 forwarding\n")
2811 ret
= ipforward_ipv6();
2813 ret
= ipforward_ipv6_off();
2816 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2817 return CMD_WARNING_CONFIG_FAILED
;
2823 /* Display dataplane info */
2824 DEFUN (show_dataplane
,
2826 "show zebra dplane [detailed]",
2829 "Zebra dataplane information\n"
2830 "Detailed output\n")
2833 bool detailed
= false;
2835 if (argv_find(argv
, argc
, "detailed", &idx
))
2838 return dplane_show_helper(vty
, detailed
);
2841 /* Display dataplane providers info */
2842 DEFUN (show_dataplane_providers
,
2843 show_dataplane_providers_cmd
,
2844 "show zebra dplane providers [detailed]",
2847 "Zebra dataplane information\n"
2848 "Zebra dataplane provider information\n"
2849 "Detailed output\n")
2852 bool detailed
= false;
2854 if (argv_find(argv
, argc
, "detailed", &idx
))
2857 return dplane_show_provs_helper(vty
, detailed
);
2860 /* Configure dataplane incoming queue limit */
2861 DEFUN (zebra_dplane_queue_limit
,
2862 zebra_dplane_queue_limit_cmd
,
2863 "zebra dplane limit (0-10000)",
2866 "Limit incoming queued updates\n"
2867 "Number of queued updates\n")
2871 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2873 dplane_set_in_queue_limit(limit
, true);
2878 /* Reset dataplane queue limit to default value */
2879 DEFUN (no_zebra_dplane_queue_limit
,
2880 no_zebra_dplane_queue_limit_cmd
,
2881 "no zebra dplane limit [(0-10000)]",
2885 "Limit incoming queued updates\n"
2886 "Number of queued updates\n")
2888 dplane_set_in_queue_limit(0, false);
2893 DEFUN (zebra_show_routing_tables_summary
,
2894 zebra_show_routing_tables_summary_cmd
,
2895 "show zebra router table summary",
2898 "The Zebra Router Information\n"
2899 "Table Information about this Zebra Router\n"
2900 "Summary Information\n")
2902 zebra_router_show_table_summary(vty
);
2907 /* Table configuration write function. */
2908 static int config_write_table(struct vty
*vty
)
2913 /* IPForwarding configuration write function. */
2914 static int config_write_forwarding(struct vty
*vty
)
2916 /* FIXME: Find better place for that. */
2917 router_id_write(vty
);
2920 vty_out(vty
, "no ip forwarding\n");
2921 if (!ipforward_ipv6())
2922 vty_out(vty
, "no ipv6 forwarding\n");
2923 vty_out(vty
, "!\n");
2927 DEFUN_HIDDEN (show_frr
,
2933 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
2934 vty_out(vty
, ".............................7777:..............................................\n");
2935 vty_out(vty
, ".............................777777,............................................\n");
2936 vty_out(vty
, "... .........................77777777,..........................................\n");
2937 vty_out(vty
, "............................=7777777777:........................................\n");
2938 vty_out(vty
, "........................:7777777777777777,......................................\n");
2939 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
2940 vty_out(vty
, "...................I7777777777+.................................................\n");
2941 vty_out(vty
, "................,777777777?............ .......................................\n");
2942 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
2943 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
2944 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
2945 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
2946 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
2947 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
2948 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
2949 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
2950 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
2951 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
2952 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
2953 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
2954 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
2955 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
2956 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
2957 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
2958 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
2959 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
2960 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
2961 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
2962 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
2963 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
2964 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
2965 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
2966 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
2967 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
2968 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
2969 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
2970 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
2971 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
2972 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
2973 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
2974 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
2975 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
2976 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
2977 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
2978 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
2979 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
2980 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
2981 vty_out(vty
, "............................~777777777777..............+777777..................\n");
2982 vty_out(vty
, "................................~77777777...............=777777.................\n");
2983 vty_out(vty
, ".....................................:=?I................~777777................\n");
2984 vty_out(vty
, "..........................................................:777777,..............\n");
2985 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
2990 /* IP node for static routes. */
2991 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2992 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2993 /* table node for routing tables. */
2994 static struct cmd_node table_node
= {TABLE_NODE
,
2995 "", /* This node has no interface. */
2997 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2998 "", /* This node has no interface. */
3002 void zebra_vty_init(void)
3004 /* Install configuration write function. */
3005 install_node(&table_node
, config_write_table
);
3006 install_node(&forwarding_node
, config_write_forwarding
);
3008 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3009 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3010 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3011 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3013 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3014 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3015 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3018 zebra_route_map_init();
3020 install_node(&ip_node
, zebra_ip_config
);
3021 install_node(&protocol_node
, config_write_protocol
);
3023 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3024 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3026 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3027 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3029 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3030 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3031 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3032 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3033 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3034 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3036 install_element(VIEW_NODE
, &show_vrf_cmd
);
3037 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3038 install_element(VIEW_NODE
, &show_route_cmd
);
3039 install_element(VIEW_NODE
, &show_route_table_cmd
);
3040 if (vrf_is_backend_netns())
3041 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3042 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3043 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3044 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3045 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3047 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3048 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3050 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3051 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3052 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3053 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3054 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3055 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3056 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3057 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3058 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3060 /* Commands for VRF */
3061 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3063 install_element(VIEW_NODE
, &show_frr_cmd
);
3064 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3065 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3066 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3067 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3068 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3069 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3070 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3071 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3072 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3073 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3074 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3075 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3076 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3077 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3078 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3079 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3080 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3081 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3082 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3083 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3084 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3085 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3086 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3087 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3088 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3089 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3091 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3092 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3094 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3095 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3096 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3097 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3099 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3100 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3101 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3102 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3104 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);