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 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
398 struct nexthop_group
*nhg
;
400 uptime
= monotime(NULL
);
401 uptime
-= re
->uptime
;
402 tm
= gmtime(&uptime
);
404 /* If showing fib information, use the fib view of the
408 nhg
= rib_active_nhg(re
);
413 json_route
= json_object_new_object();
414 json_nexthops
= json_object_new_array();
416 json_object_string_add(json_route
, "prefix",
417 srcdest_rnode2str(rn
, buf
, sizeof buf
));
418 json_object_string_add(json_route
, "protocol",
419 zebra_route_string(re
->type
));
422 json_object_int_add(json_route
, "instance",
426 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
428 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
429 json_object_boolean_true_add(json_route
, "selected");
431 if (dest
->selected_fib
== re
)
432 json_object_boolean_true_add(json_route
,
435 json_object_int_add(json_route
, "distance",
437 json_object_int_add(json_route
, "metric", re
->metric
);
439 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
440 json_object_boolean_true_add(json_route
, "installed");
442 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
443 json_object_boolean_true_add(json_route
, "failed");
445 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
446 json_object_boolean_true_add(json_route
, "queued");
449 json_object_int_add(json_route
, "tag", re
->tag
);
452 json_object_int_add(json_route
, "table", re
->table
);
454 json_object_int_add(json_route
, "internalStatus",
456 json_object_int_add(json_route
, "internalFlags",
458 json_object_int_add(json_route
, "internalNextHopNum",
460 json_object_int_add(json_route
, "internalNextHopActiveNum",
461 re
->nexthop_active_num
);
462 if (uptime
< ONE_DAY_SECOND
)
463 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
465 else if (uptime
< ONE_WEEK_SECOND
)
466 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
469 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
470 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
473 json_object_string_add(json_route
, "uptime", buf
);
475 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
476 json_nexthop
= json_object_new_object();
478 json_object_int_add(json_nexthop
, "flags",
481 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
482 json_object_boolean_true_add(json_nexthop
,
485 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
486 json_object_boolean_true_add(json_nexthop
,
489 switch (nexthop
->type
) {
490 case NEXTHOP_TYPE_IPV4
:
491 case NEXTHOP_TYPE_IPV4_IFINDEX
:
492 json_object_string_add(
494 inet_ntoa(nexthop
->gate
.ipv4
));
495 json_object_string_add(json_nexthop
, "afi",
498 if (nexthop
->ifindex
) {
499 json_object_int_add(json_nexthop
,
502 json_object_string_add(
503 json_nexthop
, "interfaceName",
509 case NEXTHOP_TYPE_IPV6
:
510 case NEXTHOP_TYPE_IPV6_IFINDEX
:
511 json_object_string_add(
513 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
515 json_object_string_add(json_nexthop
, "afi",
518 if (nexthop
->ifindex
) {
519 json_object_int_add(json_nexthop
,
522 json_object_string_add(
523 json_nexthop
, "interfaceName",
530 case NEXTHOP_TYPE_IFINDEX
:
531 json_object_boolean_true_add(
532 json_nexthop
, "directlyConnected");
533 json_object_int_add(json_nexthop
,
536 json_object_string_add(
537 json_nexthop
, "interfaceName",
538 ifindex2ifname(nexthop
->ifindex
,
541 case NEXTHOP_TYPE_BLACKHOLE
:
542 json_object_boolean_true_add(json_nexthop
,
544 switch (nexthop
->bh_type
) {
545 case BLACKHOLE_REJECT
:
546 json_object_boolean_true_add(
547 json_nexthop
, "reject");
549 case BLACKHOLE_ADMINPROHIB
:
550 json_object_boolean_true_add(
555 json_object_boolean_true_add(
556 json_nexthop
, "blackhole");
558 case BLACKHOLE_UNSPEC
:
566 if ((nexthop
->vrf_id
!= re
->vrf_id
)
567 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
569 vrf_lookup_by_id(nexthop
->vrf_id
);
571 json_object_string_add(json_nexthop
, "vrf",
574 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
575 json_object_boolean_true_add(json_nexthop
,
578 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
579 json_object_boolean_true_add(json_nexthop
,
582 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
583 json_object_boolean_true_add(json_nexthop
,
586 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
587 json_object_boolean_true_add(json_nexthop
,
590 switch (nexthop
->type
) {
591 case NEXTHOP_TYPE_IPV4
:
592 case NEXTHOP_TYPE_IPV4_IFINDEX
:
593 if (nexthop
->src
.ipv4
.s_addr
) {
594 if (inet_ntop(AF_INET
,
595 &nexthop
->src
.ipv4
, buf
,
597 json_object_string_add(
598 json_nexthop
, "source",
602 case NEXTHOP_TYPE_IPV6
:
603 case NEXTHOP_TYPE_IPV6_IFINDEX
:
604 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
606 if (inet_ntop(AF_INET6
,
607 &nexthop
->src
.ipv6
, buf
,
609 json_object_string_add(
610 json_nexthop
, "source",
618 if (nexthop
->nh_label
619 && nexthop
->nh_label
->num_labels
) {
620 json_labels
= json_object_new_array();
622 for (int label_index
= 0;
624 < nexthop
->nh_label
->num_labels
;
626 json_object_array_add(
629 nexthop
->nh_label
->label
632 json_object_object_add(json_nexthop
, "labels",
636 json_object_array_add(json_nexthops
, json_nexthop
);
639 json_object_object_add(json_route
, "nexthops", json_nexthops
);
640 json_object_array_add(json
, json_route
);
644 /* Nexthop information. */
645 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
646 if (nexthop
== nhg
->nexthop
) {
647 /* Prefix information. */
648 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
650 len
+= vty_out(vty
, "[%d]", re
->instance
);
653 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
656 re_status_output_char(re
, nexthop
),
657 srcdest_rnode2str(rn
, buf
, sizeof buf
));
659 /* Distance and metric display. */
660 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
661 (re
->distance
|| re
->metric
)) ||
662 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
663 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
666 vty_out(vty
, " %c%*c",
667 re_status_output_char(re
, nexthop
),
668 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
671 switch (nexthop
->type
) {
672 case NEXTHOP_TYPE_IPV4
:
673 case NEXTHOP_TYPE_IPV4_IFINDEX
:
674 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
675 if (nexthop
->ifindex
)
677 ifindex2ifname(nexthop
->ifindex
,
680 case NEXTHOP_TYPE_IPV6
:
681 case NEXTHOP_TYPE_IPV6_IFINDEX
:
682 vty_out(vty
, " via %s",
683 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
685 if (nexthop
->ifindex
)
687 ifindex2ifname(nexthop
->ifindex
,
691 case NEXTHOP_TYPE_IFINDEX
:
692 vty_out(vty
, " is directly connected, %s",
693 ifindex2ifname(nexthop
->ifindex
,
696 case NEXTHOP_TYPE_BLACKHOLE
:
697 vty_out(vty
, " unreachable");
698 switch (nexthop
->bh_type
) {
699 case BLACKHOLE_REJECT
:
700 vty_out(vty
, " (ICMP unreachable)");
702 case BLACKHOLE_ADMINPROHIB
:
703 vty_out(vty
, " (ICMP admin-prohibited)");
706 vty_out(vty
, " (blackhole)");
708 case BLACKHOLE_UNSPEC
:
716 if ((nexthop
->vrf_id
!= re
->vrf_id
)
717 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
718 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
721 vty_out(vty
, "(vrf %s)", vrf
->name
);
723 vty_out(vty
, "(vrf UNKNOWN)");
726 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
727 vty_out(vty
, " inactive");
729 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
730 vty_out(vty
, " onlink");
732 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
733 vty_out(vty
, " (recursive)");
735 switch (nexthop
->type
) {
736 case NEXTHOP_TYPE_IPV4
:
737 case NEXTHOP_TYPE_IPV4_IFINDEX
:
738 if (nexthop
->src
.ipv4
.s_addr
) {
739 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
741 vty_out(vty
, ", src %s", buf
);
744 case NEXTHOP_TYPE_IPV6
:
745 case NEXTHOP_TYPE_IPV6_IFINDEX
:
746 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
747 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
749 vty_out(vty
, ", src %s", buf
);
756 /* Label information */
757 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
758 vty_out(vty
, ", label %s",
759 mpls_label2str(nexthop
->nh_label
->num_labels
,
760 nexthop
->nh_label
->label
, buf
,
764 if (uptime
< ONE_DAY_SECOND
)
765 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
766 tm
->tm_min
, tm
->tm_sec
);
767 else if (uptime
< ONE_WEEK_SECOND
)
768 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
769 tm
->tm_hour
, tm
->tm_min
);
771 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
772 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
778 static void vty_show_ip_route_detail_json(struct vty
*vty
,
779 struct route_node
*rn
, bool use_fib
)
781 json_object
*json
= NULL
;
782 json_object
*json_prefix
= NULL
;
783 struct route_entry
*re
;
787 dest
= rib_dest_from_rnode(rn
);
789 json
= json_object_new_object();
790 json_prefix
= json_object_new_array();
792 RNODE_FOREACH_RE (rn
, re
) {
794 * If re not selected for forwarding, skip re
795 * for "show ip/ipv6 fib <prefix> json"
797 if (use_fib
&& re
!= dest
->selected_fib
)
799 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
802 prefix2str(&rn
->p
, buf
, sizeof(buf
));
803 json_object_object_add(json
, buf
, json_prefix
);
804 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
805 json
, JSON_C_TO_STRING_PRETTY
));
806 json_object_free(json
);
809 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
810 struct route_table
*table
, afi_t afi
,
811 bool use_fib
, route_tag_t tag
,
812 const struct prefix
*longer_prefix_p
,
813 bool supernets_only
, int type
,
814 unsigned short ospf_instance_id
, bool use_json
,
817 struct route_node
*rn
;
818 struct route_entry
*re
;
821 json_object
*json
= NULL
;
822 json_object
*json_prefix
= NULL
;
827 json
= json_object_new_object();
829 /* Show all routes. */
830 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
831 dest
= rib_dest_from_rnode(rn
);
833 RNODE_FOREACH_RE (rn
, re
) {
834 if (use_fib
&& re
!= dest
->selected_fib
)
837 if (tag
&& re
->tag
!= tag
)
841 && !prefix_match(longer_prefix_p
, &rn
->p
))
844 /* This can only be true when the afi is IPv4 */
845 if (supernets_only
) {
846 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
848 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
851 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
854 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
858 if (type
&& re
->type
!= type
)
862 && (re
->type
!= ZEBRA_ROUTE_OSPF
863 || re
->instance
!= ospf_instance_id
))
868 json_prefix
= json_object_new_array();
873 SHOW_ROUTE_V4_HEADER
);
876 SHOW_ROUTE_V6_HEADER
);
878 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
879 vty_out(vty
, "\nVRF %s table %u:\n",
880 zvrf_name(zvrf
), tableid
);
881 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
882 vty_out(vty
, "\nVRF %s:\n",
888 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
892 prefix2str(&rn
->p
, buf
, sizeof(buf
));
893 json_object_object_add(json
, buf
, json_prefix
);
899 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
900 JSON_C_TO_STRING_PRETTY
));
901 json_object_free(json
);
905 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
906 safi_t safi
, bool use_fib
, bool use_json
,
908 const struct prefix
*longer_prefix_p
,
909 bool supernets_only
, int type
,
910 unsigned short ospf_instance_id
)
912 struct route_table
*table
;
913 struct zebra_vrf
*zvrf
= NULL
;
915 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
917 vty_out(vty
, "{}\n");
919 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
923 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
925 vty_out(vty
, "{}\n");
927 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
931 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
934 vty_out(vty
, "{}\n");
938 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
939 longer_prefix_p
, supernets_only
, type
,
940 ospf_instance_id
, use_json
, 0);
945 DEFPY (show_route_table
,
946 show_route_table_cmd
,
947 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
953 "The table number to display, if available\n"
956 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
957 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
958 struct route_table
*t
;
960 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
962 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
963 0, 0, !!json
, table
);
968 DEFPY (show_route_table_vrf
,
969 show_route_table_vrf_cmd
,
970 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
976 "The table number to display, if available\n"
980 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
981 struct zebra_vrf
*zvrf
;
982 struct route_table
*t
;
983 vrf_id_t vrf_id
= VRF_DEFAULT
;
986 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
987 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
989 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
991 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
992 0, 0, !!json
, table
);
997 DEFPY (show_route_all_table_vrf
,
998 show_route_all_table_vrf_cmd
,
999 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1003 "IP routing table\n"
1004 "Display all tables\n"
1005 VRF_FULL_CMD_HELP_STR
1008 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1009 struct zebra_vrf
*zvrf
= NULL
;
1010 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1011 struct zebra_router_table
*zrt
;
1014 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1015 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1018 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1019 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1021 if (zvrf
&& zvrf
!= info
->zvrf
)
1023 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1026 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
,
1027 false, 0, false, false,
1028 0, 0, !!json
, zrt
->tableid
);
1035 "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]",
1039 "IP nexthop tracking table\n"
1040 "IP import check tracking table\n"
1046 VRF_ALL_CMD_HELP_STR
)
1048 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1049 vrf_id_t vrf_id
= VRF_DEFAULT
;
1050 struct prefix prefix
, *p
= NULL
;
1053 if (strcmp(type
, "nht") == 0)
1054 rtype
= RNH_NEXTHOP_TYPE
;
1056 rtype
= RNH_IMPORT_CHECK_TYPE
;
1060 struct zebra_vrf
*zvrf
;
1062 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1063 if ((zvrf
= vrf
->info
) != NULL
) {
1064 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1065 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1071 VRF_GET_ID(vrf_id
, vrf_name
, false);
1073 memset(&prefix
, 0, sizeof(prefix
));
1075 p
= sockunion2hostprefix(addr
, &prefix
);
1077 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1081 DEFUN (ip_nht_default_route
,
1082 ip_nht_default_route_cmd
,
1083 "ip nht resolve-via-default",
1085 "Filter Next Hop tracking route resolution\n"
1086 "Resolve via default route\n")
1088 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1093 if (zvrf
->zebra_rnh_ip_default_route
)
1096 zvrf
->zebra_rnh_ip_default_route
= 1;
1098 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1102 DEFUN (no_ip_nht_default_route
,
1103 no_ip_nht_default_route_cmd
,
1104 "no ip nht resolve-via-default",
1107 "Filter Next Hop tracking route resolution\n"
1108 "Resolve via default route\n")
1110 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1115 if (!zvrf
->zebra_rnh_ip_default_route
)
1118 zvrf
->zebra_rnh_ip_default_route
= 0;
1119 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1123 DEFUN (ipv6_nht_default_route
,
1124 ipv6_nht_default_route_cmd
,
1125 "ipv6 nht resolve-via-default",
1127 "Filter Next Hop tracking route resolution\n"
1128 "Resolve via default route\n")
1130 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1135 if (zvrf
->zebra_rnh_ipv6_default_route
)
1138 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1139 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1143 DEFUN (no_ipv6_nht_default_route
,
1144 no_ipv6_nht_default_route_cmd
,
1145 "no ipv6 nht resolve-via-default",
1148 "Filter Next Hop tracking route resolution\n"
1149 "Resolve via default route\n")
1152 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1157 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1160 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1161 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1169 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1172 |A.B.C.D/M$prefix longer-prefixes\
1173 |supernets-only$supernets_only\
1176 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1177 |ospf$type_str (1-65535)$ospf_instance_id\
1179 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1182 |X:X::X:X/M$prefix longer-prefixes\
1184 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1189 "IP forwarding table\n"
1190 "IP routing table\n"
1191 VRF_FULL_CMD_HELP_STR
1192 "Show only routes with tag\n"
1194 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1195 "Show route matching the specified Network/Mask pair only\n"
1196 "Show supernet entries only\n"
1197 FRR_IP_REDIST_HELP_STR_ZEBRA
1198 "Open Shortest Path First (OSPFv2)\n"
1201 "IP forwarding table\n"
1202 "IP routing table\n"
1203 VRF_FULL_CMD_HELP_STR
1204 "Show only routes with tag\n"
1207 "Show route matching the specified Network/Mask pair only\n"
1208 FRR_IP6_REDIST_HELP_STR_ZEBRA
1211 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1216 type
= proto_redistnum(afi
, type_str
);
1218 vty_out(vty
, "Unknown route type\n");
1224 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1225 struct zebra_vrf
*zvrf
;
1226 struct route_table
*table
;
1228 if ((zvrf
= vrf
->info
) == NULL
1229 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1233 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1234 !!json
, tag
, prefix_str
? prefix
: NULL
,
1235 !!supernets_only
, type
, ospf_instance_id
);
1238 vrf_id_t vrf_id
= VRF_DEFAULT
;
1241 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1242 vrf
= vrf_lookup_by_id(vrf_id
);
1243 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1244 !!json
, tag
, prefix_str
? prefix
: NULL
,
1245 !!supernets_only
, type
, ospf_instance_id
);
1251 DEFPY (show_route_detail
,
1252 show_route_detail_cmd
,
1255 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1260 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1269 "IPv6 forwarding table\n"
1270 "IP routing table\n"
1271 VRF_FULL_CMD_HELP_STR
1272 "Network in the IP routing table to display\n"
1273 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1275 "IPv6 forwarding table\n"
1276 "IPv6 routing table\n"
1277 VRF_FULL_CMD_HELP_STR
1282 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1283 struct route_table
*table
;
1285 struct route_node
*rn
;
1286 bool use_fib
= !!fib
;
1288 bool network_found
= false;
1291 prefix_str
= address_str
;
1292 if (str2prefix(prefix_str
, &p
) < 0) {
1293 vty_out(vty
, "%% Malformed address\n");
1299 struct zebra_vrf
*zvrf
;
1301 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1302 if ((zvrf
= vrf
->info
) == NULL
1303 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1306 rn
= route_node_match(table
, &p
);
1309 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1310 route_unlock_node(rn
);
1314 dest
= rib_dest_from_rnode(rn
);
1315 if (use_fib
&& !dest
->selected_fib
) {
1316 route_unlock_node(rn
);
1320 network_found
= true;
1322 vty_show_ip_route_detail_json(vty
, rn
,
1325 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1327 route_unlock_node(rn
);
1330 if (!network_found
) {
1332 vty_out(vty
, "{}\n");
1336 "%% Network not in FIB\n");
1339 "%% Network not in RIB\n");
1344 vrf_id_t vrf_id
= VRF_DEFAULT
;
1347 VRF_GET_ID(vrf_id
, vrf_name
, false);
1349 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1353 rn
= route_node_match(table
, &p
);
1355 dest
= rib_dest_from_rnode(rn
);
1357 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1358 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1360 vty_out(vty
, "{}\n");
1364 "%% Network not in FIB\n");
1367 "%% Network not in table\n");
1370 route_unlock_node(rn
);
1375 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1377 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
);
1379 route_unlock_node(rn
);
1385 DEFPY (show_route_summary
,
1386 show_route_summary_cmd
,
1389 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1390 summary [prefix$prefix]\
1391 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1392 summary [prefix$prefix]\
1396 "IP routing table\n"
1397 VRF_FULL_CMD_HELP_STR
1398 "Summary of all routes\n"
1401 "IP routing table\n"
1402 VRF_FULL_CMD_HELP_STR
1403 "Summary of all routes\n"
1406 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1407 struct route_table
*table
;
1411 struct zebra_vrf
*zvrf
;
1413 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1414 if ((zvrf
= vrf
->info
) == NULL
1415 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1419 vty_show_ip_route_summary_prefix(vty
, table
);
1421 vty_show_ip_route_summary(vty
, table
);
1424 vrf_id_t vrf_id
= VRF_DEFAULT
;
1427 VRF_GET_ID(vrf_id
, vrf_name
, false);
1429 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1434 vty_show_ip_route_summary_prefix(vty
, table
);
1436 vty_show_ip_route_summary(vty
, table
);
1442 static void vty_show_ip_route_summary(struct vty
*vty
,
1443 struct route_table
*table
)
1445 struct route_node
*rn
;
1446 struct route_entry
*re
;
1447 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1448 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1449 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1450 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1454 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1455 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1456 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1457 RNODE_FOREACH_RE (rn
, re
) {
1458 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1459 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1461 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1463 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1465 rib_cnt
[re
->type
]++;
1467 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1468 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1471 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1473 fib_cnt
[re
->type
]++;
1477 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1478 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1480 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1481 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1482 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1483 if (i
== ZEBRA_ROUTE_BGP
) {
1484 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1485 rib_cnt
[ZEBRA_ROUTE_BGP
],
1486 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1487 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1488 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1489 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1491 vty_out(vty
, "%-20s %-20d %-20d \n",
1492 zebra_route_string(i
), rib_cnt
[i
],
1497 vty_out(vty
, "------\n");
1498 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1499 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1504 * Implementation of the ip route summary prefix command.
1506 * This command prints the primary prefixes that have been installed by various
1507 * protocols on the box.
1510 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1511 struct route_table
*table
)
1513 struct route_node
*rn
;
1514 struct route_entry
*re
;
1515 struct nexthop
*nexthop
;
1516 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1517 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1518 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1519 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1523 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1524 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1525 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1526 RNODE_FOREACH_RE (rn
, re
) {
1529 * In case of ECMP, count only once.
1532 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1533 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1534 fib_cnt
[re
->type
]++;
1536 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1537 nexthop
= nexthop
->next
) {
1539 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1540 rib_cnt
[re
->type
]++;
1541 if (re
->type
== ZEBRA_ROUTE_BGP
1542 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1543 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1544 if (CHECK_FLAG(re
->status
,
1545 ROUTE_ENTRY_INSTALLED
))
1546 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1551 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1552 "Prefix Routes", "FIB",
1553 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1555 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1556 if (rib_cnt
[i
] > 0) {
1557 if (i
== ZEBRA_ROUTE_BGP
) {
1558 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1559 rib_cnt
[ZEBRA_ROUTE_BGP
]
1560 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1561 fib_cnt
[ZEBRA_ROUTE_BGP
]
1562 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1563 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1564 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1565 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1567 vty_out(vty
, "%-20s %-20d %-20d \n",
1568 zebra_route_string(i
), rib_cnt
[i
],
1573 vty_out(vty
, "------\n");
1574 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1575 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1580 * Show IPv6 mroute command.Used to dump
1581 * the Multicast routing table.
1583 DEFUN (show_ipv6_mroute
,
1584 show_ipv6_mroute_cmd
,
1585 "show ipv6 mroute [vrf NAME]",
1588 "IPv6 Multicast routing table\n"
1591 struct route_table
*table
;
1592 struct route_node
*rn
;
1593 struct route_entry
*re
;
1595 vrf_id_t vrf_id
= VRF_DEFAULT
;
1598 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1600 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1604 /* Show all IPv6 route. */
1605 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1606 RNODE_FOREACH_RE (rn
, re
) {
1608 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1611 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1616 DEFUN (show_ipv6_mroute_vrf_all
,
1617 show_ipv6_mroute_vrf_all_cmd
,
1618 "show ipv6 mroute vrf all",
1621 "IPv6 Multicast routing table\n"
1622 VRF_ALL_CMD_HELP_STR
)
1624 struct route_table
*table
;
1625 struct route_node
*rn
;
1626 struct route_entry
*re
;
1628 struct zebra_vrf
*zvrf
;
1631 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1632 if ((zvrf
= vrf
->info
) == NULL
1633 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1636 /* Show all IPv6 route. */
1637 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1638 RNODE_FOREACH_RE (rn
, re
) {
1640 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1643 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1649 DEFUN (allow_external_route_update
,
1650 allow_external_route_update_cmd
,
1651 "allow-external-route-update",
1652 "Allow FRR routes to be overwritten by external processes\n")
1659 DEFUN (no_allow_external_route_update
,
1660 no_allow_external_route_update_cmd
,
1661 "no allow-external-route-update",
1663 "Allow FRR routes to be overwritten by external processes\n")
1678 struct zebra_vrf
*zvrf
;
1680 if (vrf_is_backend_netns())
1681 vty_out(vty
, "netns-based vrfs\n");
1683 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1684 if (!(zvrf
= vrf
->info
))
1686 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1689 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1690 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1691 vty_out(vty
, "inactive");
1692 else if (zvrf_ns_name(zvrf
))
1693 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1694 zvrf_ns_name(zvrf
));
1696 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1698 if (vrf_is_user_cfged(vrf
))
1699 vty_out(vty
, " (configured)");
1706 DEFUN (default_vrf_vni_mapping
,
1707 default_vrf_vni_mapping_cmd
,
1708 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1709 "VNI corresponding to the DEFAULT VRF\n"
1711 "Prefix routes only \n")
1714 char err
[ERR_STR_SZ
];
1715 struct zebra_vrf
*zvrf
= NULL
;
1716 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1719 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1726 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1729 vty_out(vty
, "%s\n", err
);
1736 DEFUN (no_default_vrf_vni_mapping
,
1737 no_default_vrf_vni_mapping_cmd
,
1738 "no vni " CMD_VNI_RANGE
,
1740 "VNI corresponding to DEFAULT VRF\n"
1744 char err
[ERR_STR_SZ
];
1745 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1746 struct zebra_vrf
*zvrf
= NULL
;
1748 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1752 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1754 vty_out(vty
, "%s\n", err
);
1761 DEFUN (vrf_vni_mapping
,
1762 vrf_vni_mapping_cmd
,
1763 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1764 "VNI corresponding to tenant VRF\n"
1766 "prefix-routes-only\n")
1771 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1772 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1773 char err
[ERR_STR_SZ
];
1781 /* Mark as having FRR configuration */
1782 vrf_set_user_cfged(vrf
);
1783 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1786 vty_out(vty
, "%s\n", err
);
1793 DEFUN (no_vrf_vni_mapping
,
1794 no_vrf_vni_mapping_cmd
,
1795 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1797 "VNI corresponding to tenant VRF\n"
1799 "prefix-routes-only\n")
1803 char err
[ERR_STR_SZ
];
1804 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1806 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1814 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1815 ERR_STR_SZ
, filter
, 0);
1817 vty_out(vty
, "%s\n", err
);
1821 /* If no other FRR config for this VRF, mark accordingly. */
1822 if (!zebra_vrf_has_config(zvrf
))
1823 vrf_reset_user_cfged(vrf
);
1829 DEFUN (show_vrf_vni
,
1831 "show vrf vni [json]",
1838 struct zebra_vrf
*zvrf
;
1839 json_object
*json
= NULL
;
1840 json_object
*json_vrfs
= NULL
;
1841 bool uj
= use_json(argc
, argv
);
1844 json
= json_object_new_object();
1845 json_vrfs
= json_object_new_array();
1849 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1850 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1852 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1857 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1861 json_object_object_add(json
, "vrfs", json_vrfs
);
1862 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1863 json
, JSON_C_TO_STRING_PRETTY
));
1864 json_object_free(json
);
1870 DEFUN (show_evpn_global
,
1871 show_evpn_global_cmd
,
1877 bool uj
= use_json(argc
, argv
);
1879 zebra_vxlan_print_evpn(vty
, uj
);
1883 DEFUN (show_evpn_vni
,
1885 "show evpn vni [json]",
1888 "VxLAN Network Identifier\n"
1891 struct zebra_vrf
*zvrf
;
1892 bool uj
= use_json(argc
, argv
);
1894 zvrf
= zebra_vrf_get_evpn();
1895 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1899 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1900 "show evpn vni detail [json]",
1903 "VxLAN Network Identifier\n"
1904 "Detailed Information On Each VNI\n"
1907 struct zebra_vrf
*zvrf
;
1908 bool uj
= use_json(argc
, argv
);
1910 zvrf
= zebra_vrf_get_evpn();
1911 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1915 DEFUN (show_evpn_vni_vni
,
1916 show_evpn_vni_vni_cmd
,
1917 "show evpn vni " CMD_VNI_RANGE
"[json]",
1920 "VxLAN Network Identifier\n"
1924 struct zebra_vrf
*zvrf
;
1926 bool uj
= use_json(argc
, argv
);
1928 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1929 zvrf
= zebra_vrf_get_evpn();
1930 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1934 DEFUN (show_evpn_rmac_vni_mac
,
1935 show_evpn_rmac_vni_mac_cmd
,
1936 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1943 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1948 bool uj
= use_json(argc
, argv
);
1950 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1951 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1952 vty_out(vty
, "%% Malformed MAC address\n");
1955 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1959 DEFUN (show_evpn_rmac_vni
,
1960 show_evpn_rmac_vni_cmd
,
1961 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1970 bool uj
= use_json(argc
, argv
);
1972 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1973 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1978 DEFUN (show_evpn_rmac_vni_all
,
1979 show_evpn_rmac_vni_all_cmd
,
1980 "show evpn rmac vni all [json]",
1988 bool uj
= use_json(argc
, argv
);
1990 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1995 DEFUN (show_evpn_nh_vni_ip
,
1996 show_evpn_nh_vni_ip_cmd
,
1997 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2004 "Host address (ipv4 or ipv6)\n"
2009 bool uj
= use_json(argc
, argv
);
2011 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2012 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2014 vty_out(vty
, "%% Malformed Neighbor address\n");
2017 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2022 DEFUN (show_evpn_nh_vni
,
2023 show_evpn_nh_vni_cmd
,
2024 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2033 bool uj
= use_json(argc
, argv
);
2035 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2036 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2041 DEFUN (show_evpn_nh_vni_all
,
2042 show_evpn_nh_vni_all_cmd
,
2043 "show evpn next-hops vni all [json]",
2051 bool uj
= use_json(argc
, argv
);
2053 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2058 DEFUN (show_evpn_mac_vni
,
2059 show_evpn_mac_vni_cmd
,
2060 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2064 "VxLAN Network Identifier\n"
2068 struct zebra_vrf
*zvrf
;
2070 bool uj
= use_json(argc
, argv
);
2072 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2073 zvrf
= zebra_vrf_get_evpn();
2074 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2078 DEFUN (show_evpn_mac_vni_all
,
2079 show_evpn_mac_vni_all_cmd
,
2080 "show evpn mac vni all [json]",
2084 "VxLAN Network Identifier\n"
2088 struct zebra_vrf
*zvrf
;
2089 bool uj
= use_json(argc
, argv
);
2091 zvrf
= zebra_vrf_get_evpn();
2092 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2096 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2097 "show evpn mac vni all detail [json]",
2101 "VxLAN Network Identifier\n"
2103 "Detailed Information On Each VNI MAC\n"
2106 struct zebra_vrf
*zvrf
;
2107 bool uj
= use_json(argc
, argv
);
2109 zvrf
= zebra_vrf_get_evpn();
2110 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2114 DEFUN (show_evpn_mac_vni_all_vtep
,
2115 show_evpn_mac_vni_all_vtep_cmd
,
2116 "show evpn mac vni all vtep A.B.C.D [json]",
2120 "VxLAN Network Identifier\n"
2123 "Remote VTEP IP address\n"
2126 struct zebra_vrf
*zvrf
;
2127 struct in_addr vtep_ip
;
2128 bool uj
= use_json(argc
, argv
);
2130 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2132 vty_out(vty
, "%% Malformed VTEP IP address\n");
2135 zvrf
= zebra_vrf_get_evpn();
2136 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2142 DEFUN (show_evpn_mac_vni_mac
,
2143 show_evpn_mac_vni_mac_cmd
,
2144 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2148 "VxLAN Network Identifier\n"
2151 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2155 struct zebra_vrf
*zvrf
;
2158 bool uj
= use_json(argc
, argv
);
2160 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2161 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2162 vty_out(vty
, "%% Malformed MAC address");
2165 zvrf
= zebra_vrf_get_evpn();
2166 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2170 DEFUN (show_evpn_mac_vni_vtep
,
2171 show_evpn_mac_vni_vtep_cmd
,
2172 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2176 "VxLAN Network Identifier\n"
2179 "Remote VTEP IP address\n"
2182 struct zebra_vrf
*zvrf
;
2184 struct in_addr vtep_ip
;
2185 bool uj
= use_json(argc
, argv
);
2187 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2188 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2190 vty_out(vty
, "%% Malformed VTEP IP address\n");
2194 zvrf
= zebra_vrf_get_evpn();
2195 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2199 DEFPY (show_evpn_mac_vni_all_dad
,
2200 show_evpn_mac_vni_all_dad_cmd
,
2201 "show evpn mac vni all duplicate [json]",
2205 "VxLAN Network Identifier\n"
2207 "Duplicate address list\n"
2210 struct zebra_vrf
*zvrf
;
2211 bool uj
= use_json(argc
, argv
);
2213 zvrf
= zebra_vrf_get_evpn();
2214 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2219 DEFPY (show_evpn_mac_vni_dad
,
2220 show_evpn_mac_vni_dad_cmd
,
2221 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2225 "VxLAN Network Identifier\n"
2227 "Duplicate address list\n"
2230 struct zebra_vrf
*zvrf
;
2231 bool uj
= use_json(argc
, argv
);
2233 zvrf
= zebra_vrf_get_evpn();
2235 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2240 DEFPY (show_evpn_neigh_vni_dad
,
2241 show_evpn_neigh_vni_dad_cmd
,
2242 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2245 "ARP and ND cache\n"
2246 "VxLAN Network Identifier\n"
2248 "Duplicate address list\n"
2251 struct zebra_vrf
*zvrf
;
2252 bool uj
= use_json(argc
, argv
);
2254 zvrf
= zebra_vrf_get_evpn();
2255 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2259 DEFPY (show_evpn_neigh_vni_all_dad
,
2260 show_evpn_neigh_vni_all_dad_cmd
,
2261 "show evpn arp-cache vni all duplicate [json]",
2264 "ARP and ND cache\n"
2265 "VxLAN Network Identifier\n"
2267 "Duplicate address list\n"
2270 struct zebra_vrf
*zvrf
;
2271 bool uj
= use_json(argc
, argv
);
2273 zvrf
= zebra_vrf_get_evpn();
2274 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2279 DEFUN (show_evpn_neigh_vni
,
2280 show_evpn_neigh_vni_cmd
,
2281 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2284 "ARP and ND cache\n"
2285 "VxLAN Network Identifier\n"
2289 struct zebra_vrf
*zvrf
;
2291 bool uj
= use_json(argc
, argv
);
2293 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2294 zvrf
= zebra_vrf_get_evpn();
2295 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2299 DEFUN (show_evpn_neigh_vni_all
,
2300 show_evpn_neigh_vni_all_cmd
,
2301 "show evpn arp-cache vni all [json]",
2304 "ARP and ND cache\n"
2305 "VxLAN Network Identifier\n"
2309 struct zebra_vrf
*zvrf
;
2310 bool uj
= use_json(argc
, argv
);
2312 zvrf
= zebra_vrf_get_evpn();
2313 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2317 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2318 "show evpn arp-cache vni all detail [json]",
2321 "ARP and ND cache\n"
2322 "VxLAN Network Identifier\n"
2324 "Neighbor details for all vnis in detail\n" JSON_STR
)
2326 struct zebra_vrf
*zvrf
;
2327 bool uj
= use_json(argc
, argv
);
2329 zvrf
= zebra_vrf_get_evpn();
2330 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2334 DEFUN (show_evpn_neigh_vni_neigh
,
2335 show_evpn_neigh_vni_neigh_cmd
,
2336 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2339 "ARP and ND cache\n"
2340 "VxLAN Network Identifier\n"
2343 "Neighbor address (IPv4 or IPv6 address)\n"
2346 struct zebra_vrf
*zvrf
;
2349 bool uj
= use_json(argc
, argv
);
2351 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2352 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2354 vty_out(vty
, "%% Malformed Neighbor address\n");
2357 zvrf
= zebra_vrf_get_evpn();
2358 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2362 DEFUN (show_evpn_neigh_vni_vtep
,
2363 show_evpn_neigh_vni_vtep_cmd
,
2364 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2367 "ARP and ND cache\n"
2368 "VxLAN Network Identifier\n"
2371 "Remote VTEP IP address\n"
2374 struct zebra_vrf
*zvrf
;
2376 struct in_addr vtep_ip
;
2377 bool uj
= use_json(argc
, argv
);
2379 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2380 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2382 vty_out(vty
, "%% Malformed VTEP IP address\n");
2386 zvrf
= zebra_vrf_get_evpn();
2387 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2391 /* policy routing contexts */
2392 DEFUN (show_pbr_ipset
,
2394 "show pbr ipset [WORD]",
2396 "Policy-Based Routing\n"
2397 "IPset Context information\n"
2398 "IPset Name information\n")
2402 found
= argv_find(argv
, argc
, "WORD", &idx
);
2404 zebra_pbr_show_ipset_list(vty
, NULL
);
2406 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2410 /* policy routing contexts */
2411 DEFUN (show_pbr_iptable
,
2412 show_pbr_iptable_cmd
,
2413 "show pbr iptable [WORD]",
2415 "Policy-Based Routing\n"
2416 "IPtable Context information\n"
2417 "IPtable Name information\n")
2422 found
= argv_find(argv
, argc
, "WORD", &idx
);
2424 zebra_pbr_show_iptable(vty
, NULL
);
2426 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2430 DEFPY (clear_evpn_dup_addr
,
2431 clear_evpn_dup_addr_cmd
,
2432 "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>]>",
2435 "Duplicate address \n"
2436 "VxLAN Network Identifier\n"
2440 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2445 struct zebra_vrf
*zvrf
;
2446 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2447 int ret
= CMD_SUCCESS
;
2449 zvrf
= zebra_vrf_get_evpn();
2451 if (!is_zero_mac(&mac
->eth_addr
)) {
2452 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2456 if (sockunion_family(ip
) == AF_INET
) {
2457 host_ip
.ipa_type
= IPADDR_V4
;
2458 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2460 host_ip
.ipa_type
= IPADDR_V6
;
2461 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2462 sizeof(struct in6_addr
));
2464 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2468 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2471 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2477 /* Static ip route configuration write function. */
2478 static int zebra_ip_config(struct vty
*vty
)
2482 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2487 DEFUN (ip_zebra_import_table_distance
,
2488 ip_zebra_import_table_distance_cmd
,
2489 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2491 "import routes from non-main kernel table\n"
2492 "kernel routing table id\n"
2493 "Distance for imported routes\n"
2494 "Default distance value\n"
2495 "route-map for filtering\n"
2498 uint32_t table_id
= 0;
2500 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2501 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2503 strmatch(argv
[argc
- 2]->text
, "route-map")
2504 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2508 if (argc
== 7 || (argc
== 5 && !rmap
))
2509 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2511 if (!is_zebra_valid_kernel_table(table_id
)) {
2513 "Invalid routing table ID, %d. Must be in range 1-252\n",
2516 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2520 if (is_zebra_main_routing_table(table_id
)) {
2522 "Invalid routing table ID, %d. Must be non-default table\n",
2525 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2529 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2532 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2537 DEFUN_HIDDEN (zebra_packet_process
,
2538 zebra_packet_process_cmd
,
2539 "zebra zapi-packets (1-10000)",
2542 "Number of packets to process before relinquishing thread\n")
2544 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2546 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2547 memory_order_relaxed
);
2552 DEFUN_HIDDEN (no_zebra_packet_process
,
2553 no_zebra_packet_process_cmd
,
2554 "no zebra zapi-packets [(1-10000)]",
2558 "Number of packets to process before relinquishing thread\n")
2560 atomic_store_explicit(&zrouter
.packets_to_process
,
2561 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2562 memory_order_relaxed
);
2567 DEFUN_HIDDEN (zebra_workqueue_timer
,
2568 zebra_workqueue_timer_cmd
,
2569 "zebra work-queue (0-10000)",
2572 "Time in milliseconds\n")
2574 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2575 zrouter
.ribq
->spec
.hold
= timer
;
2580 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2581 no_zebra_workqueue_timer_cmd
,
2582 "no zebra work-queue [(0-10000)]",
2586 "Time in milliseconds\n")
2588 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2593 DEFUN (no_ip_zebra_import_table
,
2594 no_ip_zebra_import_table_cmd
,
2595 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2598 "import routes from non-main kernel table\n"
2599 "kernel routing table id\n"
2600 "Distance for imported routes\n"
2601 "Default distance value\n"
2602 "route-map for filtering\n"
2605 uint32_t table_id
= 0;
2606 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2608 if (!is_zebra_valid_kernel_table(table_id
)) {
2610 "Invalid routing table ID. Must be in range 1-252\n");
2614 if (is_zebra_main_routing_table(table_id
)) {
2616 "Invalid routing table ID, %d. Must be non-default table\n",
2621 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2624 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2627 static int config_write_protocol(struct vty
*vty
)
2630 vty_out(vty
, "allow-external-route-update\n");
2632 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2633 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2635 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2636 vty_out(vty
, "zebra zapi-packets %u\n",
2637 zrouter
.packets_to_process
);
2639 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2641 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2642 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2643 ipv4_multicast_mode
== MCAST_URIB_ONLY
2645 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2647 : ipv4_multicast_mode
2648 == MCAST_MIX_MRIB_FIRST
2650 : ipv4_multicast_mode
2651 == MCAST_MIX_DISTANCE
2666 " Route Route Neighbor LSP LSP\n");
2668 "VRF Installs Removals Updates Installs Removals\n");
2670 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2671 struct zebra_vrf
*zvrf
= vrf
->info
;
2673 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2674 " %10" PRIu64
" %10" PRIu64
"\n",
2675 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2676 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2677 zvrf
->lsp_removals
);
2683 DEFUN (ip_forwarding
,
2687 "Turn on IP forwarding\n")
2693 ret
= ipforward_on();
2696 vty_out(vty
, "Can't turn on IP forwarding\n");
2697 return CMD_WARNING_CONFIG_FAILED
;
2703 DEFUN (no_ip_forwarding
,
2704 no_ip_forwarding_cmd
,
2708 "Turn off IP forwarding\n")
2714 ret
= ipforward_off();
2717 vty_out(vty
, "Can't turn off IP forwarding\n");
2718 return CMD_WARNING_CONFIG_FAILED
;
2724 /* Only display ip forwarding is enabled or not. */
2725 DEFUN (show_ip_forwarding
,
2726 show_ip_forwarding_cmd
,
2727 "show ip forwarding",
2730 "IP forwarding status\n")
2737 vty_out(vty
, "IP forwarding is off\n");
2739 vty_out(vty
, "IP forwarding is on\n");
2743 /* Only display ipv6 forwarding is enabled or not. */
2744 DEFUN (show_ipv6_forwarding
,
2745 show_ipv6_forwarding_cmd
,
2746 "show ipv6 forwarding",
2748 "IPv6 information\n"
2749 "Forwarding status\n")
2753 ret
= ipforward_ipv6();
2757 vty_out(vty
, "ipv6 forwarding is unknown\n");
2760 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2763 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2766 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2772 DEFUN (ipv6_forwarding
,
2773 ipv6_forwarding_cmd
,
2776 "Turn on IPv6 forwarding\n")
2780 ret
= ipforward_ipv6();
2782 ret
= ipforward_ipv6_on();
2785 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2786 return CMD_WARNING_CONFIG_FAILED
;
2792 DEFUN (no_ipv6_forwarding
,
2793 no_ipv6_forwarding_cmd
,
2794 "no ipv6 forwarding",
2797 "Turn off IPv6 forwarding\n")
2801 ret
= ipforward_ipv6();
2803 ret
= ipforward_ipv6_off();
2806 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2807 return CMD_WARNING_CONFIG_FAILED
;
2813 /* Display dataplane info */
2814 DEFUN (show_dataplane
,
2816 "show zebra dplane [detailed]",
2819 "Zebra dataplane information\n"
2820 "Detailed output\n")
2823 bool detailed
= false;
2825 if (argv_find(argv
, argc
, "detailed", &idx
))
2828 return dplane_show_helper(vty
, detailed
);
2831 /* Display dataplane providers info */
2832 DEFUN (show_dataplane_providers
,
2833 show_dataplane_providers_cmd
,
2834 "show zebra dplane providers [detailed]",
2837 "Zebra dataplane information\n"
2838 "Zebra dataplane provider information\n"
2839 "Detailed output\n")
2842 bool detailed
= false;
2844 if (argv_find(argv
, argc
, "detailed", &idx
))
2847 return dplane_show_provs_helper(vty
, detailed
);
2850 /* Configure dataplane incoming queue limit */
2851 DEFUN (zebra_dplane_queue_limit
,
2852 zebra_dplane_queue_limit_cmd
,
2853 "zebra dplane limit (0-10000)",
2856 "Limit incoming queued updates\n"
2857 "Number of queued updates\n")
2861 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2863 dplane_set_in_queue_limit(limit
, true);
2868 /* Reset dataplane queue limit to default value */
2869 DEFUN (no_zebra_dplane_queue_limit
,
2870 no_zebra_dplane_queue_limit_cmd
,
2871 "no zebra dplane limit [(0-10000)]",
2875 "Limit incoming queued updates\n"
2876 "Number of queued updates\n")
2878 dplane_set_in_queue_limit(0, false);
2883 DEFUN (zebra_show_routing_tables_summary
,
2884 zebra_show_routing_tables_summary_cmd
,
2885 "show zebra router table summary",
2888 "The Zebra Router Information\n"
2889 "Table Information about this Zebra Router\n"
2890 "Summary Information\n")
2892 zebra_router_show_table_summary(vty
);
2897 /* Table configuration write function. */
2898 static int config_write_table(struct vty
*vty
)
2903 /* IPForwarding configuration write function. */
2904 static int config_write_forwarding(struct vty
*vty
)
2906 /* FIXME: Find better place for that. */
2907 router_id_write(vty
);
2910 vty_out(vty
, "no ip forwarding\n");
2911 if (!ipforward_ipv6())
2912 vty_out(vty
, "no ipv6 forwarding\n");
2913 vty_out(vty
, "!\n");
2917 DEFUN_HIDDEN (show_frr
,
2923 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
2924 vty_out(vty
, ".............................7777:..............................................\n");
2925 vty_out(vty
, ".............................777777,............................................\n");
2926 vty_out(vty
, "... .........................77777777,..........................................\n");
2927 vty_out(vty
, "............................=7777777777:........................................\n");
2928 vty_out(vty
, "........................:7777777777777777,......................................\n");
2929 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
2930 vty_out(vty
, "...................I7777777777+.................................................\n");
2931 vty_out(vty
, "................,777777777?............ .......................................\n");
2932 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
2933 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
2934 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
2935 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
2936 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
2937 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
2938 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
2939 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
2940 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
2941 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
2942 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
2943 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
2944 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
2945 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
2946 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
2947 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
2948 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
2949 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
2950 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
2951 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
2952 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
2953 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
2954 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
2955 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
2956 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
2957 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
2958 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
2959 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
2960 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
2961 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
2962 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
2963 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
2964 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
2965 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
2966 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
2967 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
2968 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
2969 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
2970 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
2971 vty_out(vty
, "............................~777777777777..............+777777..................\n");
2972 vty_out(vty
, "................................~77777777...............=777777.................\n");
2973 vty_out(vty
, ".....................................:=?I................~777777................\n");
2974 vty_out(vty
, "..........................................................:777777,..............\n");
2975 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
2980 /* IP node for static routes. */
2981 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2982 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2983 /* table node for routing tables. */
2984 static struct cmd_node table_node
= {TABLE_NODE
,
2985 "", /* This node has no interface. */
2987 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2988 "", /* This node has no interface. */
2992 void zebra_vty_init(void)
2994 /* Install configuration write function. */
2995 install_node(&table_node
, config_write_table
);
2996 install_node(&forwarding_node
, config_write_forwarding
);
2998 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2999 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3000 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3001 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3003 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3004 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3005 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3008 zebra_route_map_init();
3010 install_node(&ip_node
, zebra_ip_config
);
3011 install_node(&protocol_node
, config_write_protocol
);
3013 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3014 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3016 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3017 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3019 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3020 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3021 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3022 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3023 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3024 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3026 install_element(VIEW_NODE
, &show_vrf_cmd
);
3027 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3028 install_element(VIEW_NODE
, &show_route_cmd
);
3029 install_element(VIEW_NODE
, &show_route_table_cmd
);
3030 if (vrf_is_backend_netns())
3031 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3032 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3033 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3034 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3035 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3037 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3038 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3040 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3041 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3042 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3043 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3044 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3045 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3046 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3047 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3048 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3050 /* Commands for VRF */
3051 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3053 install_element(VIEW_NODE
, &show_frr_cmd
);
3054 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3055 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3056 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3057 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3058 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3059 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3060 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3061 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3062 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3063 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3064 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3065 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3066 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3067 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3068 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3069 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3070 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3071 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3072 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3073 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3074 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3075 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3076 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3077 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3078 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3079 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3081 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3082 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3084 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3085 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3086 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3087 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3089 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3090 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3091 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3092 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3094 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);