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
);
71 * special macro to allow us to get the correct zebra_vrf
73 #define ZEBRA_DECLVAR_CONTEXT(A, B) \
74 struct vrf *A = VTY_GET_CONTEXT(vrf); \
75 struct zebra_vrf *B = (vrf) ? vrf->info : NULL;
77 /* VNI range as per RFC 7432 */
78 #define CMD_VNI_RANGE "(1-16777215)"
80 DEFUN (ip_multicast_mode
,
81 ip_multicast_mode_cmd
,
82 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
85 "RPF lookup behavior\n"
86 "Lookup in unicast RIB only\n"
87 "Lookup in multicast RIB only\n"
88 "Try multicast RIB first, fall back to unicast RIB\n"
89 "Lookup both, use entry with lower distance\n"
90 "Lookup both, use entry with longer prefix\n")
92 char *mode
= argv
[3]->text
;
94 if (strmatch(mode
, "urib-only"))
95 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
96 else if (strmatch(mode
, "mrib-only"))
97 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
98 else if (strmatch(mode
, "mrib-then-urib"))
99 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
100 else if (strmatch(mode
, "lower-distance"))
101 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
102 else if (strmatch(mode
, "longer-prefix"))
103 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
105 vty_out(vty
, "Invalid mode specified\n");
106 return CMD_WARNING_CONFIG_FAILED
;
112 DEFUN (no_ip_multicast_mode
,
113 no_ip_multicast_mode_cmd
,
114 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
117 "Multicast options\n"
118 "RPF lookup behavior\n"
119 "Lookup in unicast RIB only\n"
120 "Lookup in multicast RIB only\n"
121 "Try multicast RIB first, fall back to unicast RIB\n"
122 "Lookup both, use entry with lower distance\n"
123 "Lookup both, use entry with longer prefix\n")
125 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
132 "show ip rpf [json]",
135 "Display RPF information for multicast source\n"
138 bool uj
= use_json(argc
, argv
);
139 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
140 false, uj
, 0, NULL
, false, 0, 0);
143 DEFUN (show_ip_rpf_addr
,
144 show_ip_rpf_addr_cmd
,
145 "show ip rpf A.B.C.D",
148 "Display RPF information for multicast source\n"
149 "IP multicast source address (e.g. 10.0.0.0)\n")
153 struct route_node
*rn
;
154 struct route_entry
*re
;
157 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
159 vty_out(vty
, "%% Malformed address\n");
163 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
166 vty_show_ip_route_detail(vty
, rn
, 1);
168 vty_out(vty
, "%% No match for RPF lookup\n");
173 /* New RIB. Detailed information for IPv4 route. */
174 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
177 struct route_entry
*re
;
178 struct nexthop
*nexthop
;
179 char buf
[SRCDEST2STR_BUFFER
];
180 struct zebra_vrf
*zvrf
;
182 RNODE_FOREACH_RE (rn
, re
) {
183 const char *mcast_info
= "";
185 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
186 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
187 ? " using Multicast RIB"
188 : " using Unicast RIB";
191 vty_out(vty
, "Routing entry for %s%s\n",
192 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
193 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
195 vty_out(vty
, "[%d]", re
->instance
);
197 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
200 vty_out(vty
, ", tag %u", re
->tag
);
201 #if defined(SUPPORT_REALMS)
202 if (re
->tag
> 0 && re
->tag
<= 255)
203 vty_out(vty
, "(realm)");
207 vty_out(vty
, ", mtu %u", re
->mtu
);
208 if (re
->vrf_id
!= VRF_DEFAULT
) {
209 zvrf
= vrf_info_lookup(re
->vrf_id
);
210 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
212 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
213 vty_out(vty
, ", best");
220 uptime
-= re
->uptime
;
221 tm
= gmtime(&uptime
);
223 vty_out(vty
, " Last update ");
225 if (uptime
< ONE_DAY_SECOND
)
226 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
228 else if (uptime
< ONE_WEEK_SECOND
)
229 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
232 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
233 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
235 vty_out(vty
, " ago\n");
237 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
240 vty_out(vty
, " %c%s",
241 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
242 ? CHECK_FLAG(nexthop
->flags
,
243 NEXTHOP_FLAG_DUPLICATE
)
247 nexthop
->rparent
? " " : "");
249 switch (nexthop
->type
) {
250 case NEXTHOP_TYPE_IPV4
:
251 case NEXTHOP_TYPE_IPV4_IFINDEX
:
253 inet_ntoa(nexthop
->gate
.ipv4
));
254 if (nexthop
->ifindex
)
255 vty_out(vty
, ", via %s",
260 case NEXTHOP_TYPE_IPV6
:
261 case NEXTHOP_TYPE_IPV6_IFINDEX
:
263 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
265 if (nexthop
->ifindex
)
266 vty_out(vty
, ", via %s",
271 case NEXTHOP_TYPE_IFINDEX
:
272 vty_out(vty
, " directly connected, %s",
273 ifindex2ifname(nexthop
->ifindex
,
276 case NEXTHOP_TYPE_BLACKHOLE
:
277 vty_out(vty
, " unreachable");
278 switch (nexthop
->bh_type
) {
279 case BLACKHOLE_REJECT
:
280 vty_out(vty
, " (ICMP unreachable)");
282 case BLACKHOLE_ADMINPROHIB
:
284 " (ICMP admin-prohibited)");
287 vty_out(vty
, " (blackhole)");
289 case BLACKHOLE_UNSPEC
:
297 if ((re
->vrf_id
!= nexthop
->vrf_id
)
298 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
300 vrf_lookup_by_id(nexthop
->vrf_id
);
303 vty_out(vty
, "(vrf %s)", vrf
->name
);
305 vty_out(vty
, "(vrf UKNOWN)");
308 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
309 vty_out(vty
, " (duplicate nexthop removed)");
311 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
312 vty_out(vty
, " inactive");
314 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
315 vty_out(vty
, " onlink");
317 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
318 vty_out(vty
, " (recursive)");
320 switch (nexthop
->type
) {
321 case NEXTHOP_TYPE_IPV4
:
322 case NEXTHOP_TYPE_IPV4_IFINDEX
:
323 if (nexthop
->src
.ipv4
.s_addr
) {
324 if (inet_ntop(AF_INET
,
326 addrstr
, sizeof addrstr
))
327 vty_out(vty
, ", src %s",
331 case NEXTHOP_TYPE_IPV6
:
332 case NEXTHOP_TYPE_IPV6_IFINDEX
:
333 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
335 if (inet_ntop(AF_INET6
,
337 addrstr
, sizeof addrstr
))
338 vty_out(vty
, ", src %s",
347 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
349 /* Label information */
350 if (nexthop
->nh_label
351 && nexthop
->nh_label
->num_labels
) {
352 vty_out(vty
, ", label %s",
354 nexthop
->nh_label
->num_labels
,
355 nexthop
->nh_label
->label
, buf
,
365 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
366 struct route_entry
*re
, json_object
*json
)
368 struct nexthop
*nexthop
;
370 char buf
[SRCDEST2STR_BUFFER
];
371 json_object
*json_nexthops
= NULL
;
372 json_object
*json_nexthop
= NULL
;
373 json_object
*json_route
= NULL
;
374 json_object
*json_labels
= NULL
;
379 uptime
-= re
->uptime
;
380 tm
= gmtime(&uptime
);
383 json_route
= json_object_new_object();
384 json_nexthops
= json_object_new_array();
386 json_object_string_add(json_route
, "prefix",
387 srcdest_rnode2str(rn
, buf
, sizeof buf
));
388 json_object_string_add(json_route
, "protocol",
389 zebra_route_string(re
->type
));
392 json_object_int_add(json_route
, "instance",
396 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
398 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
399 json_object_boolean_true_add(json_route
, "selected");
401 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
402 json_object_int_add(json_route
, "distance",
404 json_object_int_add(json_route
, "metric", re
->metric
);
408 json_object_int_add(json_route
, "tag", re
->tag
);
410 json_object_int_add(json_route
, "internalStatus",
412 json_object_int_add(json_route
, "internalFlags",
414 if (uptime
< ONE_DAY_SECOND
)
415 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
417 else if (uptime
< ONE_WEEK_SECOND
)
418 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
421 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
422 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
425 json_object_string_add(json_route
, "uptime", buf
);
427 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
428 json_nexthop
= json_object_new_object();
430 json_object_int_add(json_nexthop
, "flags",
433 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
434 json_object_boolean_true_add(json_nexthop
,
437 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
438 json_object_boolean_true_add(json_nexthop
,
441 switch (nexthop
->type
) {
442 case NEXTHOP_TYPE_IPV4
:
443 case NEXTHOP_TYPE_IPV4_IFINDEX
:
444 json_object_string_add(
446 inet_ntoa(nexthop
->gate
.ipv4
));
447 json_object_string_add(json_nexthop
, "afi",
450 if (nexthop
->ifindex
) {
451 json_object_int_add(json_nexthop
,
454 json_object_string_add(
455 json_nexthop
, "interfaceName",
461 case NEXTHOP_TYPE_IPV6
:
462 case NEXTHOP_TYPE_IPV6_IFINDEX
:
463 json_object_string_add(
465 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
467 json_object_string_add(json_nexthop
, "afi",
470 if (nexthop
->ifindex
) {
471 json_object_int_add(json_nexthop
,
474 json_object_string_add(
475 json_nexthop
, "interfaceName",
482 case NEXTHOP_TYPE_IFINDEX
:
483 json_object_boolean_true_add(
484 json_nexthop
, "directlyConnected");
485 json_object_int_add(json_nexthop
,
488 json_object_string_add(
489 json_nexthop
, "interfaceName",
490 ifindex2ifname(nexthop
->ifindex
,
493 case NEXTHOP_TYPE_BLACKHOLE
:
494 json_object_boolean_true_add(json_nexthop
,
496 switch (nexthop
->bh_type
) {
497 case BLACKHOLE_REJECT
:
498 json_object_boolean_true_add(
499 json_nexthop
, "reject");
501 case BLACKHOLE_ADMINPROHIB
:
502 json_object_boolean_true_add(
507 json_object_boolean_true_add(
508 json_nexthop
, "blackhole");
510 case BLACKHOLE_UNSPEC
:
518 if ((nexthop
->vrf_id
!= re
->vrf_id
)
519 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
521 vrf_lookup_by_id(nexthop
->vrf_id
);
523 json_object_string_add(json_nexthop
, "vrf",
526 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
527 json_object_boolean_true_add(json_nexthop
,
530 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
531 json_object_boolean_true_add(json_nexthop
,
534 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
535 json_object_boolean_true_add(json_nexthop
,
538 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
539 json_object_boolean_true_add(json_nexthop
,
542 switch (nexthop
->type
) {
543 case NEXTHOP_TYPE_IPV4
:
544 case NEXTHOP_TYPE_IPV4_IFINDEX
:
545 if (nexthop
->src
.ipv4
.s_addr
) {
546 if (inet_ntop(AF_INET
,
547 &nexthop
->src
.ipv4
, buf
,
549 json_object_string_add(
550 json_nexthop
, "source",
554 case NEXTHOP_TYPE_IPV6
:
555 case NEXTHOP_TYPE_IPV6_IFINDEX
:
556 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
558 if (inet_ntop(AF_INET6
,
559 &nexthop
->src
.ipv6
, buf
,
561 json_object_string_add(
562 json_nexthop
, "source",
570 if (nexthop
->nh_label
571 && nexthop
->nh_label
->num_labels
) {
572 json_labels
= json_object_new_array();
574 for (int label_index
= 0;
576 < nexthop
->nh_label
->num_labels
;
578 json_object_array_add(
581 nexthop
->nh_label
->label
584 json_object_object_add(json_nexthop
, "labels",
588 json_object_array_add(json_nexthops
, json_nexthop
);
591 json_object_object_add(json_route
, "nexthops", json_nexthops
);
592 json_object_array_add(json
, json_route
);
596 /* Nexthop information. */
597 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
598 if (nexthop
== re
->ng
.nexthop
) {
599 /* Prefix information. */
600 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
602 len
+= vty_out(vty
, "[%d]", re
->instance
);
605 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
608 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
611 srcdest_rnode2str(rn
, buf
, sizeof buf
));
613 /* Distance and metric display. */
614 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
615 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
618 vty_out(vty
, " %c%*c",
619 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
620 ? CHECK_FLAG(nexthop
->flags
,
621 NEXTHOP_FLAG_DUPLICATE
)
625 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
628 switch (nexthop
->type
) {
629 case NEXTHOP_TYPE_IPV4
:
630 case NEXTHOP_TYPE_IPV4_IFINDEX
:
631 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
632 if (nexthop
->ifindex
)
634 ifindex2ifname(nexthop
->ifindex
,
637 case NEXTHOP_TYPE_IPV6
:
638 case NEXTHOP_TYPE_IPV6_IFINDEX
:
639 vty_out(vty
, " via %s",
640 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
642 if (nexthop
->ifindex
)
644 ifindex2ifname(nexthop
->ifindex
,
648 case NEXTHOP_TYPE_IFINDEX
:
649 vty_out(vty
, " is directly connected, %s",
650 ifindex2ifname(nexthop
->ifindex
,
653 case NEXTHOP_TYPE_BLACKHOLE
:
654 vty_out(vty
, " unreachable");
655 switch (nexthop
->bh_type
) {
656 case BLACKHOLE_REJECT
:
657 vty_out(vty
, " (ICMP unreachable)");
659 case BLACKHOLE_ADMINPROHIB
:
660 vty_out(vty
, " (ICMP admin-prohibited)");
663 vty_out(vty
, " (blackhole)");
665 case BLACKHOLE_UNSPEC
:
673 if ((nexthop
->vrf_id
!= re
->vrf_id
)
674 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
675 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
678 vty_out(vty
, "(vrf %s)", vrf
->name
);
680 vty_out(vty
, "(vrf UKNOWN)");
683 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
684 vty_out(vty
, " inactive");
686 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
687 vty_out(vty
, " onlink");
689 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
690 vty_out(vty
, " (recursive)");
692 switch (nexthop
->type
) {
693 case NEXTHOP_TYPE_IPV4
:
694 case NEXTHOP_TYPE_IPV4_IFINDEX
:
695 if (nexthop
->src
.ipv4
.s_addr
) {
696 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
698 vty_out(vty
, ", src %s", buf
);
701 case NEXTHOP_TYPE_IPV6
:
702 case NEXTHOP_TYPE_IPV6_IFINDEX
:
703 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
704 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
706 vty_out(vty
, ", src %s", buf
);
713 /* Label information */
714 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
715 vty_out(vty
, ", label %s",
716 mpls_label2str(nexthop
->nh_label
->num_labels
,
717 nexthop
->nh_label
->label
, buf
,
721 if (uptime
< ONE_DAY_SECOND
)
722 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
723 tm
->tm_min
, tm
->tm_sec
);
724 else if (uptime
< ONE_WEEK_SECOND
)
725 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
726 tm
->tm_hour
, tm
->tm_min
);
728 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
729 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
735 static void vty_show_ip_route_detail_json(struct vty
*vty
,
736 struct route_node
*rn
)
738 json_object
*json
= NULL
;
739 json_object
*json_prefix
= NULL
;
740 struct route_entry
*re
;
743 json
= json_object_new_object();
745 RNODE_FOREACH_RE (rn
, re
) {
746 json_prefix
= json_object_new_array();
747 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
748 prefix2str(&rn
->p
, buf
, sizeof buf
);
749 json_object_object_add(json
, buf
, json_prefix
);
753 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
754 json
, JSON_C_TO_STRING_PRETTY
));
755 json_object_free(json
);
758 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
759 struct route_table
*table
, afi_t afi
,
760 bool use_fib
, route_tag_t tag
,
761 const struct prefix
*longer_prefix_p
,
762 bool supernets_only
, int type
,
763 unsigned short ospf_instance_id
, bool use_json
)
765 struct route_node
*rn
;
766 struct route_entry
*re
;
769 json_object
*json
= NULL
;
770 json_object
*json_prefix
= NULL
;
775 json
= json_object_new_object();
777 /* Show all routes. */
778 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
779 dest
= rib_dest_from_rnode(rn
);
781 RNODE_FOREACH_RE (rn
, re
) {
782 if (use_fib
&& re
!= dest
->selected_fib
)
785 if (tag
&& re
->tag
!= tag
)
789 && !prefix_match(longer_prefix_p
, &rn
->p
))
792 /* This can only be true when the afi is IPv4 */
793 if (supernets_only
) {
794 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
796 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
799 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
802 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
806 if (type
&& re
->type
!= type
)
810 && (re
->type
!= ZEBRA_ROUTE_OSPF
811 || re
->instance
!= ospf_instance_id
))
816 json_prefix
= json_object_new_array();
821 SHOW_ROUTE_V4_HEADER
);
824 SHOW_ROUTE_V6_HEADER
);
826 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
827 vty_out(vty
, "\nVRF %s:\n",
834 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
838 prefix2str(&rn
->p
, buf
, sizeof(buf
));
839 json_object_object_add(json
, buf
, json_prefix
);
845 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
846 JSON_C_TO_STRING_PRETTY
));
847 json_object_free(json
);
851 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
852 safi_t safi
, bool use_fib
, bool use_json
,
854 const struct prefix
*longer_prefix_p
,
855 bool supernets_only
, int type
,
856 unsigned short ospf_instance_id
)
858 struct route_table
*table
;
859 struct zebra_vrf
*zvrf
= NULL
;
861 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
863 vty_out(vty
, "{}\n");
865 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
869 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
871 vty_out(vty
, "{}\n");
873 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
877 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
880 vty_out(vty
, "{}\n");
884 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
885 longer_prefix_p
, supernets_only
, type
,
886 ospf_instance_id
, use_json
);
891 DEFPY (show_route_table
,
892 show_route_table_cmd
,
893 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
899 "The table number to display, if available\n"
902 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
903 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
904 struct route_table
*t
;
906 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
908 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
914 DEFPY (show_route_table_vrf
,
915 show_route_table_vrf_cmd
,
916 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
922 "The table number to display, if available\n"
926 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
927 struct zebra_vrf
*zvrf
;
928 struct route_table
*t
;
929 vrf_id_t vrf_id
= VRF_DEFAULT
;
932 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
933 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
935 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
937 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
945 "show ip nht [vrf NAME]",
948 "IP nexthop tracking table\n"
952 vrf_id_t vrf_id
= VRF_DEFAULT
;
955 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
957 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
962 DEFUN (show_ip_nht_vrf_all
,
963 show_ip_nht_vrf_all_cmd
,
964 "show ip nht vrf all",
967 "IP nexthop tracking table\n"
968 VRF_ALL_CMD_HELP_STR
)
971 struct zebra_vrf
*zvrf
;
973 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
974 if ((zvrf
= vrf
->info
) != NULL
) {
975 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
976 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
983 DEFUN (show_ipv6_nht
,
985 "show ipv6 nht [vrf NAME]",
988 "IPv6 nexthop tracking table\n"
992 vrf_id_t vrf_id
= VRF_DEFAULT
;
995 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
997 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1002 DEFUN (show_ipv6_nht_vrf_all
,
1003 show_ipv6_nht_vrf_all_cmd
,
1004 "show ipv6 nht vrf all",
1007 "IPv6 nexthop tracking table\n"
1008 VRF_ALL_CMD_HELP_STR
)
1011 struct zebra_vrf
*zvrf
;
1013 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1014 if ((zvrf
= vrf
->info
) != NULL
) {
1015 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1016 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1023 DEFUN (ip_nht_default_route
,
1024 ip_nht_default_route_cmd
,
1025 "ip nht resolve-via-default",
1027 "Filter Next Hop tracking route resolution\n"
1028 "Resolve via default route\n")
1030 if (zebra_rnh_ip_default_route
)
1033 zebra_rnh_ip_default_route
= 1;
1034 zebra_evaluate_rnh(VRF_DEFAULT
, 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 if (!zebra_rnh_ip_default_route
)
1049 zebra_rnh_ip_default_route
= 0;
1050 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1054 DEFUN (ipv6_nht_default_route
,
1055 ipv6_nht_default_route_cmd
,
1056 "ipv6 nht resolve-via-default",
1058 "Filter Next Hop tracking route resolution\n"
1059 "Resolve via default route\n")
1061 if (zebra_rnh_ipv6_default_route
)
1064 zebra_rnh_ipv6_default_route
= 1;
1065 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1069 DEFUN (no_ipv6_nht_default_route
,
1070 no_ipv6_nht_default_route_cmd
,
1071 "no ipv6 nht resolve-via-default",
1074 "Filter Next Hop tracking route resolution\n"
1075 "Resolve via default route\n")
1077 if (!zebra_rnh_ipv6_default_route
)
1080 zebra_rnh_ipv6_default_route
= 0;
1081 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1089 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1092 |A.B.C.D/M$prefix longer-prefixes\
1093 |supernets-only$supernets_only\
1096 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1097 |ospf$type_str (1-65535)$ospf_instance_id\
1099 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1102 |X:X::X:X/M$prefix longer-prefixes\
1104 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1109 "IP forwarding table\n"
1110 "IP routing table\n"
1111 VRF_FULL_CMD_HELP_STR
1112 "Show only routes with tag\n"
1114 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1115 "Show route matching the specified Network/Mask pair only\n"
1116 "Show supernet entries only\n"
1117 FRR_IP_REDIST_HELP_STR_ZEBRA
1118 "Open Shortest Path First (OSPFv2)\n"
1121 "IP forwarding table\n"
1122 "IP routing table\n"
1123 VRF_FULL_CMD_HELP_STR
1124 "Show only routes with tag\n"
1127 "Show route matching the specified Network/Mask pair only\n"
1128 FRR_IP6_REDIST_HELP_STR_ZEBRA
1131 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1136 type
= proto_redistnum(afi
, type_str
);
1138 vty_out(vty
, "Unknown route type\n");
1144 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1145 struct zebra_vrf
*zvrf
;
1146 struct route_table
*table
;
1148 if ((zvrf
= vrf
->info
) == NULL
1149 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1153 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1154 !!json
, tag
, prefix_str
? prefix
: NULL
,
1155 !!supernets_only
, type
, ospf_instance_id
);
1158 vrf_id_t vrf_id
= VRF_DEFAULT
;
1161 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1162 vrf
= vrf_lookup_by_id(vrf_id
);
1163 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1164 !!json
, tag
, prefix_str
? prefix
: NULL
,
1165 !!supernets_only
, type
, ospf_instance_id
);
1171 DEFPY (show_route_detail
,
1172 show_route_detail_cmd
,
1175 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1180 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1189 "IP routing table\n"
1190 VRF_FULL_CMD_HELP_STR
1191 "Network in the IP routing table to display\n"
1192 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1194 "IP routing table\n"
1195 VRF_FULL_CMD_HELP_STR
1200 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1201 struct route_table
*table
;
1203 struct route_node
*rn
;
1206 prefix_str
= address_str
;
1207 if (str2prefix(prefix_str
, &p
) < 0) {
1208 vty_out(vty
, "%% Malformed address\n");
1214 struct zebra_vrf
*zvrf
;
1216 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1217 if ((zvrf
= vrf
->info
) == NULL
1218 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1221 rn
= route_node_match(table
, &p
);
1224 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1225 route_unlock_node(rn
);
1230 vty_show_ip_route_detail_json(vty
, rn
);
1232 vty_show_ip_route_detail(vty
, rn
, 0);
1234 route_unlock_node(rn
);
1237 vrf_id_t vrf_id
= VRF_DEFAULT
;
1240 VRF_GET_ID(vrf_id
, vrf_name
, false);
1242 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1246 rn
= route_node_match(table
, &p
);
1248 vty_out(vty
, "%% Network not in table\n");
1251 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1252 vty_out(vty
, "%% Network not in table\n");
1253 route_unlock_node(rn
);
1258 vty_show_ip_route_detail_json(vty
, rn
);
1260 vty_show_ip_route_detail(vty
, rn
, 0);
1262 route_unlock_node(rn
);
1268 DEFPY (show_route_summary
,
1269 show_route_summary_cmd
,
1272 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1273 summary [prefix$prefix]\
1274 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1275 summary [prefix$prefix]\
1279 "IP routing table\n"
1280 VRF_FULL_CMD_HELP_STR
1281 "Summary of all routes\n"
1284 "IP routing table\n"
1285 VRF_FULL_CMD_HELP_STR
1286 "Summary of all routes\n"
1289 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1290 struct route_table
*table
;
1294 struct zebra_vrf
*zvrf
;
1296 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1297 if ((zvrf
= vrf
->info
) == NULL
1298 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1302 vty_show_ip_route_summary_prefix(vty
, table
);
1304 vty_show_ip_route_summary(vty
, table
);
1307 vrf_id_t vrf_id
= VRF_DEFAULT
;
1310 VRF_GET_ID(vrf_id
, vrf_name
, false);
1312 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1317 vty_show_ip_route_summary_prefix(vty
, table
);
1319 vty_show_ip_route_summary(vty
, table
);
1325 static void vty_show_ip_route_summary(struct vty
*vty
,
1326 struct route_table
*table
)
1328 struct route_node
*rn
;
1329 struct route_entry
*re
;
1330 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1331 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1332 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1333 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1337 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1338 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1339 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1340 RNODE_FOREACH_RE (rn
, re
) {
1341 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1342 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1344 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1346 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1348 rib_cnt
[re
->type
]++;
1350 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1351 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1354 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1356 fib_cnt
[re
->type
]++;
1360 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1361 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1363 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1364 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1365 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1366 if (i
== ZEBRA_ROUTE_BGP
) {
1367 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1368 rib_cnt
[ZEBRA_ROUTE_BGP
],
1369 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1370 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1371 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1372 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1374 vty_out(vty
, "%-20s %-20d %-20d \n",
1375 zebra_route_string(i
), rib_cnt
[i
],
1380 vty_out(vty
, "------\n");
1381 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1382 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1387 * Implementation of the ip route summary prefix command.
1389 * This command prints the primary prefixes that have been installed by various
1390 * protocols on the box.
1393 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1394 struct route_table
*table
)
1396 struct route_node
*rn
;
1397 struct route_entry
*re
;
1398 struct nexthop
*nexthop
;
1399 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1400 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1401 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1402 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1406 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1407 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1408 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1409 RNODE_FOREACH_RE (rn
, re
) {
1412 * In case of ECMP, count only once.
1415 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1416 nexthop
= nexthop
->next
) {
1418 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1419 rib_cnt
[re
->type
]++;
1420 if (CHECK_FLAG(nexthop
->flags
,
1421 NEXTHOP_FLAG_FIB
)) {
1422 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1423 fib_cnt
[re
->type
]++;
1425 if (re
->type
== ZEBRA_ROUTE_BGP
1426 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1427 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1428 if (CHECK_FLAG(nexthop
->flags
,
1430 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1435 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1436 "Prefix Routes", "FIB",
1437 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1439 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1440 if (rib_cnt
[i
] > 0) {
1441 if (i
== ZEBRA_ROUTE_BGP
) {
1442 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1443 rib_cnt
[ZEBRA_ROUTE_BGP
]
1444 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1445 fib_cnt
[ZEBRA_ROUTE_BGP
]
1446 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1447 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1448 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1449 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1451 vty_out(vty
, "%-20s %-20d %-20d \n",
1452 zebra_route_string(i
), rib_cnt
[i
],
1457 vty_out(vty
, "------\n");
1458 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1459 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1464 * Show IPv6 mroute command.Used to dump
1465 * the Multicast routing table.
1467 DEFUN (show_ipv6_mroute
,
1468 show_ipv6_mroute_cmd
,
1469 "show ipv6 mroute [vrf NAME]",
1472 "IPv6 Multicast routing table\n"
1475 struct route_table
*table
;
1476 struct route_node
*rn
;
1477 struct route_entry
*re
;
1479 vrf_id_t vrf_id
= VRF_DEFAULT
;
1482 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1484 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1488 /* Show all IPv6 route. */
1489 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1490 RNODE_FOREACH_RE (rn
, re
) {
1492 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1495 vty_show_ip_route(vty
, rn
, re
, NULL
);
1500 DEFUN (show_ipv6_mroute_vrf_all
,
1501 show_ipv6_mroute_vrf_all_cmd
,
1502 "show ipv6 mroute vrf all",
1505 "IPv6 Multicast routing table\n"
1506 VRF_ALL_CMD_HELP_STR
)
1508 struct route_table
*table
;
1509 struct route_node
*rn
;
1510 struct route_entry
*re
;
1512 struct zebra_vrf
*zvrf
;
1515 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1516 if ((zvrf
= vrf
->info
) == NULL
1517 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1520 /* Show all IPv6 route. */
1521 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1522 RNODE_FOREACH_RE (rn
, re
) {
1524 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1527 vty_show_ip_route(vty
, rn
, re
, NULL
);
1533 DEFUN (allow_external_route_update
,
1534 allow_external_route_update_cmd
,
1535 "allow-external-route-update",
1536 "Allow FRR routes to be overwritten by external processes\n")
1543 DEFUN (no_allow_external_route_update
,
1544 no_allow_external_route_update_cmd
,
1545 "no allow-external-route-update",
1547 "Allow FRR routes to be overwritten by external processes\n")
1562 struct zebra_vrf
*zvrf
;
1564 if (vrf_is_backend_netns())
1565 vty_out(vty
, "netns-based vrfs\n");
1567 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1568 if (!(zvrf
= vrf
->info
))
1570 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1573 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1574 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1575 vty_out(vty
, "inactive");
1576 else if (zvrf_ns_name(zvrf
))
1577 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1578 zvrf_ns_name(zvrf
));
1580 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1582 if (vrf_is_user_cfged(vrf
))
1583 vty_out(vty
, " (configured)");
1590 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1591 default_vrf_vni_mapping_cmd
,
1592 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1593 "VNI corresponding to the DEFAULT VRF\n"
1595 "Prefix routes only \n")
1598 char err
[ERR_STR_SZ
];
1599 struct zebra_vrf
*zvrf
= NULL
;
1600 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1603 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1610 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1613 vty_out(vty
, "%s\n", err
);
1620 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1621 no_default_vrf_vni_mapping_cmd
,
1622 "no vni " CMD_VNI_RANGE
,
1624 "VNI corresponding to DEFAULT VRF\n"
1628 char err
[ERR_STR_SZ
];
1629 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1630 struct zebra_vrf
*zvrf
= NULL
;
1632 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1636 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1638 vty_out(vty
, "%s\n", err
);
1645 DEFUN (vrf_vni_mapping
,
1646 vrf_vni_mapping_cmd
,
1647 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1648 "VNI corresponding to tenant VRF\n"
1650 "prefix-routes-only\n")
1655 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1656 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1657 char err
[ERR_STR_SZ
];
1665 /* Mark as having FRR configuration */
1666 vrf_set_user_cfged(vrf
);
1667 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1670 vty_out(vty
, "%s\n", err
);
1677 DEFUN (no_vrf_vni_mapping
,
1678 no_vrf_vni_mapping_cmd
,
1679 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1681 "VNI corresponding to tenant VRF\n"
1683 "prefix-routes-only\n")
1687 char err
[ERR_STR_SZ
];
1688 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1690 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1698 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1699 ERR_STR_SZ
, filter
, 0);
1701 vty_out(vty
, "%s\n", err
);
1705 /* If no other FRR config for this VRF, mark accordingly. */
1706 if (!zebra_vrf_has_config(zvrf
))
1707 vrf_reset_user_cfged(vrf
);
1713 DEFUN (show_vrf_vni
,
1715 "show vrf vni [json]",
1722 struct zebra_vrf
*zvrf
;
1723 json_object
*json
= NULL
;
1724 json_object
*json_vrfs
= NULL
;
1725 bool uj
= use_json(argc
, argv
);
1728 json
= json_object_new_object();
1729 json_vrfs
= json_object_new_array();
1733 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1734 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1736 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1741 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1745 json_object_object_add(json
, "vrfs", json_vrfs
);
1746 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1747 json
, JSON_C_TO_STRING_PRETTY
));
1748 json_object_free(json
);
1754 DEFUN (show_evpn_global
,
1755 show_evpn_global_cmd
,
1761 bool uj
= use_json(argc
, argv
);
1763 zebra_vxlan_print_evpn(vty
, uj
);
1767 DEFUN (show_evpn_vni
,
1769 "show evpn vni [json]",
1772 "VxLAN information\n"
1775 struct zebra_vrf
*zvrf
;
1776 bool uj
= use_json(argc
, argv
);
1778 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1779 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1783 DEFUN (show_evpn_vni_vni
,
1784 show_evpn_vni_vni_cmd
,
1785 "show evpn vni " CMD_VNI_RANGE
"[json]",
1788 "VxLAN Network Identifier\n"
1792 struct zebra_vrf
*zvrf
;
1794 bool uj
= use_json(argc
, argv
);
1796 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1797 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1798 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1802 DEFUN (show_evpn_rmac_vni_mac
,
1803 show_evpn_rmac_vni_mac_cmd
,
1804 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1811 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1816 bool uj
= use_json(argc
, argv
);
1818 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1819 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1820 vty_out(vty
, "%% Malformed MAC address\n");
1823 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1827 DEFUN (show_evpn_rmac_vni
,
1828 show_evpn_rmac_vni_cmd
,
1829 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1838 bool uj
= use_json(argc
, argv
);
1840 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1841 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1846 DEFUN (show_evpn_rmac_vni_all
,
1847 show_evpn_rmac_vni_all_cmd
,
1848 "show evpn rmac vni all [json]",
1856 bool uj
= use_json(argc
, argv
);
1858 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1863 DEFUN (show_evpn_nh_vni_ip
,
1864 show_evpn_nh_vni_ip_cmd
,
1865 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1872 "Host address (ipv4 or ipv6)\n"
1877 bool uj
= use_json(argc
, argv
);
1879 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1880 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1882 vty_out(vty
, "%% Malformed Neighbor address\n");
1885 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1890 DEFUN (show_evpn_nh_vni
,
1891 show_evpn_nh_vni_cmd
,
1892 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1901 bool uj
= use_json(argc
, argv
);
1903 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1904 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1909 DEFUN (show_evpn_nh_vni_all
,
1910 show_evpn_nh_vni_all_cmd
,
1911 "show evpn next-hops vni all [json]",
1919 bool uj
= use_json(argc
, argv
);
1921 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1926 DEFUN (show_evpn_mac_vni
,
1927 show_evpn_mac_vni_cmd
,
1928 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1932 "VxLAN Network Identifier\n"
1936 struct zebra_vrf
*zvrf
;
1938 bool uj
= use_json(argc
, argv
);
1940 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1941 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1942 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1946 DEFUN (show_evpn_mac_vni_all
,
1947 show_evpn_mac_vni_all_cmd
,
1948 "show evpn mac vni all [json]",
1952 "VxLAN Network Identifier\n"
1956 struct zebra_vrf
*zvrf
;
1957 bool uj
= use_json(argc
, argv
);
1959 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1960 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
1964 DEFUN (show_evpn_mac_vni_all_vtep
,
1965 show_evpn_mac_vni_all_vtep_cmd
,
1966 "show evpn mac vni all vtep A.B.C.D [json]",
1970 "VxLAN Network Identifier\n"
1973 "Remote VTEP IP address\n"
1976 struct zebra_vrf
*zvrf
;
1977 struct in_addr vtep_ip
;
1978 bool uj
= use_json(argc
, argv
);
1980 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
1982 vty_out(vty
, "%% Malformed VTEP IP address\n");
1985 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1986 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
1992 DEFUN (show_evpn_mac_vni_mac
,
1993 show_evpn_mac_vni_mac_cmd
,
1994 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
1998 "VxLAN Network Identifier\n"
2001 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2003 struct zebra_vrf
*zvrf
;
2007 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2008 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2009 vty_out(vty
, "%% Malformed MAC address");
2012 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2013 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2017 DEFUN (show_evpn_mac_vni_vtep
,
2018 show_evpn_mac_vni_vtep_cmd
,
2019 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2023 "VxLAN Network Identifier\n"
2026 "Remote VTEP IP address\n"
2029 struct zebra_vrf
*zvrf
;
2031 struct in_addr vtep_ip
;
2032 bool uj
= use_json(argc
, argv
);
2034 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2035 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2037 vty_out(vty
, "%% Malformed VTEP IP address\n");
2041 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2042 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2046 DEFUN (show_evpn_neigh_vni
,
2047 show_evpn_neigh_vni_cmd
,
2048 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2051 "ARP and ND cache\n"
2052 "VxLAN Network Identifier\n"
2056 struct zebra_vrf
*zvrf
;
2058 bool uj
= use_json(argc
, argv
);
2060 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2061 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2062 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2066 DEFUN (show_evpn_neigh_vni_all
,
2067 show_evpn_neigh_vni_all_cmd
,
2068 "show evpn arp-cache vni all [json]",
2071 "ARP and ND cache\n"
2072 "VxLAN Network Identifier\n"
2076 struct zebra_vrf
*zvrf
;
2077 bool uj
= use_json(argc
, argv
);
2079 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2080 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2084 DEFUN (show_evpn_neigh_vni_neigh
,
2085 show_evpn_neigh_vni_neigh_cmd
,
2086 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2089 "ARP and ND cache\n"
2090 "VxLAN Network Identifier\n"
2093 "Neighbor address (IPv4 or IPv6 address)\n"
2096 struct zebra_vrf
*zvrf
;
2099 bool uj
= use_json(argc
, argv
);
2101 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2102 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2104 vty_out(vty
, "%% Malformed Neighbor address\n");
2107 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2108 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2112 DEFUN (show_evpn_neigh_vni_vtep
,
2113 show_evpn_neigh_vni_vtep_cmd
,
2114 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2117 "ARP and ND cache\n"
2118 "VxLAN Network Identifier\n"
2121 "Remote VTEP IP address\n"
2124 struct zebra_vrf
*zvrf
;
2126 struct in_addr vtep_ip
;
2127 bool uj
= use_json(argc
, argv
);
2129 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2130 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2132 vty_out(vty
, "%% Malformed VTEP IP address\n");
2136 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2137 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2141 /* policy routing contexts */
2142 DEFUN (show_pbr_ipset
,
2144 "show pbr ipset [WORD]",
2146 "Policy-Based Routing\n"
2147 "IPset Context information\n"
2148 "IPset Name information\n")
2152 found
= argv_find(argv
, argc
, "WORD", &idx
);
2154 zebra_pbr_show_ipset_list(vty
, NULL
);
2156 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2160 /* policy routing contexts */
2161 DEFUN (show_pbr_iptable
,
2162 show_pbr_iptable_cmd
,
2163 "show pbr iptable [WORD]",
2165 "Policy-Based Routing\n"
2166 "IPtable Context information\n"
2167 "IPtable Name information\n")
2172 found
= argv_find(argv
, argc
, "WORD", &idx
);
2174 zebra_pbr_show_iptable(vty
, NULL
);
2176 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2180 /* Static ip route configuration write function. */
2181 static int zebra_ip_config(struct vty
*vty
)
2185 write
+= zebra_import_table_config(vty
);
2190 DEFUN (ip_zebra_import_table_distance
,
2191 ip_zebra_import_table_distance_cmd
,
2192 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2194 "import routes from non-main kernel table\n"
2195 "kernel routing table id\n"
2196 "Distance for imported routes\n"
2197 "Default distance value\n"
2198 "route-map for filtering\n"
2201 uint32_t table_id
= 0;
2203 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2204 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2206 strmatch(argv
[argc
- 2]->text
, "route-map")
2207 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2211 if (argc
== 7 || (argc
== 5 && !rmap
))
2212 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2214 if (!is_zebra_valid_kernel_table(table_id
)) {
2216 "Invalid routing table ID, %d. Must be in range 1-252\n",
2219 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2223 if (is_zebra_main_routing_table(table_id
)) {
2225 "Invalid routing table ID, %d. Must be non-default table\n",
2228 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2232 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2234 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2239 DEFUN_HIDDEN (zebra_packet_process
,
2240 zebra_packet_process_cmd
,
2241 "zebra zapi-packets (1-10000)",
2244 "Number of packets to process before relinquishing thread\n")
2246 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2248 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2249 memory_order_relaxed
);
2254 DEFUN_HIDDEN (no_zebra_packet_process
,
2255 no_zebra_packet_process_cmd
,
2256 "no zebra zapi-packets [(1-10000)]",
2260 "Number of packets to process before relinquishing thread\n")
2262 atomic_store_explicit(&zebrad
.packets_to_process
,
2263 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2264 memory_order_relaxed
);
2269 DEFUN_HIDDEN (zebra_workqueue_timer
,
2270 zebra_workqueue_timer_cmd
,
2271 "zebra work-queue (0-10000)",
2274 "Time in milliseconds\n")
2276 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2277 zebrad
.ribq
->spec
.hold
= timer
;
2282 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2283 no_zebra_workqueue_timer_cmd
,
2284 "no zebra work-queue [(0-10000)]",
2288 "Time in milliseconds\n")
2290 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2295 DEFUN (no_ip_zebra_import_table
,
2296 no_ip_zebra_import_table_cmd
,
2297 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2300 "import routes from non-main kernel table\n"
2301 "kernel routing table id\n"
2302 "Distance for imported routes\n"
2303 "Default distance value\n"
2304 "route-map for filtering\n"
2307 uint32_t table_id
= 0;
2308 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2310 if (!is_zebra_valid_kernel_table(table_id
)) {
2312 "Invalid routing table ID. Must be in range 1-252\n");
2316 if (is_zebra_main_routing_table(table_id
)) {
2318 "Invalid routing table ID, %d. Must be non-default table\n",
2323 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2326 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2329 static int config_write_protocol(struct vty
*vty
)
2332 vty_out(vty
, "allow-external-route-update\n");
2334 if (zebra_rnh_ip_default_route
)
2335 vty_out(vty
, "ip nht resolve-via-default\n");
2337 if (zebra_rnh_ipv6_default_route
)
2338 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2340 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2341 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2343 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2344 vty_out(vty
, "zebra zapi-packets %u\n",
2345 zebrad
.packets_to_process
);
2347 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2349 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2350 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2351 ipv4_multicast_mode
== MCAST_URIB_ONLY
2353 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2355 : ipv4_multicast_mode
2356 == MCAST_MIX_MRIB_FIRST
2358 : ipv4_multicast_mode
2359 == MCAST_MIX_DISTANCE
2363 zebra_routemap_config_write_protocol(vty
);
2369 /* Display default rtm_table for all clients. */
2374 "default routing table to use for all clients\n")
2376 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2380 DEFUN (config_table
,
2383 "Configure target kernel routing table\n"
2386 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2390 DEFUN (no_config_table
,
2391 no_config_table_cmd
,
2392 "no table [TABLENO]",
2394 "Configure target kernel routing table\n"
2397 zebrad
.rtm_table_default
= 0;
2411 " Route Route Neighbor LSP LSP\n");
2413 "VRF Installs Removals Updates Installs Removals\n");
2415 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2416 struct zebra_vrf
*zvrf
= vrf
->info
;
2418 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2419 " %10" PRIu64
" %10" PRIu64
"\n",
2420 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2421 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2422 zvrf
->lsp_removals
);
2428 DEFUN (ip_forwarding
,
2432 "Turn on IP forwarding\n")
2438 ret
= ipforward_on();
2441 vty_out(vty
, "Can't turn on IP forwarding\n");
2442 return CMD_WARNING_CONFIG_FAILED
;
2448 DEFUN (no_ip_forwarding
,
2449 no_ip_forwarding_cmd
,
2453 "Turn off IP forwarding\n")
2459 ret
= ipforward_off();
2462 vty_out(vty
, "Can't turn off IP forwarding\n");
2463 return CMD_WARNING_CONFIG_FAILED
;
2469 /* Only display ip forwarding is enabled or not. */
2470 DEFUN (show_ip_forwarding
,
2471 show_ip_forwarding_cmd
,
2472 "show ip forwarding",
2475 "IP forwarding status\n")
2482 vty_out(vty
, "IP forwarding is off\n");
2484 vty_out(vty
, "IP forwarding is on\n");
2488 /* Only display ipv6 forwarding is enabled or not. */
2489 DEFUN (show_ipv6_forwarding
,
2490 show_ipv6_forwarding_cmd
,
2491 "show ipv6 forwarding",
2493 "IPv6 information\n"
2494 "Forwarding status\n")
2498 ret
= ipforward_ipv6();
2502 vty_out(vty
, "ipv6 forwarding is unknown\n");
2505 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2508 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2511 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2517 DEFUN (ipv6_forwarding
,
2518 ipv6_forwarding_cmd
,
2521 "Turn on IPv6 forwarding\n")
2525 ret
= ipforward_ipv6();
2527 ret
= ipforward_ipv6_on();
2530 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2531 return CMD_WARNING_CONFIG_FAILED
;
2537 DEFUN (no_ipv6_forwarding
,
2538 no_ipv6_forwarding_cmd
,
2539 "no ipv6 forwarding",
2542 "Turn off IPv6 forwarding\n")
2546 ret
= ipforward_ipv6();
2548 ret
= ipforward_ipv6_off();
2551 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2552 return CMD_WARNING_CONFIG_FAILED
;
2558 /* Table configuration write function. */
2559 static int config_write_table(struct vty
*vty
)
2561 if (zebrad
.rtm_table_default
)
2562 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2566 /* IPForwarding configuration write function. */
2567 static int config_write_forwarding(struct vty
*vty
)
2569 /* FIXME: Find better place for that. */
2570 router_id_write(vty
);
2573 vty_out(vty
, "no ip forwarding\n");
2574 if (!ipforward_ipv6())
2575 vty_out(vty
, "no ipv6 forwarding\n");
2576 vty_out(vty
, "!\n");
2580 /* IP node for static routes. */
2581 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2582 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2583 /* table node for routing tables. */
2584 static struct cmd_node table_node
= {TABLE_NODE
,
2585 "", /* This node has no interface. */
2587 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2588 "", /* This node has no interface. */
2592 void zebra_vty_init(void)
2594 /* Install configuration write function. */
2595 install_node(&table_node
, config_write_table
);
2596 install_node(&forwarding_node
, config_write_forwarding
);
2598 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2599 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2600 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2601 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2604 install_element(VIEW_NODE
, &show_table_cmd
);
2605 install_element(CONFIG_NODE
, &config_table_cmd
);
2606 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2607 #endif /* HAVE_NETLINK */
2609 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2610 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2611 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2614 zebra_route_map_init();
2616 install_node(&ip_node
, zebra_ip_config
);
2617 install_node(&protocol_node
, config_write_protocol
);
2619 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2620 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2622 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2623 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2625 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2626 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2627 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2628 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2629 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2630 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2632 install_element(VIEW_NODE
, &show_vrf_cmd
);
2633 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2634 install_element(VIEW_NODE
, &show_route_cmd
);
2635 install_element(VIEW_NODE
, &show_route_table_cmd
);
2636 if (vrf_is_backend_netns())
2637 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2638 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2639 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2640 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2641 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2642 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2643 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2645 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2646 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2648 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2649 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2650 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2651 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2652 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2654 /* Commands for VRF */
2655 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2657 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2658 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2659 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2660 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2661 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2662 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2663 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2664 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2665 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2666 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2667 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2668 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2669 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2670 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2671 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2672 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2673 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2674 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2676 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2677 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2679 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2680 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2681 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2682 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);