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/zserv.h"
39 #include "zebra/zebra_vrf.h"
40 #include "zebra/zebra_mpls.h"
41 #include "zebra/zebra_rnh.h"
42 #include "zebra/redistribute.h"
43 #include "zebra/zebra_routemap.h"
45 #include "zebra/zebra_vxlan.h"
46 #ifndef VTYSH_EXTRACT_PL
47 #include "zebra/zebra_vty_clippy.c"
49 #include "zebra/zserv.h"
50 #include "zebra/router-id.h"
51 #include "zebra/ipforward.h"
52 #include "zebra/zebra_vxlan_private.h"
53 #include "zebra/zebra_pbr.h"
55 extern int allow_delete
;
57 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
58 safi_t safi
, bool use_fib
, bool use_json
,
60 const struct prefix
*longer_prefix_p
,
61 bool supernets_only
, int type
,
62 unsigned short ospf_instance_id
);
63 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
65 static void vty_show_ip_route_summary(struct vty
*vty
,
66 struct route_table
*table
);
67 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
68 struct route_table
*table
);
70 /* VNI range as per RFC 7432 */
71 #define CMD_VNI_RANGE "(1-16777215)"
73 DEFUN (ip_multicast_mode
,
74 ip_multicast_mode_cmd
,
75 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
78 "RPF lookup behavior\n"
79 "Lookup in unicast RIB only\n"
80 "Lookup in multicast RIB only\n"
81 "Try multicast RIB first, fall back to unicast RIB\n"
82 "Lookup both, use entry with lower distance\n"
83 "Lookup both, use entry with longer prefix\n")
85 char *mode
= argv
[3]->text
;
87 if (strmatch(mode
, "urib-only"))
88 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
89 else if (strmatch(mode
, "mrib-only"))
90 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
91 else if (strmatch(mode
, "mrib-then-urib"))
92 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
93 else if (strmatch(mode
, "lower-distance"))
94 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
95 else if (strmatch(mode
, "longer-prefix"))
96 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
98 vty_out(vty
, "Invalid mode specified\n");
99 return CMD_WARNING_CONFIG_FAILED
;
105 DEFUN (no_ip_multicast_mode
,
106 no_ip_multicast_mode_cmd
,
107 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
110 "Multicast options\n"
111 "RPF lookup behavior\n"
112 "Lookup in unicast RIB only\n"
113 "Lookup in multicast RIB only\n"
114 "Try multicast RIB first, fall back to unicast RIB\n"
115 "Lookup both, use entry with lower distance\n"
116 "Lookup both, use entry with longer prefix\n")
118 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
125 "show ip rpf [json]",
128 "Display RPF information for multicast source\n"
131 bool uj
= use_json(argc
, argv
);
132 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
133 false, uj
, 0, NULL
, false, 0, 0);
136 DEFUN (show_ip_rpf_addr
,
137 show_ip_rpf_addr_cmd
,
138 "show ip rpf A.B.C.D",
141 "Display RPF information for multicast source\n"
142 "IP multicast source address (e.g. 10.0.0.0)\n")
146 struct route_node
*rn
;
147 struct route_entry
*re
;
150 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
152 vty_out(vty
, "%% Malformed address\n");
156 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
159 vty_show_ip_route_detail(vty
, rn
, 1);
161 vty_out(vty
, "%% No match for RPF lookup\n");
166 /* New RIB. Detailed information for IPv4 route. */
167 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
170 struct route_entry
*re
;
171 struct nexthop
*nexthop
;
172 char buf
[SRCDEST2STR_BUFFER
];
173 struct zebra_vrf
*zvrf
;
175 RNODE_FOREACH_RE (rn
, re
) {
176 const char *mcast_info
= "";
178 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
179 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
180 ? " using Multicast RIB"
181 : " using Unicast RIB";
184 vty_out(vty
, "Routing entry for %s%s\n",
185 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
186 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
188 vty_out(vty
, "[%d]", re
->instance
);
190 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
193 vty_out(vty
, ", tag %u", re
->tag
);
194 #if defined(SUPPORT_REALMS)
195 if (re
->tag
> 0 && re
->tag
<= 255)
196 vty_out(vty
, "(realm)");
200 vty_out(vty
, ", mtu %u", re
->mtu
);
201 if (re
->vrf_id
!= VRF_DEFAULT
) {
202 zvrf
= vrf_info_lookup(re
->vrf_id
);
203 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
205 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
206 vty_out(vty
, ", best");
213 uptime
-= re
->uptime
;
214 tm
= gmtime(&uptime
);
216 vty_out(vty
, " Last update ");
218 if (uptime
< ONE_DAY_SECOND
)
219 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
221 else if (uptime
< ONE_WEEK_SECOND
)
222 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
225 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
226 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
228 vty_out(vty
, " ago\n");
230 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
233 vty_out(vty
, " %c%s",
234 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
235 ? CHECK_FLAG(nexthop
->flags
,
236 NEXTHOP_FLAG_DUPLICATE
)
240 nexthop
->rparent
? " " : "");
242 switch (nexthop
->type
) {
243 case NEXTHOP_TYPE_IPV4
:
244 case NEXTHOP_TYPE_IPV4_IFINDEX
:
246 inet_ntoa(nexthop
->gate
.ipv4
));
247 if (nexthop
->ifindex
)
248 vty_out(vty
, ", via %s",
253 case NEXTHOP_TYPE_IPV6
:
254 case NEXTHOP_TYPE_IPV6_IFINDEX
:
256 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
258 if (nexthop
->ifindex
)
259 vty_out(vty
, ", via %s",
264 case NEXTHOP_TYPE_IFINDEX
:
265 vty_out(vty
, " directly connected, %s",
266 ifindex2ifname(nexthop
->ifindex
,
269 case NEXTHOP_TYPE_BLACKHOLE
:
270 vty_out(vty
, " unreachable");
271 switch (nexthop
->bh_type
) {
272 case BLACKHOLE_REJECT
:
273 vty_out(vty
, " (ICMP unreachable)");
275 case BLACKHOLE_ADMINPROHIB
:
277 " (ICMP admin-prohibited)");
280 vty_out(vty
, " (blackhole)");
282 case BLACKHOLE_UNSPEC
:
290 if ((re
->vrf_id
!= nexthop
->vrf_id
)
291 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
293 vrf_lookup_by_id(nexthop
->vrf_id
);
296 vty_out(vty
, "(vrf %s)", vrf
->name
);
298 vty_out(vty
, "(vrf UKNOWN)");
301 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
302 vty_out(vty
, " (duplicate nexthop removed)");
304 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
305 vty_out(vty
, " inactive");
307 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
308 vty_out(vty
, " onlink");
310 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
311 vty_out(vty
, " (recursive)");
313 switch (nexthop
->type
) {
314 case NEXTHOP_TYPE_IPV4
:
315 case NEXTHOP_TYPE_IPV4_IFINDEX
:
316 if (nexthop
->src
.ipv4
.s_addr
) {
317 if (inet_ntop(AF_INET
,
319 addrstr
, sizeof addrstr
))
320 vty_out(vty
, ", src %s",
324 case NEXTHOP_TYPE_IPV6
:
325 case NEXTHOP_TYPE_IPV6_IFINDEX
:
326 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
328 if (inet_ntop(AF_INET6
,
330 addrstr
, sizeof addrstr
))
331 vty_out(vty
, ", src %s",
340 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
342 /* Label information */
343 if (nexthop
->nh_label
344 && nexthop
->nh_label
->num_labels
) {
345 vty_out(vty
, ", label %s",
347 nexthop
->nh_label
->num_labels
,
348 nexthop
->nh_label
->label
, buf
,
358 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
359 struct route_entry
*re
, json_object
*json
)
361 struct nexthop
*nexthop
;
363 char buf
[SRCDEST2STR_BUFFER
];
364 json_object
*json_nexthops
= NULL
;
365 json_object
*json_nexthop
= NULL
;
366 json_object
*json_route
= NULL
;
367 json_object
*json_labels
= NULL
;
372 uptime
-= re
->uptime
;
373 tm
= gmtime(&uptime
);
376 json_route
= json_object_new_object();
377 json_nexthops
= json_object_new_array();
379 json_object_string_add(json_route
, "prefix",
380 srcdest_rnode2str(rn
, buf
, sizeof buf
));
381 json_object_string_add(json_route
, "protocol",
382 zebra_route_string(re
->type
));
385 json_object_int_add(json_route
, "instance",
389 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
391 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
392 json_object_boolean_true_add(json_route
, "selected");
394 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
395 json_object_int_add(json_route
, "distance",
397 json_object_int_add(json_route
, "metric", re
->metric
);
401 json_object_int_add(json_route
, "tag", re
->tag
);
403 json_object_int_add(json_route
, "internalStatus",
405 json_object_int_add(json_route
, "internalFlags",
407 if (uptime
< ONE_DAY_SECOND
)
408 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
410 else if (uptime
< ONE_WEEK_SECOND
)
411 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
414 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
415 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
418 json_object_string_add(json_route
, "uptime", buf
);
420 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
421 json_nexthop
= json_object_new_object();
423 json_object_int_add(json_nexthop
, "flags",
426 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
427 json_object_boolean_true_add(json_nexthop
,
430 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
431 json_object_boolean_true_add(json_nexthop
,
434 switch (nexthop
->type
) {
435 case NEXTHOP_TYPE_IPV4
:
436 case NEXTHOP_TYPE_IPV4_IFINDEX
:
437 json_object_string_add(
439 inet_ntoa(nexthop
->gate
.ipv4
));
440 json_object_string_add(json_nexthop
, "afi",
443 if (nexthop
->ifindex
) {
444 json_object_int_add(json_nexthop
,
447 json_object_string_add(
448 json_nexthop
, "interfaceName",
454 case NEXTHOP_TYPE_IPV6
:
455 case NEXTHOP_TYPE_IPV6_IFINDEX
:
456 json_object_string_add(
458 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
460 json_object_string_add(json_nexthop
, "afi",
463 if (nexthop
->ifindex
) {
464 json_object_int_add(json_nexthop
,
467 json_object_string_add(
468 json_nexthop
, "interfaceName",
475 case NEXTHOP_TYPE_IFINDEX
:
476 json_object_boolean_true_add(
477 json_nexthop
, "directlyConnected");
478 json_object_int_add(json_nexthop
,
481 json_object_string_add(
482 json_nexthop
, "interfaceName",
483 ifindex2ifname(nexthop
->ifindex
,
486 case NEXTHOP_TYPE_BLACKHOLE
:
487 json_object_boolean_true_add(json_nexthop
,
489 switch (nexthop
->bh_type
) {
490 case BLACKHOLE_REJECT
:
491 json_object_boolean_true_add(
492 json_nexthop
, "reject");
494 case BLACKHOLE_ADMINPROHIB
:
495 json_object_boolean_true_add(
500 json_object_boolean_true_add(
501 json_nexthop
, "blackhole");
503 case BLACKHOLE_UNSPEC
:
511 if ((nexthop
->vrf_id
!= re
->vrf_id
)
512 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
514 vrf_lookup_by_id(nexthop
->vrf_id
);
516 json_object_string_add(json_nexthop
, "vrf",
519 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
520 json_object_boolean_true_add(json_nexthop
,
523 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
524 json_object_boolean_true_add(json_nexthop
,
527 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
528 json_object_boolean_true_add(json_nexthop
,
531 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
532 json_object_boolean_true_add(json_nexthop
,
535 switch (nexthop
->type
) {
536 case NEXTHOP_TYPE_IPV4
:
537 case NEXTHOP_TYPE_IPV4_IFINDEX
:
538 if (nexthop
->src
.ipv4
.s_addr
) {
539 if (inet_ntop(AF_INET
,
540 &nexthop
->src
.ipv4
, buf
,
542 json_object_string_add(
543 json_nexthop
, "source",
547 case NEXTHOP_TYPE_IPV6
:
548 case NEXTHOP_TYPE_IPV6_IFINDEX
:
549 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
551 if (inet_ntop(AF_INET6
,
552 &nexthop
->src
.ipv6
, buf
,
554 json_object_string_add(
555 json_nexthop
, "source",
563 if (nexthop
->nh_label
564 && nexthop
->nh_label
->num_labels
) {
565 json_labels
= json_object_new_array();
567 for (int label_index
= 0;
569 < nexthop
->nh_label
->num_labels
;
571 json_object_array_add(
574 nexthop
->nh_label
->label
577 json_object_object_add(json_nexthop
, "labels",
581 json_object_array_add(json_nexthops
, json_nexthop
);
584 json_object_object_add(json_route
, "nexthops", json_nexthops
);
585 json_object_array_add(json
, json_route
);
589 /* Nexthop information. */
590 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
591 if (nexthop
== re
->ng
.nexthop
) {
592 /* Prefix information. */
593 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
595 len
+= vty_out(vty
, "[%d]", re
->instance
);
598 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
601 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
604 srcdest_rnode2str(rn
, buf
, sizeof buf
));
606 /* Distance and metric display. */
607 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
608 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
611 vty_out(vty
, " %c%*c",
612 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
613 ? CHECK_FLAG(nexthop
->flags
,
614 NEXTHOP_FLAG_DUPLICATE
)
618 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
621 switch (nexthop
->type
) {
622 case NEXTHOP_TYPE_IPV4
:
623 case NEXTHOP_TYPE_IPV4_IFINDEX
:
624 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
625 if (nexthop
->ifindex
)
627 ifindex2ifname(nexthop
->ifindex
,
630 case NEXTHOP_TYPE_IPV6
:
631 case NEXTHOP_TYPE_IPV6_IFINDEX
:
632 vty_out(vty
, " via %s",
633 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
635 if (nexthop
->ifindex
)
637 ifindex2ifname(nexthop
->ifindex
,
641 case NEXTHOP_TYPE_IFINDEX
:
642 vty_out(vty
, " is directly connected, %s",
643 ifindex2ifname(nexthop
->ifindex
,
646 case NEXTHOP_TYPE_BLACKHOLE
:
647 vty_out(vty
, " unreachable");
648 switch (nexthop
->bh_type
) {
649 case BLACKHOLE_REJECT
:
650 vty_out(vty
, " (ICMP unreachable)");
652 case BLACKHOLE_ADMINPROHIB
:
653 vty_out(vty
, " (ICMP admin-prohibited)");
656 vty_out(vty
, " (blackhole)");
658 case BLACKHOLE_UNSPEC
:
666 if ((nexthop
->vrf_id
!= re
->vrf_id
)
667 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
668 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
671 vty_out(vty
, "(vrf %s)", vrf
->name
);
673 vty_out(vty
, "(vrf UKNOWN)");
676 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
677 vty_out(vty
, " inactive");
679 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
680 vty_out(vty
, " onlink");
682 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
683 vty_out(vty
, " (recursive)");
685 switch (nexthop
->type
) {
686 case NEXTHOP_TYPE_IPV4
:
687 case NEXTHOP_TYPE_IPV4_IFINDEX
:
688 if (nexthop
->src
.ipv4
.s_addr
) {
689 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
691 vty_out(vty
, ", src %s", buf
);
694 case NEXTHOP_TYPE_IPV6
:
695 case NEXTHOP_TYPE_IPV6_IFINDEX
:
696 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
697 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
699 vty_out(vty
, ", src %s", buf
);
706 /* Label information */
707 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
708 vty_out(vty
, ", label %s",
709 mpls_label2str(nexthop
->nh_label
->num_labels
,
710 nexthop
->nh_label
->label
, buf
,
714 if (uptime
< ONE_DAY_SECOND
)
715 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
716 tm
->tm_min
, tm
->tm_sec
);
717 else if (uptime
< ONE_WEEK_SECOND
)
718 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
719 tm
->tm_hour
, tm
->tm_min
);
721 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
722 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
728 static void vty_show_ip_route_detail_json(struct vty
*vty
,
729 struct route_node
*rn
)
731 json_object
*json
= NULL
;
732 json_object
*json_prefix
= NULL
;
733 struct route_entry
*re
;
736 json
= json_object_new_object();
738 RNODE_FOREACH_RE (rn
, re
) {
739 json_prefix
= json_object_new_array();
740 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
741 prefix2str(&rn
->p
, buf
, sizeof buf
);
742 json_object_object_add(json
, buf
, json_prefix
);
746 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
747 json
, JSON_C_TO_STRING_PRETTY
));
748 json_object_free(json
);
751 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
752 struct route_table
*table
, afi_t afi
,
753 bool use_fib
, route_tag_t tag
,
754 const struct prefix
*longer_prefix_p
,
755 bool supernets_only
, int type
,
756 unsigned short ospf_instance_id
, bool use_json
)
758 struct route_node
*rn
;
759 struct route_entry
*re
;
762 json_object
*json
= NULL
;
763 json_object
*json_prefix
= NULL
;
768 json
= json_object_new_object();
770 /* Show all routes. */
771 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
772 dest
= rib_dest_from_rnode(rn
);
774 RNODE_FOREACH_RE (rn
, re
) {
775 if (use_fib
&& re
!= dest
->selected_fib
)
778 if (tag
&& re
->tag
!= tag
)
782 && !prefix_match(longer_prefix_p
, &rn
->p
))
785 /* This can only be true when the afi is IPv4 */
786 if (supernets_only
) {
787 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
789 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
792 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
795 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
799 if (type
&& re
->type
!= type
)
803 && (re
->type
!= ZEBRA_ROUTE_OSPF
804 || re
->instance
!= ospf_instance_id
))
809 json_prefix
= json_object_new_array();
814 SHOW_ROUTE_V4_HEADER
);
817 SHOW_ROUTE_V6_HEADER
);
819 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
820 vty_out(vty
, "\nVRF %s:\n",
827 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
831 prefix2str(&rn
->p
, buf
, sizeof(buf
));
832 json_object_object_add(json
, buf
, json_prefix
);
838 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
839 JSON_C_TO_STRING_PRETTY
));
840 json_object_free(json
);
844 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
845 safi_t safi
, bool use_fib
, bool use_json
,
847 const struct prefix
*longer_prefix_p
,
848 bool supernets_only
, int type
,
849 unsigned short ospf_instance_id
)
851 struct route_table
*table
;
852 struct zebra_vrf
*zvrf
= NULL
;
854 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
856 vty_out(vty
, "{}\n");
858 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
862 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
864 vty_out(vty
, "{}\n");
866 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
870 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
873 vty_out(vty
, "{}\n");
877 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
878 longer_prefix_p
, supernets_only
, type
,
879 ospf_instance_id
, use_json
);
884 DEFPY (show_route_table
,
885 show_route_table_cmd
,
886 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
892 "The table number to display, if available\n"
895 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
896 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
897 struct route_table
*t
;
899 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
901 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
907 DEFPY (show_route_table_vrf
,
908 show_route_table_vrf_cmd
,
909 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
915 "The table number to display, if available\n"
919 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
920 struct zebra_vrf
*zvrf
;
921 struct route_table
*t
;
922 vrf_id_t vrf_id
= VRF_DEFAULT
;
925 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
926 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
928 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
930 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
938 "show ip nht [vrf NAME]",
941 "IP nexthop tracking table\n"
945 vrf_id_t vrf_id
= VRF_DEFAULT
;
948 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
950 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
955 DEFUN (show_ip_nht_vrf_all
,
956 show_ip_nht_vrf_all_cmd
,
957 "show ip nht vrf all",
960 "IP nexthop tracking table\n"
961 VRF_ALL_CMD_HELP_STR
)
964 struct zebra_vrf
*zvrf
;
966 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
967 if ((zvrf
= vrf
->info
) != NULL
) {
968 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
969 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
976 DEFUN (show_ipv6_nht
,
978 "show ipv6 nht [vrf NAME]",
981 "IPv6 nexthop tracking table\n"
985 vrf_id_t vrf_id
= VRF_DEFAULT
;
988 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
990 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
995 DEFUN (show_ipv6_nht_vrf_all
,
996 show_ipv6_nht_vrf_all_cmd
,
997 "show ipv6 nht vrf all",
1000 "IPv6 nexthop tracking table\n"
1001 VRF_ALL_CMD_HELP_STR
)
1004 struct zebra_vrf
*zvrf
;
1006 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1007 if ((zvrf
= vrf
->info
) != NULL
) {
1008 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1009 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1016 DEFUN (ip_nht_default_route
,
1017 ip_nht_default_route_cmd
,
1018 "ip nht resolve-via-default",
1020 "Filter Next Hop tracking route resolution\n"
1021 "Resolve via default route\n")
1023 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1028 if (zebra_rnh_ip_default_route
)
1031 zebra_rnh_ip_default_route
= 1;
1033 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1037 DEFUN (no_ip_nht_default_route
,
1038 no_ip_nht_default_route_cmd
,
1039 "no ip nht resolve-via-default",
1042 "Filter Next Hop tracking route resolution\n"
1043 "Resolve via default route\n")
1045 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1050 if (!zebra_rnh_ip_default_route
)
1053 zebra_rnh_ip_default_route
= 0;
1054 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1058 DEFUN (ipv6_nht_default_route
,
1059 ipv6_nht_default_route_cmd
,
1060 "ipv6 nht resolve-via-default",
1062 "Filter Next Hop tracking route resolution\n"
1063 "Resolve via default route\n")
1065 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1070 if (zebra_rnh_ipv6_default_route
)
1073 zebra_rnh_ipv6_default_route
= 1;
1074 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1078 DEFUN (no_ipv6_nht_default_route
,
1079 no_ipv6_nht_default_route_cmd
,
1080 "no ipv6 nht resolve-via-default",
1083 "Filter Next Hop tracking route resolution\n"
1084 "Resolve via default route\n")
1087 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1092 if (!zebra_rnh_ipv6_default_route
)
1095 zebra_rnh_ipv6_default_route
= 0;
1096 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1104 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1107 |A.B.C.D/M$prefix longer-prefixes\
1108 |supernets-only$supernets_only\
1111 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1112 |ospf$type_str (1-65535)$ospf_instance_id\
1114 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1117 |X:X::X:X/M$prefix longer-prefixes\
1119 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1124 "IP forwarding table\n"
1125 "IP routing table\n"
1126 VRF_FULL_CMD_HELP_STR
1127 "Show only routes with tag\n"
1129 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1130 "Show route matching the specified Network/Mask pair only\n"
1131 "Show supernet entries only\n"
1132 FRR_IP_REDIST_HELP_STR_ZEBRA
1133 "Open Shortest Path First (OSPFv2)\n"
1136 "IP forwarding table\n"
1137 "IP routing table\n"
1138 VRF_FULL_CMD_HELP_STR
1139 "Show only routes with tag\n"
1142 "Show route matching the specified Network/Mask pair only\n"
1143 FRR_IP6_REDIST_HELP_STR_ZEBRA
1146 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1151 type
= proto_redistnum(afi
, type_str
);
1153 vty_out(vty
, "Unknown route type\n");
1159 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1160 struct zebra_vrf
*zvrf
;
1161 struct route_table
*table
;
1163 if ((zvrf
= vrf
->info
) == NULL
1164 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1168 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1169 !!json
, tag
, prefix_str
? prefix
: NULL
,
1170 !!supernets_only
, type
, ospf_instance_id
);
1173 vrf_id_t vrf_id
= VRF_DEFAULT
;
1176 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1177 vrf
= vrf_lookup_by_id(vrf_id
);
1178 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1179 !!json
, tag
, prefix_str
? prefix
: NULL
,
1180 !!supernets_only
, type
, ospf_instance_id
);
1186 DEFPY (show_route_detail
,
1187 show_route_detail_cmd
,
1190 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1195 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1204 "IP routing table\n"
1205 VRF_FULL_CMD_HELP_STR
1206 "Network in the IP routing table to display\n"
1207 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1209 "IP routing table\n"
1210 VRF_FULL_CMD_HELP_STR
1215 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1216 struct route_table
*table
;
1218 struct route_node
*rn
;
1221 prefix_str
= address_str
;
1222 if (str2prefix(prefix_str
, &p
) < 0) {
1223 vty_out(vty
, "%% Malformed address\n");
1229 struct zebra_vrf
*zvrf
;
1231 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1232 if ((zvrf
= vrf
->info
) == NULL
1233 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1236 rn
= route_node_match(table
, &p
);
1239 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1240 route_unlock_node(rn
);
1245 vty_show_ip_route_detail_json(vty
, rn
);
1247 vty_show_ip_route_detail(vty
, rn
, 0);
1249 route_unlock_node(rn
);
1252 vrf_id_t vrf_id
= VRF_DEFAULT
;
1255 VRF_GET_ID(vrf_id
, vrf_name
, false);
1257 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1261 rn
= route_node_match(table
, &p
);
1263 vty_out(vty
, "%% Network not in table\n");
1266 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1267 vty_out(vty
, "%% Network not in table\n");
1268 route_unlock_node(rn
);
1273 vty_show_ip_route_detail_json(vty
, rn
);
1275 vty_show_ip_route_detail(vty
, rn
, 0);
1277 route_unlock_node(rn
);
1283 DEFPY (show_route_summary
,
1284 show_route_summary_cmd
,
1287 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1288 summary [prefix$prefix]\
1289 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1290 summary [prefix$prefix]\
1294 "IP routing table\n"
1295 VRF_FULL_CMD_HELP_STR
1296 "Summary of all routes\n"
1299 "IP routing table\n"
1300 VRF_FULL_CMD_HELP_STR
1301 "Summary of all routes\n"
1304 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1305 struct route_table
*table
;
1309 struct zebra_vrf
*zvrf
;
1311 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1312 if ((zvrf
= vrf
->info
) == NULL
1313 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1317 vty_show_ip_route_summary_prefix(vty
, table
);
1319 vty_show_ip_route_summary(vty
, table
);
1322 vrf_id_t vrf_id
= VRF_DEFAULT
;
1325 VRF_GET_ID(vrf_id
, vrf_name
, false);
1327 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1332 vty_show_ip_route_summary_prefix(vty
, table
);
1334 vty_show_ip_route_summary(vty
, table
);
1340 static void vty_show_ip_route_summary(struct vty
*vty
,
1341 struct route_table
*table
)
1343 struct route_node
*rn
;
1344 struct route_entry
*re
;
1345 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1346 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1347 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1348 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1352 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1353 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1354 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1355 RNODE_FOREACH_RE (rn
, re
) {
1356 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1357 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1359 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1361 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1363 rib_cnt
[re
->type
]++;
1365 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1366 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1369 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1371 fib_cnt
[re
->type
]++;
1375 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1376 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1378 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1379 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1380 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1381 if (i
== ZEBRA_ROUTE_BGP
) {
1382 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1383 rib_cnt
[ZEBRA_ROUTE_BGP
],
1384 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1385 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1386 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1387 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1389 vty_out(vty
, "%-20s %-20d %-20d \n",
1390 zebra_route_string(i
), rib_cnt
[i
],
1395 vty_out(vty
, "------\n");
1396 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1397 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1402 * Implementation of the ip route summary prefix command.
1404 * This command prints the primary prefixes that have been installed by various
1405 * protocols on the box.
1408 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1409 struct route_table
*table
)
1411 struct route_node
*rn
;
1412 struct route_entry
*re
;
1413 struct nexthop
*nexthop
;
1414 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1415 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1416 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1417 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1421 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1422 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1423 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1424 RNODE_FOREACH_RE (rn
, re
) {
1427 * In case of ECMP, count only once.
1430 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1431 nexthop
= nexthop
->next
) {
1433 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1434 rib_cnt
[re
->type
]++;
1435 if (CHECK_FLAG(nexthop
->flags
,
1436 NEXTHOP_FLAG_FIB
)) {
1437 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1438 fib_cnt
[re
->type
]++;
1440 if (re
->type
== ZEBRA_ROUTE_BGP
1441 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1442 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1443 if (CHECK_FLAG(nexthop
->flags
,
1445 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1450 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1451 "Prefix Routes", "FIB",
1452 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1454 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1455 if (rib_cnt
[i
] > 0) {
1456 if (i
== ZEBRA_ROUTE_BGP
) {
1457 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1458 rib_cnt
[ZEBRA_ROUTE_BGP
]
1459 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1460 fib_cnt
[ZEBRA_ROUTE_BGP
]
1461 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1462 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1463 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1464 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1466 vty_out(vty
, "%-20s %-20d %-20d \n",
1467 zebra_route_string(i
), rib_cnt
[i
],
1472 vty_out(vty
, "------\n");
1473 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1474 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1479 * Show IPv6 mroute command.Used to dump
1480 * the Multicast routing table.
1482 DEFUN (show_ipv6_mroute
,
1483 show_ipv6_mroute_cmd
,
1484 "show ipv6 mroute [vrf NAME]",
1487 "IPv6 Multicast routing table\n"
1490 struct route_table
*table
;
1491 struct route_node
*rn
;
1492 struct route_entry
*re
;
1494 vrf_id_t vrf_id
= VRF_DEFAULT
;
1497 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1499 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1503 /* Show all IPv6 route. */
1504 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1505 RNODE_FOREACH_RE (rn
, re
) {
1507 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1510 vty_show_ip_route(vty
, rn
, re
, NULL
);
1515 DEFUN (show_ipv6_mroute_vrf_all
,
1516 show_ipv6_mroute_vrf_all_cmd
,
1517 "show ipv6 mroute vrf all",
1520 "IPv6 Multicast routing table\n"
1521 VRF_ALL_CMD_HELP_STR
)
1523 struct route_table
*table
;
1524 struct route_node
*rn
;
1525 struct route_entry
*re
;
1527 struct zebra_vrf
*zvrf
;
1530 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1531 if ((zvrf
= vrf
->info
) == NULL
1532 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1535 /* Show all IPv6 route. */
1536 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1537 RNODE_FOREACH_RE (rn
, re
) {
1539 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1542 vty_show_ip_route(vty
, rn
, re
, NULL
);
1548 DEFUN (allow_external_route_update
,
1549 allow_external_route_update_cmd
,
1550 "allow-external-route-update",
1551 "Allow FRR routes to be overwritten by external processes\n")
1558 DEFUN (no_allow_external_route_update
,
1559 no_allow_external_route_update_cmd
,
1560 "no allow-external-route-update",
1562 "Allow FRR routes to be overwritten by external processes\n")
1577 struct zebra_vrf
*zvrf
;
1579 if (vrf_is_backend_netns())
1580 vty_out(vty
, "netns-based vrfs\n");
1582 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1583 if (!(zvrf
= vrf
->info
))
1585 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1588 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1589 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1590 vty_out(vty
, "inactive");
1591 else if (zvrf_ns_name(zvrf
))
1592 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1593 zvrf_ns_name(zvrf
));
1595 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1597 if (vrf_is_user_cfged(vrf
))
1598 vty_out(vty
, " (configured)");
1605 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1606 default_vrf_vni_mapping_cmd
,
1607 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1608 "VNI corresponding to the DEFAULT VRF\n"
1610 "Prefix routes only \n")
1613 char err
[ERR_STR_SZ
];
1614 struct zebra_vrf
*zvrf
= NULL
;
1615 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1618 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1625 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1628 vty_out(vty
, "%s\n", err
);
1635 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1636 no_default_vrf_vni_mapping_cmd
,
1637 "no vni " CMD_VNI_RANGE
,
1639 "VNI corresponding to DEFAULT VRF\n"
1643 char err
[ERR_STR_SZ
];
1644 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1645 struct zebra_vrf
*zvrf
= NULL
;
1647 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1651 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1653 vty_out(vty
, "%s\n", err
);
1660 DEFUN (vrf_vni_mapping
,
1661 vrf_vni_mapping_cmd
,
1662 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1663 "VNI corresponding to tenant VRF\n"
1665 "prefix-routes-only\n")
1670 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1671 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1672 char err
[ERR_STR_SZ
];
1680 /* Mark as having FRR configuration */
1681 vrf_set_user_cfged(vrf
);
1682 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1685 vty_out(vty
, "%s\n", err
);
1692 DEFUN (no_vrf_vni_mapping
,
1693 no_vrf_vni_mapping_cmd
,
1694 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1696 "VNI corresponding to tenant VRF\n"
1698 "prefix-routes-only\n")
1702 char err
[ERR_STR_SZ
];
1703 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1705 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1713 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1714 ERR_STR_SZ
, filter
, 0);
1716 vty_out(vty
, "%s\n", err
);
1720 /* If no other FRR config for this VRF, mark accordingly. */
1721 if (!zebra_vrf_has_config(zvrf
))
1722 vrf_reset_user_cfged(vrf
);
1728 DEFUN (show_vrf_vni
,
1730 "show vrf vni [json]",
1737 struct zebra_vrf
*zvrf
;
1738 json_object
*json
= NULL
;
1739 json_object
*json_vrfs
= NULL
;
1740 bool uj
= use_json(argc
, argv
);
1743 json
= json_object_new_object();
1744 json_vrfs
= json_object_new_array();
1748 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1749 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1751 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1756 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1760 json_object_object_add(json
, "vrfs", json_vrfs
);
1761 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1762 json
, JSON_C_TO_STRING_PRETTY
));
1763 json_object_free(json
);
1769 DEFUN (show_evpn_global
,
1770 show_evpn_global_cmd
,
1776 bool uj
= use_json(argc
, argv
);
1778 zebra_vxlan_print_evpn(vty
, uj
);
1782 DEFUN (show_evpn_vni
,
1784 "show evpn vni [json]",
1787 "VxLAN information\n"
1790 struct zebra_vrf
*zvrf
;
1791 bool uj
= use_json(argc
, argv
);
1793 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1794 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1798 DEFUN (show_evpn_vni_vni
,
1799 show_evpn_vni_vni_cmd
,
1800 "show evpn vni " CMD_VNI_RANGE
"[json]",
1803 "VxLAN Network Identifier\n"
1807 struct zebra_vrf
*zvrf
;
1809 bool uj
= use_json(argc
, argv
);
1811 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1812 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1813 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1817 DEFUN (show_evpn_rmac_vni_mac
,
1818 show_evpn_rmac_vni_mac_cmd
,
1819 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1826 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1831 bool uj
= use_json(argc
, argv
);
1833 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1834 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1835 vty_out(vty
, "%% Malformed MAC address\n");
1838 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1842 DEFUN (show_evpn_rmac_vni
,
1843 show_evpn_rmac_vni_cmd
,
1844 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1853 bool uj
= use_json(argc
, argv
);
1855 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1856 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1861 DEFUN (show_evpn_rmac_vni_all
,
1862 show_evpn_rmac_vni_all_cmd
,
1863 "show evpn rmac vni all [json]",
1871 bool uj
= use_json(argc
, argv
);
1873 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1878 DEFUN (show_evpn_nh_vni_ip
,
1879 show_evpn_nh_vni_ip_cmd
,
1880 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1887 "Host address (ipv4 or ipv6)\n"
1892 bool uj
= use_json(argc
, argv
);
1894 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1895 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1897 vty_out(vty
, "%% Malformed Neighbor address\n");
1900 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1905 DEFUN (show_evpn_nh_vni
,
1906 show_evpn_nh_vni_cmd
,
1907 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1916 bool uj
= use_json(argc
, argv
);
1918 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1919 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1924 DEFUN (show_evpn_nh_vni_all
,
1925 show_evpn_nh_vni_all_cmd
,
1926 "show evpn next-hops vni all [json]",
1934 bool uj
= use_json(argc
, argv
);
1936 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1941 DEFUN (show_evpn_mac_vni
,
1942 show_evpn_mac_vni_cmd
,
1943 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1947 "VxLAN Network Identifier\n"
1951 struct zebra_vrf
*zvrf
;
1953 bool uj
= use_json(argc
, argv
);
1955 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1956 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1957 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1961 DEFUN (show_evpn_mac_vni_all
,
1962 show_evpn_mac_vni_all_cmd
,
1963 "show evpn mac vni all [json]",
1967 "VxLAN Network Identifier\n"
1971 struct zebra_vrf
*zvrf
;
1972 bool uj
= use_json(argc
, argv
);
1974 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1975 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
1979 DEFUN (show_evpn_mac_vni_all_vtep
,
1980 show_evpn_mac_vni_all_vtep_cmd
,
1981 "show evpn mac vni all vtep A.B.C.D [json]",
1985 "VxLAN Network Identifier\n"
1988 "Remote VTEP IP address\n"
1991 struct zebra_vrf
*zvrf
;
1992 struct in_addr vtep_ip
;
1993 bool uj
= use_json(argc
, argv
);
1995 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
1997 vty_out(vty
, "%% Malformed VTEP IP address\n");
2000 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2001 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2007 DEFUN (show_evpn_mac_vni_mac
,
2008 show_evpn_mac_vni_mac_cmd
,
2009 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2013 "VxLAN Network Identifier\n"
2016 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2018 struct zebra_vrf
*zvrf
;
2022 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2023 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2024 vty_out(vty
, "%% Malformed MAC address");
2027 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2028 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2032 DEFUN (show_evpn_mac_vni_vtep
,
2033 show_evpn_mac_vni_vtep_cmd
,
2034 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2038 "VxLAN Network Identifier\n"
2041 "Remote VTEP IP address\n"
2044 struct zebra_vrf
*zvrf
;
2046 struct in_addr vtep_ip
;
2047 bool uj
= use_json(argc
, argv
);
2049 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2050 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2052 vty_out(vty
, "%% Malformed VTEP IP address\n");
2056 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2057 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2061 DEFUN (show_evpn_neigh_vni
,
2062 show_evpn_neigh_vni_cmd
,
2063 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2066 "ARP and ND cache\n"
2067 "VxLAN Network Identifier\n"
2071 struct zebra_vrf
*zvrf
;
2073 bool uj
= use_json(argc
, argv
);
2075 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2076 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2077 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2081 DEFUN (show_evpn_neigh_vni_all
,
2082 show_evpn_neigh_vni_all_cmd
,
2083 "show evpn arp-cache vni all [json]",
2086 "ARP and ND cache\n"
2087 "VxLAN Network Identifier\n"
2091 struct zebra_vrf
*zvrf
;
2092 bool uj
= use_json(argc
, argv
);
2094 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2095 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2099 DEFUN (show_evpn_neigh_vni_neigh
,
2100 show_evpn_neigh_vni_neigh_cmd
,
2101 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2104 "ARP and ND cache\n"
2105 "VxLAN Network Identifier\n"
2108 "Neighbor address (IPv4 or IPv6 address)\n"
2111 struct zebra_vrf
*zvrf
;
2114 bool uj
= use_json(argc
, argv
);
2116 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2117 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2119 vty_out(vty
, "%% Malformed Neighbor address\n");
2122 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2123 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2127 DEFUN (show_evpn_neigh_vni_vtep
,
2128 show_evpn_neigh_vni_vtep_cmd
,
2129 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2132 "ARP and ND cache\n"
2133 "VxLAN Network Identifier\n"
2136 "Remote VTEP IP address\n"
2139 struct zebra_vrf
*zvrf
;
2141 struct in_addr vtep_ip
;
2142 bool uj
= use_json(argc
, argv
);
2144 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2145 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2147 vty_out(vty
, "%% Malformed VTEP IP address\n");
2151 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2152 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2156 /* policy routing contexts */
2157 DEFUN (show_pbr_ipset
,
2159 "show pbr ipset [WORD]",
2161 "Policy-Based Routing\n"
2162 "IPset Context information\n"
2163 "IPset Name information\n")
2167 found
= argv_find(argv
, argc
, "WORD", &idx
);
2169 zebra_pbr_show_ipset_list(vty
, NULL
);
2171 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2175 /* policy routing contexts */
2176 DEFUN (show_pbr_iptable
,
2177 show_pbr_iptable_cmd
,
2178 "show pbr iptable [WORD]",
2180 "Policy-Based Routing\n"
2181 "IPtable Context information\n"
2182 "IPtable Name information\n")
2187 found
= argv_find(argv
, argc
, "WORD", &idx
);
2189 zebra_pbr_show_iptable(vty
, NULL
);
2191 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2195 /* Static ip route configuration write function. */
2196 static int zebra_ip_config(struct vty
*vty
)
2200 write
+= zebra_import_table_config(vty
);
2205 DEFUN (ip_zebra_import_table_distance
,
2206 ip_zebra_import_table_distance_cmd
,
2207 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2209 "import routes from non-main kernel table\n"
2210 "kernel routing table id\n"
2211 "Distance for imported routes\n"
2212 "Default distance value\n"
2213 "route-map for filtering\n"
2216 uint32_t table_id
= 0;
2218 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2219 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2221 strmatch(argv
[argc
- 2]->text
, "route-map")
2222 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2226 if (argc
== 7 || (argc
== 5 && !rmap
))
2227 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2229 if (!is_zebra_valid_kernel_table(table_id
)) {
2231 "Invalid routing table ID, %d. Must be in range 1-252\n",
2234 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2238 if (is_zebra_main_routing_table(table_id
)) {
2240 "Invalid routing table ID, %d. Must be non-default table\n",
2243 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2247 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2249 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2254 DEFUN_HIDDEN (zebra_packet_process
,
2255 zebra_packet_process_cmd
,
2256 "zebra zapi-packets (1-10000)",
2259 "Number of packets to process before relinquishing thread\n")
2261 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2263 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2264 memory_order_relaxed
);
2269 DEFUN_HIDDEN (no_zebra_packet_process
,
2270 no_zebra_packet_process_cmd
,
2271 "no zebra zapi-packets [(1-10000)]",
2275 "Number of packets to process before relinquishing thread\n")
2277 atomic_store_explicit(&zebrad
.packets_to_process
,
2278 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2279 memory_order_relaxed
);
2284 DEFUN_HIDDEN (zebra_workqueue_timer
,
2285 zebra_workqueue_timer_cmd
,
2286 "zebra work-queue (0-10000)",
2289 "Time in milliseconds\n")
2291 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2292 zebrad
.ribq
->spec
.hold
= timer
;
2297 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2298 no_zebra_workqueue_timer_cmd
,
2299 "no zebra work-queue [(0-10000)]",
2303 "Time in milliseconds\n")
2305 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2310 DEFUN (no_ip_zebra_import_table
,
2311 no_ip_zebra_import_table_cmd
,
2312 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2315 "import routes from non-main kernel table\n"
2316 "kernel routing table id\n"
2317 "Distance for imported routes\n"
2318 "Default distance value\n"
2319 "route-map for filtering\n"
2322 uint32_t table_id
= 0;
2323 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2325 if (!is_zebra_valid_kernel_table(table_id
)) {
2327 "Invalid routing table ID. Must be in range 1-252\n");
2331 if (is_zebra_main_routing_table(table_id
)) {
2333 "Invalid routing table ID, %d. Must be non-default table\n",
2338 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2341 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2344 static int config_write_protocol(struct vty
*vty
)
2347 vty_out(vty
, "allow-external-route-update\n");
2349 if (zebra_rnh_ip_default_route
)
2350 vty_out(vty
, "ip nht resolve-via-default\n");
2352 if (zebra_rnh_ipv6_default_route
)
2353 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2355 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2356 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2358 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2359 vty_out(vty
, "zebra zapi-packets %u\n",
2360 zebrad
.packets_to_process
);
2362 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2364 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2365 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2366 ipv4_multicast_mode
== MCAST_URIB_ONLY
2368 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2370 : ipv4_multicast_mode
2371 == MCAST_MIX_MRIB_FIRST
2373 : ipv4_multicast_mode
2374 == MCAST_MIX_DISTANCE
2381 /* Display default rtm_table for all clients. */
2386 "default routing table to use for all clients\n")
2388 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2392 DEFUN (config_table
,
2395 "Configure target kernel routing table\n"
2398 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2402 DEFUN (no_config_table
,
2403 no_config_table_cmd
,
2404 "no table [TABLENO]",
2406 "Configure target kernel routing table\n"
2409 zebrad
.rtm_table_default
= 0;
2423 " Route Route Neighbor LSP LSP\n");
2425 "VRF Installs Removals Updates Installs Removals\n");
2427 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2428 struct zebra_vrf
*zvrf
= vrf
->info
;
2430 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2431 " %10" PRIu64
" %10" PRIu64
"\n",
2432 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2433 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2434 zvrf
->lsp_removals
);
2440 DEFUN (ip_forwarding
,
2444 "Turn on IP forwarding\n")
2450 ret
= ipforward_on();
2453 vty_out(vty
, "Can't turn on IP forwarding\n");
2454 return CMD_WARNING_CONFIG_FAILED
;
2460 DEFUN (no_ip_forwarding
,
2461 no_ip_forwarding_cmd
,
2465 "Turn off IP forwarding\n")
2471 ret
= ipforward_off();
2474 vty_out(vty
, "Can't turn off IP forwarding\n");
2475 return CMD_WARNING_CONFIG_FAILED
;
2481 /* Only display ip forwarding is enabled or not. */
2482 DEFUN (show_ip_forwarding
,
2483 show_ip_forwarding_cmd
,
2484 "show ip forwarding",
2487 "IP forwarding status\n")
2494 vty_out(vty
, "IP forwarding is off\n");
2496 vty_out(vty
, "IP forwarding is on\n");
2500 /* Only display ipv6 forwarding is enabled or not. */
2501 DEFUN (show_ipv6_forwarding
,
2502 show_ipv6_forwarding_cmd
,
2503 "show ipv6 forwarding",
2505 "IPv6 information\n"
2506 "Forwarding status\n")
2510 ret
= ipforward_ipv6();
2514 vty_out(vty
, "ipv6 forwarding is unknown\n");
2517 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2520 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2523 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2529 DEFUN (ipv6_forwarding
,
2530 ipv6_forwarding_cmd
,
2533 "Turn on IPv6 forwarding\n")
2537 ret
= ipforward_ipv6();
2539 ret
= ipforward_ipv6_on();
2542 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2543 return CMD_WARNING_CONFIG_FAILED
;
2549 DEFUN (no_ipv6_forwarding
,
2550 no_ipv6_forwarding_cmd
,
2551 "no ipv6 forwarding",
2554 "Turn off IPv6 forwarding\n")
2558 ret
= ipforward_ipv6();
2560 ret
= ipforward_ipv6_off();
2563 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2564 return CMD_WARNING_CONFIG_FAILED
;
2570 /* Display dataplane info */
2571 DEFUN (show_dataplane
,
2573 "show zebra dplane [detailed]",
2576 "Zebra dataplane information\n"
2577 "Detailed output\n")
2580 bool detailed
= false;
2582 if (argv_find(argv
, argc
, "detailed", &idx
))
2585 return dplane_show_helper(vty
, detailed
);
2588 /* Display dataplane providers info */
2589 DEFUN (show_dataplane_providers
,
2590 show_dataplane_providers_cmd
,
2591 "show zebra dplane providers [detailed]",
2594 "Zebra dataplane information\n"
2595 "Zebra dataplane provider information\n"
2596 "Detailed output\n")
2599 bool detailed
= false;
2601 if (argv_find(argv
, argc
, "detailed", &idx
))
2604 return dplane_show_provs_helper(vty
, detailed
);
2607 /* Configure dataplane incoming queue limit */
2608 DEFUN (zebra_dplane_queue_limit
,
2609 zebra_dplane_queue_limit_cmd
,
2610 "zebra dplane limit (0-10000)",
2613 "Limit incoming queued updates\n"
2614 "Number of queued updates\n")
2618 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2620 dplane_set_in_queue_limit(limit
, true);
2625 /* Reset dataplane queue limit to default value */
2626 DEFUN (no_zebra_dplane_queue_limit
,
2627 no_zebra_dplane_queue_limit_cmd
,
2628 "no zebra dplane limit [(0-10000)]",
2632 "Limit incoming queued updates\n"
2633 "Number of queued updates\n")
2635 dplane_set_in_queue_limit(0, false);
2640 /* Table configuration write function. */
2641 static int config_write_table(struct vty
*vty
)
2643 if (zebrad
.rtm_table_default
)
2644 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2648 /* IPForwarding configuration write function. */
2649 static int config_write_forwarding(struct vty
*vty
)
2651 /* FIXME: Find better place for that. */
2652 router_id_write(vty
);
2655 vty_out(vty
, "no ip forwarding\n");
2656 if (!ipforward_ipv6())
2657 vty_out(vty
, "no ipv6 forwarding\n");
2658 vty_out(vty
, "!\n");
2662 /* IP node for static routes. */
2663 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2664 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2665 /* table node for routing tables. */
2666 static struct cmd_node table_node
= {TABLE_NODE
,
2667 "", /* This node has no interface. */
2669 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2670 "", /* This node has no interface. */
2674 void zebra_vty_init(void)
2676 /* Install configuration write function. */
2677 install_node(&table_node
, config_write_table
);
2678 install_node(&forwarding_node
, config_write_forwarding
);
2680 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2681 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2682 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2683 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2686 install_element(VIEW_NODE
, &show_table_cmd
);
2687 install_element(CONFIG_NODE
, &config_table_cmd
);
2688 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2689 #endif /* HAVE_NETLINK */
2691 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2692 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2693 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2696 zebra_route_map_init();
2698 install_node(&ip_node
, zebra_ip_config
);
2699 install_node(&protocol_node
, config_write_protocol
);
2701 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2702 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2704 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2705 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2707 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2708 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2709 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2710 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2711 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2712 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2714 install_element(VIEW_NODE
, &show_vrf_cmd
);
2715 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2716 install_element(VIEW_NODE
, &show_route_cmd
);
2717 install_element(VIEW_NODE
, &show_route_table_cmd
);
2718 if (vrf_is_backend_netns())
2719 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2720 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2721 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2722 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2723 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2724 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2725 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2727 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2728 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2730 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2731 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2732 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2733 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2734 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2735 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2736 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2737 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2738 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2740 /* Commands for VRF */
2741 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2743 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2744 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2745 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2746 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2747 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2748 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2749 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2750 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2751 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2752 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2753 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2754 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2755 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2756 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2757 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2758 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2759 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2760 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2762 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2763 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2765 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2766 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2767 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2768 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2770 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2771 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2772 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2773 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);