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
,
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 /* VNI range as per RFC 7432 */
72 #define CMD_VNI_RANGE "(1-16777215)"
74 DEFUN (ip_multicast_mode
,
75 ip_multicast_mode_cmd
,
76 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
79 "RPF lookup behavior\n"
80 "Lookup in unicast RIB only\n"
81 "Lookup in multicast RIB only\n"
82 "Try multicast RIB first, fall back to unicast RIB\n"
83 "Lookup both, use entry with lower distance\n"
84 "Lookup both, use entry with longer prefix\n")
86 char *mode
= argv
[3]->text
;
88 if (strmatch(mode
, "urib-only"))
89 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
90 else if (strmatch(mode
, "mrib-only"))
91 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
92 else if (strmatch(mode
, "mrib-then-urib"))
93 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
94 else if (strmatch(mode
, "lower-distance"))
95 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
96 else if (strmatch(mode
, "longer-prefix"))
97 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
99 vty_out(vty
, "Invalid mode specified\n");
100 return CMD_WARNING_CONFIG_FAILED
;
106 DEFUN (no_ip_multicast_mode
,
107 no_ip_multicast_mode_cmd
,
108 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
111 "Multicast options\n"
112 "RPF lookup behavior\n"
113 "Lookup in unicast RIB only\n"
114 "Lookup in multicast RIB only\n"
115 "Try multicast RIB first, fall back to unicast RIB\n"
116 "Lookup both, use entry with lower distance\n"
117 "Lookup both, use entry with longer prefix\n")
119 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
126 "show ip rpf [json]",
129 "Display RPF information for multicast source\n"
132 bool uj
= use_json(argc
, argv
);
133 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
134 false, uj
, 0, NULL
, false, 0, 0);
137 DEFUN (show_ip_rpf_addr
,
138 show_ip_rpf_addr_cmd
,
139 "show ip rpf A.B.C.D",
142 "Display RPF information for multicast source\n"
143 "IP multicast source address (e.g. 10.0.0.0)\n")
147 struct route_node
*rn
;
148 struct route_entry
*re
;
151 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
153 vty_out(vty
, "%% Malformed address\n");
157 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
160 vty_show_ip_route_detail(vty
, rn
, 1);
162 vty_out(vty
, "%% No match for RPF lookup\n");
167 /* New RIB. Detailed information for IPv4 route. */
168 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
171 struct route_entry
*re
;
172 struct nexthop
*nexthop
;
173 char buf
[SRCDEST2STR_BUFFER
];
174 struct zebra_vrf
*zvrf
;
176 RNODE_FOREACH_RE (rn
, re
) {
177 const char *mcast_info
= "";
179 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
180 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
181 ? " using Multicast RIB"
182 : " using Unicast RIB";
185 vty_out(vty
, "Routing entry for %s%s\n",
186 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
187 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
189 vty_out(vty
, "[%d]", re
->instance
);
191 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
194 vty_out(vty
, ", tag %u", re
->tag
);
195 #if defined(SUPPORT_REALMS)
196 if (re
->tag
> 0 && re
->tag
<= 255)
197 vty_out(vty
, "(realm)");
201 vty_out(vty
, ", mtu %u", re
->mtu
);
202 if (re
->vrf_id
!= VRF_DEFAULT
) {
203 zvrf
= vrf_info_lookup(re
->vrf_id
);
204 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
206 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
207 vty_out(vty
, ", best");
214 uptime
-= re
->uptime
;
215 tm
= gmtime(&uptime
);
217 vty_out(vty
, " Last update ");
219 if (uptime
< ONE_DAY_SECOND
)
220 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
222 else if (uptime
< ONE_WEEK_SECOND
)
223 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
226 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
227 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
229 vty_out(vty
, " ago\n");
231 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
234 vty_out(vty
, " %c%s",
235 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
236 ? CHECK_FLAG(nexthop
->flags
,
237 NEXTHOP_FLAG_DUPLICATE
)
241 nexthop
->rparent
? " " : "");
243 switch (nexthop
->type
) {
244 case NEXTHOP_TYPE_IPV4
:
245 case NEXTHOP_TYPE_IPV4_IFINDEX
:
247 inet_ntoa(nexthop
->gate
.ipv4
));
248 if (nexthop
->ifindex
)
249 vty_out(vty
, ", via %s",
254 case NEXTHOP_TYPE_IPV6
:
255 case NEXTHOP_TYPE_IPV6_IFINDEX
:
257 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
259 if (nexthop
->ifindex
)
260 vty_out(vty
, ", via %s",
265 case NEXTHOP_TYPE_IFINDEX
:
266 vty_out(vty
, " directly connected, %s",
267 ifindex2ifname(nexthop
->ifindex
,
270 case NEXTHOP_TYPE_BLACKHOLE
:
271 vty_out(vty
, " unreachable");
272 switch (nexthop
->bh_type
) {
273 case BLACKHOLE_REJECT
:
274 vty_out(vty
, " (ICMP unreachable)");
276 case BLACKHOLE_ADMINPROHIB
:
278 " (ICMP admin-prohibited)");
281 vty_out(vty
, " (blackhole)");
283 case BLACKHOLE_UNSPEC
:
291 if ((re
->vrf_id
!= nexthop
->vrf_id
)
292 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
294 vrf_lookup_by_id(nexthop
->vrf_id
);
297 vty_out(vty
, "(vrf %s)", vrf
->name
);
299 vty_out(vty
, "(vrf UNKNOWN)");
302 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
303 vty_out(vty
, " (duplicate nexthop removed)");
305 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
306 vty_out(vty
, " inactive");
308 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
309 vty_out(vty
, " onlink");
311 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
312 vty_out(vty
, " (recursive)");
314 switch (nexthop
->type
) {
315 case NEXTHOP_TYPE_IPV4
:
316 case NEXTHOP_TYPE_IPV4_IFINDEX
:
317 if (nexthop
->src
.ipv4
.s_addr
) {
318 if (inet_ntop(AF_INET
,
320 addrstr
, sizeof addrstr
))
321 vty_out(vty
, ", src %s",
325 case NEXTHOP_TYPE_IPV6
:
326 case NEXTHOP_TYPE_IPV6_IFINDEX
:
327 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
329 if (inet_ntop(AF_INET6
,
331 addrstr
, sizeof addrstr
))
332 vty_out(vty
, ", src %s",
341 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
343 /* Label information */
344 if (nexthop
->nh_label
345 && nexthop
->nh_label
->num_labels
) {
346 vty_out(vty
, ", label %s",
348 nexthop
->nh_label
->num_labels
,
349 nexthop
->nh_label
->label
, buf
,
359 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
360 struct route_entry
*re
, json_object
*json
)
362 struct nexthop
*nexthop
;
364 char buf
[SRCDEST2STR_BUFFER
];
365 json_object
*json_nexthops
= NULL
;
366 json_object
*json_nexthop
= NULL
;
367 json_object
*json_route
= NULL
;
368 json_object
*json_labels
= NULL
;
373 uptime
-= re
->uptime
;
374 tm
= gmtime(&uptime
);
377 json_route
= json_object_new_object();
378 json_nexthops
= json_object_new_array();
380 json_object_string_add(json_route
, "prefix",
381 srcdest_rnode2str(rn
, buf
, sizeof buf
));
382 json_object_string_add(json_route
, "protocol",
383 zebra_route_string(re
->type
));
386 json_object_int_add(json_route
, "instance",
390 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
392 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
393 json_object_boolean_true_add(json_route
, "selected");
395 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
396 json_object_int_add(json_route
, "distance",
398 json_object_int_add(json_route
, "metric", re
->metric
);
402 json_object_int_add(json_route
, "tag", re
->tag
);
404 json_object_int_add(json_route
, "internalStatus",
406 json_object_int_add(json_route
, "internalFlags",
408 if (uptime
< ONE_DAY_SECOND
)
409 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
411 else if (uptime
< ONE_WEEK_SECOND
)
412 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
415 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
416 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
419 json_object_string_add(json_route
, "uptime", buf
);
421 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
422 json_nexthop
= json_object_new_object();
424 json_object_int_add(json_nexthop
, "flags",
427 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
428 json_object_boolean_true_add(json_nexthop
,
431 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
432 json_object_boolean_true_add(json_nexthop
,
435 switch (nexthop
->type
) {
436 case NEXTHOP_TYPE_IPV4
:
437 case NEXTHOP_TYPE_IPV4_IFINDEX
:
438 json_object_string_add(
440 inet_ntoa(nexthop
->gate
.ipv4
));
441 json_object_string_add(json_nexthop
, "afi",
444 if (nexthop
->ifindex
) {
445 json_object_int_add(json_nexthop
,
448 json_object_string_add(
449 json_nexthop
, "interfaceName",
455 case NEXTHOP_TYPE_IPV6
:
456 case NEXTHOP_TYPE_IPV6_IFINDEX
:
457 json_object_string_add(
459 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
461 json_object_string_add(json_nexthop
, "afi",
464 if (nexthop
->ifindex
) {
465 json_object_int_add(json_nexthop
,
468 json_object_string_add(
469 json_nexthop
, "interfaceName",
476 case NEXTHOP_TYPE_IFINDEX
:
477 json_object_boolean_true_add(
478 json_nexthop
, "directlyConnected");
479 json_object_int_add(json_nexthop
,
482 json_object_string_add(
483 json_nexthop
, "interfaceName",
484 ifindex2ifname(nexthop
->ifindex
,
487 case NEXTHOP_TYPE_BLACKHOLE
:
488 json_object_boolean_true_add(json_nexthop
,
490 switch (nexthop
->bh_type
) {
491 case BLACKHOLE_REJECT
:
492 json_object_boolean_true_add(
493 json_nexthop
, "reject");
495 case BLACKHOLE_ADMINPROHIB
:
496 json_object_boolean_true_add(
501 json_object_boolean_true_add(
502 json_nexthop
, "blackhole");
504 case BLACKHOLE_UNSPEC
:
512 if ((nexthop
->vrf_id
!= re
->vrf_id
)
513 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
515 vrf_lookup_by_id(nexthop
->vrf_id
);
517 json_object_string_add(json_nexthop
, "vrf",
520 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
521 json_object_boolean_true_add(json_nexthop
,
524 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
525 json_object_boolean_true_add(json_nexthop
,
528 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
529 json_object_boolean_true_add(json_nexthop
,
532 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
533 json_object_boolean_true_add(json_nexthop
,
536 switch (nexthop
->type
) {
537 case NEXTHOP_TYPE_IPV4
:
538 case NEXTHOP_TYPE_IPV4_IFINDEX
:
539 if (nexthop
->src
.ipv4
.s_addr
) {
540 if (inet_ntop(AF_INET
,
541 &nexthop
->src
.ipv4
, buf
,
543 json_object_string_add(
544 json_nexthop
, "source",
548 case NEXTHOP_TYPE_IPV6
:
549 case NEXTHOP_TYPE_IPV6_IFINDEX
:
550 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
552 if (inet_ntop(AF_INET6
,
553 &nexthop
->src
.ipv6
, buf
,
555 json_object_string_add(
556 json_nexthop
, "source",
564 if (nexthop
->nh_label
565 && nexthop
->nh_label
->num_labels
) {
566 json_labels
= json_object_new_array();
568 for (int label_index
= 0;
570 < nexthop
->nh_label
->num_labels
;
572 json_object_array_add(
575 nexthop
->nh_label
->label
578 json_object_object_add(json_nexthop
, "labels",
582 json_object_array_add(json_nexthops
, json_nexthop
);
585 json_object_object_add(json_route
, "nexthops", json_nexthops
);
586 json_object_array_add(json
, json_route
);
590 /* Nexthop information. */
591 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
592 if (nexthop
== re
->ng
.nexthop
) {
593 /* Prefix information. */
594 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
596 len
+= vty_out(vty
, "[%d]", re
->instance
);
599 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
602 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
605 srcdest_rnode2str(rn
, buf
, sizeof buf
));
607 /* Distance and metric display. */
608 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
609 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
612 vty_out(vty
, " %c%*c",
613 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
614 ? CHECK_FLAG(nexthop
->flags
,
615 NEXTHOP_FLAG_DUPLICATE
)
619 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
622 switch (nexthop
->type
) {
623 case NEXTHOP_TYPE_IPV4
:
624 case NEXTHOP_TYPE_IPV4_IFINDEX
:
625 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
626 if (nexthop
->ifindex
)
628 ifindex2ifname(nexthop
->ifindex
,
631 case NEXTHOP_TYPE_IPV6
:
632 case NEXTHOP_TYPE_IPV6_IFINDEX
:
633 vty_out(vty
, " via %s",
634 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
636 if (nexthop
->ifindex
)
638 ifindex2ifname(nexthop
->ifindex
,
642 case NEXTHOP_TYPE_IFINDEX
:
643 vty_out(vty
, " is directly connected, %s",
644 ifindex2ifname(nexthop
->ifindex
,
647 case NEXTHOP_TYPE_BLACKHOLE
:
648 vty_out(vty
, " unreachable");
649 switch (nexthop
->bh_type
) {
650 case BLACKHOLE_REJECT
:
651 vty_out(vty
, " (ICMP unreachable)");
653 case BLACKHOLE_ADMINPROHIB
:
654 vty_out(vty
, " (ICMP admin-prohibited)");
657 vty_out(vty
, " (blackhole)");
659 case BLACKHOLE_UNSPEC
:
667 if ((nexthop
->vrf_id
!= re
->vrf_id
)
668 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
669 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
672 vty_out(vty
, "(vrf %s)", vrf
->name
);
674 vty_out(vty
, "(vrf UNKNOWN)");
677 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
678 vty_out(vty
, " inactive");
680 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
681 vty_out(vty
, " onlink");
683 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
684 vty_out(vty
, " (recursive)");
686 switch (nexthop
->type
) {
687 case NEXTHOP_TYPE_IPV4
:
688 case NEXTHOP_TYPE_IPV4_IFINDEX
:
689 if (nexthop
->src
.ipv4
.s_addr
) {
690 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
692 vty_out(vty
, ", src %s", buf
);
695 case NEXTHOP_TYPE_IPV6
:
696 case NEXTHOP_TYPE_IPV6_IFINDEX
:
697 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
698 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
700 vty_out(vty
, ", src %s", buf
);
707 /* Label information */
708 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
709 vty_out(vty
, ", label %s",
710 mpls_label2str(nexthop
->nh_label
->num_labels
,
711 nexthop
->nh_label
->label
, buf
,
715 if (uptime
< ONE_DAY_SECOND
)
716 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
717 tm
->tm_min
, tm
->tm_sec
);
718 else if (uptime
< ONE_WEEK_SECOND
)
719 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
720 tm
->tm_hour
, tm
->tm_min
);
722 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
723 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
729 static void vty_show_ip_route_detail_json(struct vty
*vty
,
730 struct route_node
*rn
)
732 json_object
*json
= NULL
;
733 json_object
*json_prefix
= NULL
;
734 struct route_entry
*re
;
737 json
= json_object_new_object();
739 RNODE_FOREACH_RE (rn
, re
) {
740 json_prefix
= json_object_new_array();
741 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
742 prefix2str(&rn
->p
, buf
, sizeof buf
);
743 json_object_object_add(json
, buf
, json_prefix
);
747 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
748 json
, JSON_C_TO_STRING_PRETTY
));
749 json_object_free(json
);
752 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
753 struct route_table
*table
, afi_t afi
,
754 bool use_fib
, route_tag_t tag
,
755 const struct prefix
*longer_prefix_p
,
756 bool supernets_only
, int type
,
757 unsigned short ospf_instance_id
, bool use_json
)
759 struct route_node
*rn
;
760 struct route_entry
*re
;
763 json_object
*json
= NULL
;
764 json_object
*json_prefix
= NULL
;
769 json
= json_object_new_object();
771 /* Show all routes. */
772 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
773 dest
= rib_dest_from_rnode(rn
);
775 RNODE_FOREACH_RE (rn
, re
) {
776 if (use_fib
&& re
!= dest
->selected_fib
)
779 if (tag
&& re
->tag
!= tag
)
783 && !prefix_match(longer_prefix_p
, &rn
->p
))
786 /* This can only be true when the afi is IPv4 */
787 if (supernets_only
) {
788 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
790 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
793 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
796 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
800 if (type
&& re
->type
!= type
)
804 && (re
->type
!= ZEBRA_ROUTE_OSPF
805 || re
->instance
!= ospf_instance_id
))
810 json_prefix
= json_object_new_array();
815 SHOW_ROUTE_V4_HEADER
);
818 SHOW_ROUTE_V6_HEADER
);
820 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
821 vty_out(vty
, "\nVRF %s:\n",
828 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
832 prefix2str(&rn
->p
, buf
, sizeof(buf
));
833 json_object_object_add(json
, buf
, json_prefix
);
839 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
840 JSON_C_TO_STRING_PRETTY
));
841 json_object_free(json
);
845 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
846 safi_t safi
, bool use_fib
, bool use_json
,
848 const struct prefix
*longer_prefix_p
,
849 bool supernets_only
, int type
,
850 unsigned short ospf_instance_id
)
852 struct route_table
*table
;
853 struct zebra_vrf
*zvrf
= NULL
;
855 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
857 vty_out(vty
, "{}\n");
859 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
863 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
865 vty_out(vty
, "{}\n");
867 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
871 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
874 vty_out(vty
, "{}\n");
878 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
879 longer_prefix_p
, supernets_only
, type
,
880 ospf_instance_id
, use_json
);
885 DEFPY (show_route_table
,
886 show_route_table_cmd
,
887 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
893 "The table number to display, if available\n"
896 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
897 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
898 struct route_table
*t
;
900 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
902 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
908 DEFPY (show_route_table_vrf
,
909 show_route_table_vrf_cmd
,
910 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
916 "The table number to display, if available\n"
920 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
921 struct zebra_vrf
*zvrf
;
922 struct route_table
*t
;
923 vrf_id_t vrf_id
= VRF_DEFAULT
;
926 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
927 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
929 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
931 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
939 "show ip nht [vrf NAME]",
942 "IP nexthop tracking table\n"
946 vrf_id_t vrf_id
= VRF_DEFAULT
;
949 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
951 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
956 DEFUN (show_ip_nht_vrf_all
,
957 show_ip_nht_vrf_all_cmd
,
958 "show ip nht vrf all",
961 "IP nexthop tracking table\n"
962 VRF_ALL_CMD_HELP_STR
)
965 struct zebra_vrf
*zvrf
;
967 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
968 if ((zvrf
= vrf
->info
) != NULL
) {
969 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
970 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
977 DEFUN (show_ipv6_nht
,
979 "show ipv6 nht [vrf NAME]",
982 "IPv6 nexthop tracking table\n"
986 vrf_id_t vrf_id
= VRF_DEFAULT
;
989 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
991 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
996 DEFUN (show_ipv6_nht_vrf_all
,
997 show_ipv6_nht_vrf_all_cmd
,
998 "show ipv6 nht vrf all",
1001 "IPv6 nexthop tracking table\n"
1002 VRF_ALL_CMD_HELP_STR
)
1005 struct zebra_vrf
*zvrf
;
1007 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1008 if ((zvrf
= vrf
->info
) != NULL
) {
1009 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1010 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1017 DEFUN (ip_nht_default_route
,
1018 ip_nht_default_route_cmd
,
1019 "ip nht resolve-via-default",
1021 "Filter Next Hop tracking route resolution\n"
1022 "Resolve via default route\n")
1024 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1029 if (zebra_rnh_ip_default_route
)
1032 zebra_rnh_ip_default_route
= 1;
1034 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1038 DEFUN (no_ip_nht_default_route
,
1039 no_ip_nht_default_route_cmd
,
1040 "no ip nht resolve-via-default",
1043 "Filter Next Hop tracking route resolution\n"
1044 "Resolve via default route\n")
1046 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1051 if (!zebra_rnh_ip_default_route
)
1054 zebra_rnh_ip_default_route
= 0;
1055 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1059 DEFUN (ipv6_nht_default_route
,
1060 ipv6_nht_default_route_cmd
,
1061 "ipv6 nht resolve-via-default",
1063 "Filter Next Hop tracking route resolution\n"
1064 "Resolve via default route\n")
1066 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1071 if (zebra_rnh_ipv6_default_route
)
1074 zebra_rnh_ipv6_default_route
= 1;
1075 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1079 DEFUN (no_ipv6_nht_default_route
,
1080 no_ipv6_nht_default_route_cmd
,
1081 "no ipv6 nht resolve-via-default",
1084 "Filter Next Hop tracking route resolution\n"
1085 "Resolve via default route\n")
1088 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1093 if (!zebra_rnh_ipv6_default_route
)
1096 zebra_rnh_ipv6_default_route
= 0;
1097 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1105 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1108 |A.B.C.D/M$prefix longer-prefixes\
1109 |supernets-only$supernets_only\
1112 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1113 |ospf$type_str (1-65535)$ospf_instance_id\
1115 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1118 |X:X::X:X/M$prefix longer-prefixes\
1120 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1125 "IP forwarding table\n"
1126 "IP routing table\n"
1127 VRF_FULL_CMD_HELP_STR
1128 "Show only routes with tag\n"
1130 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1131 "Show route matching the specified Network/Mask pair only\n"
1132 "Show supernet entries only\n"
1133 FRR_IP_REDIST_HELP_STR_ZEBRA
1134 "Open Shortest Path First (OSPFv2)\n"
1137 "IP forwarding table\n"
1138 "IP routing table\n"
1139 VRF_FULL_CMD_HELP_STR
1140 "Show only routes with tag\n"
1143 "Show route matching the specified Network/Mask pair only\n"
1144 FRR_IP6_REDIST_HELP_STR_ZEBRA
1147 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1152 type
= proto_redistnum(afi
, type_str
);
1154 vty_out(vty
, "Unknown route type\n");
1160 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1161 struct zebra_vrf
*zvrf
;
1162 struct route_table
*table
;
1164 if ((zvrf
= vrf
->info
) == NULL
1165 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1169 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1170 !!json
, tag
, prefix_str
? prefix
: NULL
,
1171 !!supernets_only
, type
, ospf_instance_id
);
1174 vrf_id_t vrf_id
= VRF_DEFAULT
;
1177 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1178 vrf
= vrf_lookup_by_id(vrf_id
);
1179 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1180 !!json
, tag
, prefix_str
? prefix
: NULL
,
1181 !!supernets_only
, type
, ospf_instance_id
);
1187 DEFPY (show_route_detail
,
1188 show_route_detail_cmd
,
1191 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1196 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1205 "IP routing table\n"
1206 VRF_FULL_CMD_HELP_STR
1207 "Network in the IP routing table to display\n"
1208 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1210 "IP routing table\n"
1211 VRF_FULL_CMD_HELP_STR
1216 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1217 struct route_table
*table
;
1219 struct route_node
*rn
;
1222 prefix_str
= address_str
;
1223 if (str2prefix(prefix_str
, &p
) < 0) {
1224 vty_out(vty
, "%% Malformed address\n");
1230 struct zebra_vrf
*zvrf
;
1232 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1233 if ((zvrf
= vrf
->info
) == NULL
1234 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1237 rn
= route_node_match(table
, &p
);
1240 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1241 route_unlock_node(rn
);
1246 vty_show_ip_route_detail_json(vty
, rn
);
1248 vty_show_ip_route_detail(vty
, rn
, 0);
1250 route_unlock_node(rn
);
1253 vrf_id_t vrf_id
= VRF_DEFAULT
;
1256 VRF_GET_ID(vrf_id
, vrf_name
, false);
1258 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1262 rn
= route_node_match(table
, &p
);
1264 vty_out(vty
, "%% Network not in table\n");
1267 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1268 vty_out(vty
, "%% Network not in table\n");
1269 route_unlock_node(rn
);
1274 vty_show_ip_route_detail_json(vty
, rn
);
1276 vty_show_ip_route_detail(vty
, rn
, 0);
1278 route_unlock_node(rn
);
1284 DEFPY (show_route_summary
,
1285 show_route_summary_cmd
,
1288 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1289 summary [prefix$prefix]\
1290 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1291 summary [prefix$prefix]\
1295 "IP routing table\n"
1296 VRF_FULL_CMD_HELP_STR
1297 "Summary of all routes\n"
1300 "IP routing table\n"
1301 VRF_FULL_CMD_HELP_STR
1302 "Summary of all routes\n"
1305 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1306 struct route_table
*table
;
1310 struct zebra_vrf
*zvrf
;
1312 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1313 if ((zvrf
= vrf
->info
) == NULL
1314 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1318 vty_show_ip_route_summary_prefix(vty
, table
);
1320 vty_show_ip_route_summary(vty
, table
);
1323 vrf_id_t vrf_id
= VRF_DEFAULT
;
1326 VRF_GET_ID(vrf_id
, vrf_name
, false);
1328 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1333 vty_show_ip_route_summary_prefix(vty
, table
);
1335 vty_show_ip_route_summary(vty
, table
);
1341 static void vty_show_ip_route_summary(struct vty
*vty
,
1342 struct route_table
*table
)
1344 struct route_node
*rn
;
1345 struct route_entry
*re
;
1346 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1347 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1348 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1349 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1353 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1354 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1355 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1356 RNODE_FOREACH_RE (rn
, re
) {
1357 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1358 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1360 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1362 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1364 rib_cnt
[re
->type
]++;
1366 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1367 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1370 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1372 fib_cnt
[re
->type
]++;
1376 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1377 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1379 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1380 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1381 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1382 if (i
== ZEBRA_ROUTE_BGP
) {
1383 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1384 rib_cnt
[ZEBRA_ROUTE_BGP
],
1385 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1386 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1387 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1388 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1390 vty_out(vty
, "%-20s %-20d %-20d \n",
1391 zebra_route_string(i
), rib_cnt
[i
],
1396 vty_out(vty
, "------\n");
1397 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1398 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1403 * Implementation of the ip route summary prefix command.
1405 * This command prints the primary prefixes that have been installed by various
1406 * protocols on the box.
1409 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1410 struct route_table
*table
)
1412 struct route_node
*rn
;
1413 struct route_entry
*re
;
1414 struct nexthop
*nexthop
;
1415 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1416 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1417 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1418 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1422 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1423 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1424 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1425 RNODE_FOREACH_RE (rn
, re
) {
1428 * In case of ECMP, count only once.
1431 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1432 nexthop
= nexthop
->next
) {
1434 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1435 rib_cnt
[re
->type
]++;
1436 if (CHECK_FLAG(nexthop
->flags
,
1437 NEXTHOP_FLAG_FIB
)) {
1438 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1439 fib_cnt
[re
->type
]++;
1441 if (re
->type
== ZEBRA_ROUTE_BGP
1442 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1443 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1444 if (CHECK_FLAG(nexthop
->flags
,
1446 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1451 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1452 "Prefix Routes", "FIB",
1453 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1455 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1456 if (rib_cnt
[i
] > 0) {
1457 if (i
== ZEBRA_ROUTE_BGP
) {
1458 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1459 rib_cnt
[ZEBRA_ROUTE_BGP
]
1460 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1461 fib_cnt
[ZEBRA_ROUTE_BGP
]
1462 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1463 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1464 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1465 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1467 vty_out(vty
, "%-20s %-20d %-20d \n",
1468 zebra_route_string(i
), rib_cnt
[i
],
1473 vty_out(vty
, "------\n");
1474 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1475 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1480 * Show IPv6 mroute command.Used to dump
1481 * the Multicast routing table.
1483 DEFUN (show_ipv6_mroute
,
1484 show_ipv6_mroute_cmd
,
1485 "show ipv6 mroute [vrf NAME]",
1488 "IPv6 Multicast routing table\n"
1491 struct route_table
*table
;
1492 struct route_node
*rn
;
1493 struct route_entry
*re
;
1495 vrf_id_t vrf_id
= VRF_DEFAULT
;
1498 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1500 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1504 /* Show all IPv6 route. */
1505 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1506 RNODE_FOREACH_RE (rn
, re
) {
1508 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1511 vty_show_ip_route(vty
, rn
, re
, NULL
);
1516 DEFUN (show_ipv6_mroute_vrf_all
,
1517 show_ipv6_mroute_vrf_all_cmd
,
1518 "show ipv6 mroute vrf all",
1521 "IPv6 Multicast routing table\n"
1522 VRF_ALL_CMD_HELP_STR
)
1524 struct route_table
*table
;
1525 struct route_node
*rn
;
1526 struct route_entry
*re
;
1528 struct zebra_vrf
*zvrf
;
1531 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1532 if ((zvrf
= vrf
->info
) == NULL
1533 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1536 /* Show all IPv6 route. */
1537 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1538 RNODE_FOREACH_RE (rn
, re
) {
1540 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1543 vty_show_ip_route(vty
, rn
, re
, NULL
);
1549 DEFUN (allow_external_route_update
,
1550 allow_external_route_update_cmd
,
1551 "allow-external-route-update",
1552 "Allow FRR routes to be overwritten by external processes\n")
1559 DEFUN (no_allow_external_route_update
,
1560 no_allow_external_route_update_cmd
,
1561 "no allow-external-route-update",
1563 "Allow FRR routes to be overwritten by external processes\n")
1578 struct zebra_vrf
*zvrf
;
1580 if (vrf_is_backend_netns())
1581 vty_out(vty
, "netns-based vrfs\n");
1583 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1584 if (!(zvrf
= vrf
->info
))
1586 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1589 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1590 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1591 vty_out(vty
, "inactive");
1592 else if (zvrf_ns_name(zvrf
))
1593 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1594 zvrf_ns_name(zvrf
));
1596 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1598 if (vrf_is_user_cfged(vrf
))
1599 vty_out(vty
, " (configured)");
1606 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1607 default_vrf_vni_mapping_cmd
,
1608 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1609 "VNI corresponding to the DEFAULT VRF\n"
1611 "Prefix routes only \n")
1614 char err
[ERR_STR_SZ
];
1615 struct zebra_vrf
*zvrf
= NULL
;
1616 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1619 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1626 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1629 vty_out(vty
, "%s\n", err
);
1636 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1637 no_default_vrf_vni_mapping_cmd
,
1638 "no vni " CMD_VNI_RANGE
,
1640 "VNI corresponding to DEFAULT VRF\n"
1644 char err
[ERR_STR_SZ
];
1645 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1646 struct zebra_vrf
*zvrf
= NULL
;
1648 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1652 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1654 vty_out(vty
, "%s\n", err
);
1661 DEFUN (vrf_vni_mapping
,
1662 vrf_vni_mapping_cmd
,
1663 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1664 "VNI corresponding to tenant VRF\n"
1666 "prefix-routes-only\n")
1671 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1672 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1673 char err
[ERR_STR_SZ
];
1681 /* Mark as having FRR configuration */
1682 vrf_set_user_cfged(vrf
);
1683 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1686 vty_out(vty
, "%s\n", err
);
1693 DEFUN (no_vrf_vni_mapping
,
1694 no_vrf_vni_mapping_cmd
,
1695 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1697 "VNI corresponding to tenant VRF\n"
1699 "prefix-routes-only\n")
1703 char err
[ERR_STR_SZ
];
1704 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1706 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1714 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1715 ERR_STR_SZ
, filter
, 0);
1717 vty_out(vty
, "%s\n", err
);
1721 /* If no other FRR config for this VRF, mark accordingly. */
1722 if (!zebra_vrf_has_config(zvrf
))
1723 vrf_reset_user_cfged(vrf
);
1729 DEFUN (show_vrf_vni
,
1731 "show vrf vni [json]",
1738 struct zebra_vrf
*zvrf
;
1739 json_object
*json
= NULL
;
1740 json_object
*json_vrfs
= NULL
;
1741 bool uj
= use_json(argc
, argv
);
1744 json
= json_object_new_object();
1745 json_vrfs
= json_object_new_array();
1749 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1750 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1752 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1757 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1761 json_object_object_add(json
, "vrfs", json_vrfs
);
1762 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1763 json
, JSON_C_TO_STRING_PRETTY
));
1764 json_object_free(json
);
1770 DEFUN (show_evpn_global
,
1771 show_evpn_global_cmd
,
1777 bool uj
= use_json(argc
, argv
);
1779 zebra_vxlan_print_evpn(vty
, uj
);
1783 DEFUN (show_evpn_vni
,
1785 "show evpn vni [json]",
1788 "VxLAN information\n"
1791 struct zebra_vrf
*zvrf
;
1792 bool uj
= use_json(argc
, argv
);
1794 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1795 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1799 DEFUN (show_evpn_vni_vni
,
1800 show_evpn_vni_vni_cmd
,
1801 "show evpn vni " CMD_VNI_RANGE
"[json]",
1804 "VxLAN Network Identifier\n"
1808 struct zebra_vrf
*zvrf
;
1810 bool uj
= use_json(argc
, argv
);
1812 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1813 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1814 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1818 DEFUN (show_evpn_rmac_vni_mac
,
1819 show_evpn_rmac_vni_mac_cmd
,
1820 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1827 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1832 bool uj
= use_json(argc
, argv
);
1834 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1835 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1836 vty_out(vty
, "%% Malformed MAC address\n");
1839 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1843 DEFUN (show_evpn_rmac_vni
,
1844 show_evpn_rmac_vni_cmd
,
1845 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1854 bool uj
= use_json(argc
, argv
);
1856 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1857 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1862 DEFUN (show_evpn_rmac_vni_all
,
1863 show_evpn_rmac_vni_all_cmd
,
1864 "show evpn rmac vni all [json]",
1872 bool uj
= use_json(argc
, argv
);
1874 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1879 DEFUN (show_evpn_nh_vni_ip
,
1880 show_evpn_nh_vni_ip_cmd
,
1881 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1888 "Host address (ipv4 or ipv6)\n"
1893 bool uj
= use_json(argc
, argv
);
1895 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1896 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1898 vty_out(vty
, "%% Malformed Neighbor address\n");
1901 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1906 DEFUN (show_evpn_nh_vni
,
1907 show_evpn_nh_vni_cmd
,
1908 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1917 bool uj
= use_json(argc
, argv
);
1919 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1920 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1925 DEFUN (show_evpn_nh_vni_all
,
1926 show_evpn_nh_vni_all_cmd
,
1927 "show evpn next-hops vni all [json]",
1935 bool uj
= use_json(argc
, argv
);
1937 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1942 DEFUN (show_evpn_mac_vni
,
1943 show_evpn_mac_vni_cmd
,
1944 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1948 "VxLAN Network Identifier\n"
1952 struct zebra_vrf
*zvrf
;
1954 bool uj
= use_json(argc
, argv
);
1956 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1957 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1958 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1962 DEFUN (show_evpn_mac_vni_all
,
1963 show_evpn_mac_vni_all_cmd
,
1964 "show evpn mac vni all [json]",
1968 "VxLAN Network Identifier\n"
1972 struct zebra_vrf
*zvrf
;
1973 bool uj
= use_json(argc
, argv
);
1975 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1976 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
1980 DEFUN (show_evpn_mac_vni_all_vtep
,
1981 show_evpn_mac_vni_all_vtep_cmd
,
1982 "show evpn mac vni all vtep A.B.C.D [json]",
1986 "VxLAN Network Identifier\n"
1989 "Remote VTEP IP address\n"
1992 struct zebra_vrf
*zvrf
;
1993 struct in_addr vtep_ip
;
1994 bool uj
= use_json(argc
, argv
);
1996 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
1998 vty_out(vty
, "%% Malformed VTEP IP address\n");
2001 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2002 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2008 DEFUN (show_evpn_mac_vni_mac
,
2009 show_evpn_mac_vni_mac_cmd
,
2010 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2014 "VxLAN Network Identifier\n"
2017 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2019 struct zebra_vrf
*zvrf
;
2023 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2024 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2025 vty_out(vty
, "%% Malformed MAC address");
2028 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2029 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2033 DEFUN (show_evpn_mac_vni_vtep
,
2034 show_evpn_mac_vni_vtep_cmd
,
2035 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2039 "VxLAN Network Identifier\n"
2042 "Remote VTEP IP address\n"
2045 struct zebra_vrf
*zvrf
;
2047 struct in_addr vtep_ip
;
2048 bool uj
= use_json(argc
, argv
);
2050 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2051 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2053 vty_out(vty
, "%% Malformed VTEP IP address\n");
2057 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2058 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2062 DEFUN (show_evpn_neigh_vni
,
2063 show_evpn_neigh_vni_cmd
,
2064 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2067 "ARP and ND cache\n"
2068 "VxLAN Network Identifier\n"
2072 struct zebra_vrf
*zvrf
;
2074 bool uj
= use_json(argc
, argv
);
2076 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2077 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2078 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2082 DEFUN (show_evpn_neigh_vni_all
,
2083 show_evpn_neigh_vni_all_cmd
,
2084 "show evpn arp-cache vni all [json]",
2087 "ARP and ND cache\n"
2088 "VxLAN Network Identifier\n"
2092 struct zebra_vrf
*zvrf
;
2093 bool uj
= use_json(argc
, argv
);
2095 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2096 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2100 DEFUN (show_evpn_neigh_vni_neigh
,
2101 show_evpn_neigh_vni_neigh_cmd
,
2102 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2105 "ARP and ND cache\n"
2106 "VxLAN Network Identifier\n"
2109 "Neighbor address (IPv4 or IPv6 address)\n"
2112 struct zebra_vrf
*zvrf
;
2115 bool uj
= use_json(argc
, argv
);
2117 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2118 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2120 vty_out(vty
, "%% Malformed Neighbor address\n");
2123 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2124 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2128 DEFUN (show_evpn_neigh_vni_vtep
,
2129 show_evpn_neigh_vni_vtep_cmd
,
2130 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2133 "ARP and ND cache\n"
2134 "VxLAN Network Identifier\n"
2137 "Remote VTEP IP address\n"
2140 struct zebra_vrf
*zvrf
;
2142 struct in_addr vtep_ip
;
2143 bool uj
= use_json(argc
, argv
);
2145 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2146 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2148 vty_out(vty
, "%% Malformed VTEP IP address\n");
2152 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2153 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2157 /* policy routing contexts */
2158 DEFUN (show_pbr_ipset
,
2160 "show pbr ipset [WORD]",
2162 "Policy-Based Routing\n"
2163 "IPset Context information\n"
2164 "IPset Name information\n")
2168 found
= argv_find(argv
, argc
, "WORD", &idx
);
2170 zebra_pbr_show_ipset_list(vty
, NULL
);
2172 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2176 /* policy routing contexts */
2177 DEFUN (show_pbr_iptable
,
2178 show_pbr_iptable_cmd
,
2179 "show pbr iptable [WORD]",
2181 "Policy-Based Routing\n"
2182 "IPtable Context information\n"
2183 "IPtable Name information\n")
2188 found
= argv_find(argv
, argc
, "WORD", &idx
);
2190 zebra_pbr_show_iptable(vty
, NULL
);
2192 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2196 /* Static ip route configuration write function. */
2197 static int zebra_ip_config(struct vty
*vty
)
2201 write
+= zebra_import_table_config(vty
);
2206 DEFUN (ip_zebra_import_table_distance
,
2207 ip_zebra_import_table_distance_cmd
,
2208 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2210 "import routes from non-main kernel table\n"
2211 "kernel routing table id\n"
2212 "Distance for imported routes\n"
2213 "Default distance value\n"
2214 "route-map for filtering\n"
2217 uint32_t table_id
= 0;
2219 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2220 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2222 strmatch(argv
[argc
- 2]->text
, "route-map")
2223 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2227 if (argc
== 7 || (argc
== 5 && !rmap
))
2228 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2230 if (!is_zebra_valid_kernel_table(table_id
)) {
2232 "Invalid routing table ID, %d. Must be in range 1-252\n",
2235 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2239 if (is_zebra_main_routing_table(table_id
)) {
2241 "Invalid routing table ID, %d. Must be non-default table\n",
2244 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2248 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2250 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2255 DEFUN_HIDDEN (zebra_packet_process
,
2256 zebra_packet_process_cmd
,
2257 "zebra zapi-packets (1-10000)",
2260 "Number of packets to process before relinquishing thread\n")
2262 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2264 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2265 memory_order_relaxed
);
2270 DEFUN_HIDDEN (no_zebra_packet_process
,
2271 no_zebra_packet_process_cmd
,
2272 "no zebra zapi-packets [(1-10000)]",
2276 "Number of packets to process before relinquishing thread\n")
2278 atomic_store_explicit(&zebrad
.packets_to_process
,
2279 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2280 memory_order_relaxed
);
2285 DEFUN_HIDDEN (zebra_workqueue_timer
,
2286 zebra_workqueue_timer_cmd
,
2287 "zebra work-queue (0-10000)",
2290 "Time in milliseconds\n")
2292 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2293 zebrad
.ribq
->spec
.hold
= timer
;
2298 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2299 no_zebra_workqueue_timer_cmd
,
2300 "no zebra work-queue [(0-10000)]",
2304 "Time in milliseconds\n")
2306 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2311 DEFUN (no_ip_zebra_import_table
,
2312 no_ip_zebra_import_table_cmd
,
2313 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2316 "import routes from non-main kernel table\n"
2317 "kernel routing table id\n"
2318 "Distance for imported routes\n"
2319 "Default distance value\n"
2320 "route-map for filtering\n"
2323 uint32_t table_id
= 0;
2324 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2326 if (!is_zebra_valid_kernel_table(table_id
)) {
2328 "Invalid routing table ID. Must be in range 1-252\n");
2332 if (is_zebra_main_routing_table(table_id
)) {
2334 "Invalid routing table ID, %d. Must be non-default table\n",
2339 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2342 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2345 static int config_write_protocol(struct vty
*vty
)
2348 vty_out(vty
, "allow-external-route-update\n");
2350 if (zebra_rnh_ip_default_route
)
2351 vty_out(vty
, "ip nht resolve-via-default\n");
2353 if (zebra_rnh_ipv6_default_route
)
2354 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2356 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2357 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2359 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2360 vty_out(vty
, "zebra zapi-packets %u\n",
2361 zebrad
.packets_to_process
);
2363 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2365 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2366 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2367 ipv4_multicast_mode
== MCAST_URIB_ONLY
2369 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2371 : ipv4_multicast_mode
2372 == MCAST_MIX_MRIB_FIRST
2374 : ipv4_multicast_mode
2375 == MCAST_MIX_DISTANCE
2382 /* Display default rtm_table for all clients. */
2387 "default routing table to use for all clients\n")
2389 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2393 DEFUN (config_table
,
2396 "Configure target kernel routing table\n"
2399 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2403 DEFUN (no_config_table
,
2404 no_config_table_cmd
,
2405 "no table [TABLENO]",
2407 "Configure target kernel routing table\n"
2410 zebrad
.rtm_table_default
= 0;
2424 " Route Route Neighbor LSP LSP\n");
2426 "VRF Installs Removals Updates Installs Removals\n");
2428 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2429 struct zebra_vrf
*zvrf
= vrf
->info
;
2431 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2432 " %10" PRIu64
" %10" PRIu64
"\n",
2433 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2434 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2435 zvrf
->lsp_removals
);
2441 DEFUN (ip_forwarding
,
2445 "Turn on IP forwarding\n")
2451 ret
= ipforward_on();
2454 vty_out(vty
, "Can't turn on IP forwarding\n");
2455 return CMD_WARNING_CONFIG_FAILED
;
2461 DEFUN (no_ip_forwarding
,
2462 no_ip_forwarding_cmd
,
2466 "Turn off IP forwarding\n")
2472 ret
= ipforward_off();
2475 vty_out(vty
, "Can't turn off IP forwarding\n");
2476 return CMD_WARNING_CONFIG_FAILED
;
2482 /* Only display ip forwarding is enabled or not. */
2483 DEFUN (show_ip_forwarding
,
2484 show_ip_forwarding_cmd
,
2485 "show ip forwarding",
2488 "IP forwarding status\n")
2495 vty_out(vty
, "IP forwarding is off\n");
2497 vty_out(vty
, "IP forwarding is on\n");
2501 /* Only display ipv6 forwarding is enabled or not. */
2502 DEFUN (show_ipv6_forwarding
,
2503 show_ipv6_forwarding_cmd
,
2504 "show ipv6 forwarding",
2506 "IPv6 information\n"
2507 "Forwarding status\n")
2511 ret
= ipforward_ipv6();
2515 vty_out(vty
, "ipv6 forwarding is unknown\n");
2518 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2521 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2524 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2530 DEFUN (ipv6_forwarding
,
2531 ipv6_forwarding_cmd
,
2534 "Turn on IPv6 forwarding\n")
2538 ret
= ipforward_ipv6();
2540 ret
= ipforward_ipv6_on();
2543 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2544 return CMD_WARNING_CONFIG_FAILED
;
2550 DEFUN (no_ipv6_forwarding
,
2551 no_ipv6_forwarding_cmd
,
2552 "no ipv6 forwarding",
2555 "Turn off IPv6 forwarding\n")
2559 ret
= ipforward_ipv6();
2561 ret
= ipforward_ipv6_off();
2564 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2565 return CMD_WARNING_CONFIG_FAILED
;
2571 /* Display dataplane info */
2572 DEFUN (show_dataplane
,
2574 "show zebra dplane [detailed]",
2577 "Zebra dataplane information\n"
2578 "Detailed output\n")
2581 bool detailed
= false;
2583 if (argv_find(argv
, argc
, "detailed", &idx
))
2586 return dplane_show_helper(vty
, detailed
);
2589 /* Display dataplane providers info */
2590 DEFUN (show_dataplane_providers
,
2591 show_dataplane_providers_cmd
,
2592 "show zebra dplane providers [detailed]",
2595 "Zebra dataplane information\n"
2596 "Zebra dataplane provider information\n"
2597 "Detailed output\n")
2600 bool detailed
= false;
2602 if (argv_find(argv
, argc
, "detailed", &idx
))
2605 return dplane_show_provs_helper(vty
, detailed
);
2608 /* Configure dataplane incoming queue limit */
2609 DEFUN (zebra_dplane_queue_limit
,
2610 zebra_dplane_queue_limit_cmd
,
2611 "zebra dplane limit (0-10000)",
2614 "Limit incoming queued updates\n"
2615 "Number of queued updates\n")
2619 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2621 dplane_set_in_queue_limit(limit
, true);
2626 /* Reset dataplane queue limit to default value */
2627 DEFUN (no_zebra_dplane_queue_limit
,
2628 no_zebra_dplane_queue_limit_cmd
,
2629 "no zebra dplane limit [(0-10000)]",
2633 "Limit incoming queued updates\n"
2634 "Number of queued updates\n")
2636 dplane_set_in_queue_limit(0, false);
2641 /* Table configuration write function. */
2642 static int config_write_table(struct vty
*vty
)
2644 if (zebrad
.rtm_table_default
)
2645 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2649 /* IPForwarding configuration write function. */
2650 static int config_write_forwarding(struct vty
*vty
)
2652 /* FIXME: Find better place for that. */
2653 router_id_write(vty
);
2656 vty_out(vty
, "no ip forwarding\n");
2657 if (!ipforward_ipv6())
2658 vty_out(vty
, "no ipv6 forwarding\n");
2659 vty_out(vty
, "!\n");
2663 /* IP node for static routes. */
2664 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2665 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2666 /* table node for routing tables. */
2667 static struct cmd_node table_node
= {TABLE_NODE
,
2668 "", /* This node has no interface. */
2670 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2671 "", /* This node has no interface. */
2675 void zebra_vty_init(void)
2677 /* Install configuration write function. */
2678 install_node(&table_node
, config_write_table
);
2679 install_node(&forwarding_node
, config_write_forwarding
);
2681 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2682 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2683 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2684 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2687 install_element(VIEW_NODE
, &show_table_cmd
);
2688 install_element(CONFIG_NODE
, &config_table_cmd
);
2689 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2690 #endif /* HAVE_NETLINK */
2692 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2693 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2694 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2697 zebra_route_map_init();
2699 install_node(&ip_node
, zebra_ip_config
);
2700 install_node(&protocol_node
, config_write_protocol
);
2702 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2703 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2705 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2706 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2708 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2709 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2710 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2711 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2712 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2713 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2715 install_element(VIEW_NODE
, &show_vrf_cmd
);
2716 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2717 install_element(VIEW_NODE
, &show_route_cmd
);
2718 install_element(VIEW_NODE
, &show_route_table_cmd
);
2719 if (vrf_is_backend_netns())
2720 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2721 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2722 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2723 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2724 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2725 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2726 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2728 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2729 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2731 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2732 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2733 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2734 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2735 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2736 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2737 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2738 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2739 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2741 /* Commands for VRF */
2742 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2744 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2745 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2746 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2747 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2748 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2749 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2750 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2751 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2752 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2753 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2754 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2755 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2756 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2757 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2758 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2759 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2760 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2761 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2763 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2764 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2766 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2767 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2768 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2769 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2771 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2772 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2773 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2774 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);