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
, uint8_t 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 int 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
,
766 struct route_node
*rn
;
767 struct route_entry
*re
;
770 json_object
*json
= NULL
;
771 json_object
*json_prefix
= NULL
;
776 json
= json_object_new_object();
778 /* Show all routes. */
779 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
780 dest
= rib_dest_from_rnode(rn
);
782 RNODE_FOREACH_RE (rn
, re
) {
783 if (use_fib
&& re
!= dest
->selected_fib
)
786 if (tag
&& re
->tag
!= tag
)
790 && !prefix_match(longer_prefix_p
, &rn
->p
))
793 /* This can only be true when the afi is IPv4 */
794 if (supernets_only
) {
795 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
797 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
800 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
803 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
807 if (type
&& re
->type
!= type
)
811 && (re
->type
!= ZEBRA_ROUTE_OSPF
812 || re
->instance
!= ospf_instance_id
))
817 json_prefix
= json_object_new_array();
822 SHOW_ROUTE_V4_HEADER
);
825 SHOW_ROUTE_V6_HEADER
);
827 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
828 vty_out(vty
, "\nVRF %s:\n",
835 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
839 prefix2str(&rn
->p
, buf
, sizeof(buf
));
840 json_object_object_add(json
, buf
, json_prefix
);
846 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
847 JSON_C_TO_STRING_PRETTY
));
848 json_object_free(json
);
852 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
853 safi_t safi
, bool use_fib
, uint8_t use_json
,
855 const struct prefix
*longer_prefix_p
,
856 bool supernets_only
, int type
,
857 unsigned short ospf_instance_id
)
859 struct route_table
*table
;
860 struct zebra_vrf
*zvrf
= NULL
;
862 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
864 vty_out(vty
, "{}\n");
866 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
870 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
872 vty_out(vty
, "{}\n");
874 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
878 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
881 vty_out(vty
, "{}\n");
885 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
886 longer_prefix_p
, supernets_only
, type
,
887 ospf_instance_id
, use_json
);
892 DEFPY (show_route_table
,
893 show_route_table_cmd
,
894 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
900 "The table number to display, if available\n"
903 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
904 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
905 struct route_table
*t
;
907 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
909 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
915 DEFPY (show_route_table_vrf
,
916 show_route_table_vrf_cmd
,
917 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
923 "The table number to display, if available\n"
927 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
928 struct zebra_vrf
*zvrf
;
929 struct route_table
*t
;
930 vrf_id_t vrf_id
= VRF_DEFAULT
;
933 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
934 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
936 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
938 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
946 "show ip nht [vrf NAME]",
949 "IP nexthop tracking table\n"
953 vrf_id_t vrf_id
= VRF_DEFAULT
;
956 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
958 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
963 DEFUN (show_ip_nht_vrf_all
,
964 show_ip_nht_vrf_all_cmd
,
965 "show ip nht vrf all",
968 "IP nexthop tracking table\n"
969 VRF_ALL_CMD_HELP_STR
)
972 struct zebra_vrf
*zvrf
;
974 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
975 if ((zvrf
= vrf
->info
) != NULL
) {
976 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
977 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
984 DEFUN (show_ipv6_nht
,
986 "show ipv6 nht [vrf NAME]",
989 "IPv6 nexthop tracking table\n"
993 vrf_id_t vrf_id
= VRF_DEFAULT
;
996 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
998 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1003 DEFUN (show_ipv6_nht_vrf_all
,
1004 show_ipv6_nht_vrf_all_cmd
,
1005 "show ipv6 nht vrf all",
1008 "IPv6 nexthop tracking table\n"
1009 VRF_ALL_CMD_HELP_STR
)
1012 struct zebra_vrf
*zvrf
;
1014 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1015 if ((zvrf
= vrf
->info
) != NULL
) {
1016 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1017 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1024 DEFUN (ip_nht_default_route
,
1025 ip_nht_default_route_cmd
,
1026 "ip nht resolve-via-default",
1028 "Filter Next Hop tracking route resolution\n"
1029 "Resolve via default route\n")
1031 if (zebra_rnh_ip_default_route
)
1034 zebra_rnh_ip_default_route
= 1;
1035 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1039 DEFUN (no_ip_nht_default_route
,
1040 no_ip_nht_default_route_cmd
,
1041 "no ip nht resolve-via-default",
1044 "Filter Next Hop tracking route resolution\n"
1045 "Resolve via default route\n")
1047 if (!zebra_rnh_ip_default_route
)
1050 zebra_rnh_ip_default_route
= 0;
1051 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1055 DEFUN (ipv6_nht_default_route
,
1056 ipv6_nht_default_route_cmd
,
1057 "ipv6 nht resolve-via-default",
1059 "Filter Next Hop tracking route resolution\n"
1060 "Resolve via default route\n")
1062 if (zebra_rnh_ipv6_default_route
)
1065 zebra_rnh_ipv6_default_route
= 1;
1066 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1070 DEFUN (no_ipv6_nht_default_route
,
1071 no_ipv6_nht_default_route_cmd
,
1072 "no ipv6 nht resolve-via-default",
1075 "Filter Next Hop tracking route resolution\n"
1076 "Resolve via default route\n")
1078 if (!zebra_rnh_ipv6_default_route
)
1081 zebra_rnh_ipv6_default_route
= 0;
1082 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1090 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1093 |A.B.C.D/M$prefix longer-prefixes\
1094 |supernets-only$supernets_only\
1097 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1098 |ospf$type_str (1-65535)$ospf_instance_id\
1100 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1103 |X:X::X:X/M$prefix longer-prefixes\
1105 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1110 "IP forwarding table\n"
1111 "IP routing table\n"
1112 VRF_FULL_CMD_HELP_STR
1113 "Show only routes with tag\n"
1115 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1116 "Show route matching the specified Network/Mask pair only\n"
1117 "Show supernet entries only\n"
1118 FRR_IP_REDIST_HELP_STR_ZEBRA
1119 "Open Shortest Path First (OSPFv2)\n"
1122 "IP forwarding table\n"
1123 "IP routing table\n"
1124 VRF_FULL_CMD_HELP_STR
1125 "Show only routes with tag\n"
1128 "Show route matching the specified Network/Mask pair only\n"
1129 FRR_IP6_REDIST_HELP_STR_ZEBRA
1132 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1137 type
= proto_redistnum(afi
, type_str
);
1139 vty_out(vty
, "Unknown route type\n");
1145 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1146 struct zebra_vrf
*zvrf
;
1147 struct route_table
*table
;
1149 if ((zvrf
= vrf
->info
) == NULL
1150 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1154 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1155 !!json
, tag
, prefix_str
? prefix
: NULL
,
1156 !!supernets_only
, type
, ospf_instance_id
);
1159 vrf_id_t vrf_id
= VRF_DEFAULT
;
1162 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1163 vrf
= vrf_lookup_by_id(vrf_id
);
1164 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1165 !!json
, tag
, prefix_str
? prefix
: NULL
,
1166 !!supernets_only
, type
, ospf_instance_id
);
1172 DEFPY (show_route_detail
,
1173 show_route_detail_cmd
,
1176 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1181 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1190 "IP routing table\n"
1191 VRF_FULL_CMD_HELP_STR
1192 "Network in the IP routing table to display\n"
1193 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1195 "IP routing table\n"
1196 VRF_FULL_CMD_HELP_STR
1201 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1202 struct route_table
*table
;
1204 struct route_node
*rn
;
1207 prefix_str
= address_str
;
1208 if (str2prefix(prefix_str
, &p
) < 0) {
1209 vty_out(vty
, "%% Malformed address\n");
1215 struct zebra_vrf
*zvrf
;
1217 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1218 if ((zvrf
= vrf
->info
) == NULL
1219 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1222 rn
= route_node_match(table
, &p
);
1225 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1226 route_unlock_node(rn
);
1231 vty_show_ip_route_detail_json(vty
, rn
);
1233 vty_show_ip_route_detail(vty
, rn
, 0);
1235 route_unlock_node(rn
);
1238 vrf_id_t vrf_id
= VRF_DEFAULT
;
1241 VRF_GET_ID(vrf_id
, vrf_name
, false);
1243 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1247 rn
= route_node_match(table
, &p
);
1249 vty_out(vty
, "%% Network not in table\n");
1252 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1253 vty_out(vty
, "%% Network not in table\n");
1254 route_unlock_node(rn
);
1259 vty_show_ip_route_detail_json(vty
, rn
);
1261 vty_show_ip_route_detail(vty
, rn
, 0);
1263 route_unlock_node(rn
);
1269 DEFPY (show_route_summary
,
1270 show_route_summary_cmd
,
1273 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1274 summary [prefix$prefix]\
1275 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1276 summary [prefix$prefix]\
1280 "IP routing table\n"
1281 VRF_FULL_CMD_HELP_STR
1282 "Summary of all routes\n"
1285 "IP routing table\n"
1286 VRF_FULL_CMD_HELP_STR
1287 "Summary of all routes\n"
1290 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1291 struct route_table
*table
;
1295 struct zebra_vrf
*zvrf
;
1297 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1298 if ((zvrf
= vrf
->info
) == NULL
1299 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1303 vty_show_ip_route_summary_prefix(vty
, table
);
1305 vty_show_ip_route_summary(vty
, table
);
1308 vrf_id_t vrf_id
= VRF_DEFAULT
;
1311 VRF_GET_ID(vrf_id
, vrf_name
, false);
1313 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1318 vty_show_ip_route_summary_prefix(vty
, table
);
1320 vty_show_ip_route_summary(vty
, table
);
1326 static void vty_show_ip_route_summary(struct vty
*vty
,
1327 struct route_table
*table
)
1329 struct route_node
*rn
;
1330 struct route_entry
*re
;
1331 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1332 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1333 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1334 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1338 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1339 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1340 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1341 RNODE_FOREACH_RE (rn
, re
) {
1342 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1343 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1345 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1347 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1349 rib_cnt
[re
->type
]++;
1351 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1352 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1355 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1357 fib_cnt
[re
->type
]++;
1361 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1362 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1364 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1365 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1366 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1367 if (i
== ZEBRA_ROUTE_BGP
) {
1368 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1369 rib_cnt
[ZEBRA_ROUTE_BGP
],
1370 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1371 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1372 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1373 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1375 vty_out(vty
, "%-20s %-20d %-20d \n",
1376 zebra_route_string(i
), rib_cnt
[i
],
1381 vty_out(vty
, "------\n");
1382 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1383 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1388 * Implementation of the ip route summary prefix command.
1390 * This command prints the primary prefixes that have been installed by various
1391 * protocols on the box.
1394 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1395 struct route_table
*table
)
1397 struct route_node
*rn
;
1398 struct route_entry
*re
;
1399 struct nexthop
*nexthop
;
1400 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1401 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1402 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1403 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1407 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1408 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1409 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1410 RNODE_FOREACH_RE (rn
, re
) {
1413 * In case of ECMP, count only once.
1416 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1417 nexthop
= nexthop
->next
) {
1419 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1420 rib_cnt
[re
->type
]++;
1421 if (CHECK_FLAG(nexthop
->flags
,
1422 NEXTHOP_FLAG_FIB
)) {
1423 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1424 fib_cnt
[re
->type
]++;
1426 if (re
->type
== ZEBRA_ROUTE_BGP
1427 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1428 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1429 if (CHECK_FLAG(nexthop
->flags
,
1431 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1436 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1437 "Prefix Routes", "FIB",
1438 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1440 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1441 if (rib_cnt
[i
] > 0) {
1442 if (i
== ZEBRA_ROUTE_BGP
) {
1443 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1444 rib_cnt
[ZEBRA_ROUTE_BGP
]
1445 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1446 fib_cnt
[ZEBRA_ROUTE_BGP
]
1447 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1448 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1449 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1450 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1452 vty_out(vty
, "%-20s %-20d %-20d \n",
1453 zebra_route_string(i
), rib_cnt
[i
],
1458 vty_out(vty
, "------\n");
1459 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1460 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1465 * Show IPv6 mroute command.Used to dump
1466 * the Multicast routing table.
1468 DEFUN (show_ipv6_mroute
,
1469 show_ipv6_mroute_cmd
,
1470 "show ipv6 mroute [vrf NAME]",
1473 "IPv6 Multicast routing table\n"
1476 struct route_table
*table
;
1477 struct route_node
*rn
;
1478 struct route_entry
*re
;
1480 vrf_id_t vrf_id
= VRF_DEFAULT
;
1483 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1485 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1489 /* Show all IPv6 route. */
1490 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1491 RNODE_FOREACH_RE (rn
, re
) {
1493 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1496 vty_show_ip_route(vty
, rn
, re
, NULL
);
1501 DEFUN (show_ipv6_mroute_vrf_all
,
1502 show_ipv6_mroute_vrf_all_cmd
,
1503 "show ipv6 mroute vrf all",
1506 "IPv6 Multicast routing table\n"
1507 VRF_ALL_CMD_HELP_STR
)
1509 struct route_table
*table
;
1510 struct route_node
*rn
;
1511 struct route_entry
*re
;
1513 struct zebra_vrf
*zvrf
;
1516 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1517 if ((zvrf
= vrf
->info
) == NULL
1518 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1521 /* Show all IPv6 route. */
1522 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1523 RNODE_FOREACH_RE (rn
, re
) {
1525 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1528 vty_show_ip_route(vty
, rn
, re
, NULL
);
1534 DEFUN (allow_external_route_update
,
1535 allow_external_route_update_cmd
,
1536 "allow-external-route-update",
1537 "Allow FRR routes to be overwritten by external processes\n")
1544 DEFUN (no_allow_external_route_update
,
1545 no_allow_external_route_update_cmd
,
1546 "no allow-external-route-update",
1548 "Allow FRR routes to be overwritten by external processes\n")
1563 struct zebra_vrf
*zvrf
;
1565 if (vrf_is_backend_netns())
1566 vty_out(vty
, "netns-based vrfs\n");
1568 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1569 if (!(zvrf
= vrf
->info
))
1571 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1574 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1575 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1576 vty_out(vty
, "inactive");
1577 else if (zvrf_ns_name(zvrf
))
1578 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1579 zvrf_ns_name(zvrf
));
1581 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1583 if (vrf_is_user_cfged(vrf
))
1584 vty_out(vty
, " (configured)");
1591 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1592 default_vrf_vni_mapping_cmd
,
1593 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1594 "VNI corresponding to the DEFAULT VRF\n"
1596 "Prefix routes only \n")
1599 char err
[ERR_STR_SZ
];
1600 struct zebra_vrf
*zvrf
= NULL
;
1601 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1604 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1611 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1614 vty_out(vty
, "%s\n", err
);
1621 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1622 no_default_vrf_vni_mapping_cmd
,
1623 "no vni " CMD_VNI_RANGE
,
1625 "VNI corresponding to DEFAULT VRF\n"
1629 char err
[ERR_STR_SZ
];
1630 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1631 struct zebra_vrf
*zvrf
= NULL
;
1633 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1637 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1639 vty_out(vty
, "%s\n", err
);
1646 DEFUN (vrf_vni_mapping
,
1647 vrf_vni_mapping_cmd
,
1648 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1649 "VNI corresponding to tenant VRF\n"
1651 "prefix-routes-only\n")
1656 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1657 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1658 char err
[ERR_STR_SZ
];
1666 /* Mark as having FRR configuration */
1667 vrf_set_user_cfged(vrf
);
1668 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1671 vty_out(vty
, "%s\n", err
);
1678 DEFUN (no_vrf_vni_mapping
,
1679 no_vrf_vni_mapping_cmd
,
1680 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1682 "VNI corresponding to tenant VRF\n"
1684 "prefix-routes-only\n")
1688 char err
[ERR_STR_SZ
];
1689 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1691 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1699 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1700 ERR_STR_SZ
, filter
, 0);
1702 vty_out(vty
, "%s\n", err
);
1706 /* If no other FRR config for this VRF, mark accordingly. */
1707 if (!zebra_vrf_has_config(zvrf
))
1708 vrf_reset_user_cfged(vrf
);
1714 DEFUN (show_vrf_vni
,
1716 "show vrf vni [json]",
1723 struct zebra_vrf
*zvrf
;
1724 json_object
*json
= NULL
;
1725 json_object
*json_vrfs
= NULL
;
1726 uint8_t uj
= use_json(argc
, argv
);
1729 json
= json_object_new_object();
1730 json_vrfs
= json_object_new_array();
1734 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1735 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1737 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1742 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1746 json_object_object_add(json
, "vrfs", json_vrfs
);
1747 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1748 json
, JSON_C_TO_STRING_PRETTY
));
1749 json_object_free(json
);
1755 DEFUN (show_evpn_global
,
1756 show_evpn_global_cmd
,
1762 uint8_t uj
= use_json(argc
, argv
);
1764 zebra_vxlan_print_evpn(vty
, uj
);
1768 DEFUN (show_evpn_vni
,
1770 "show evpn vni [json]",
1773 "VxLAN information\n"
1776 struct zebra_vrf
*zvrf
;
1777 uint8_t uj
= use_json(argc
, argv
);
1779 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1780 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1784 DEFUN (show_evpn_vni_vni
,
1785 show_evpn_vni_vni_cmd
,
1786 "show evpn vni " CMD_VNI_RANGE
"[json]",
1789 "VxLAN Network Identifier\n"
1793 struct zebra_vrf
*zvrf
;
1795 uint8_t uj
= use_json(argc
, argv
);
1797 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1798 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1799 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1803 DEFUN (show_evpn_rmac_vni_mac
,
1804 show_evpn_rmac_vni_mac_cmd
,
1805 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1812 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1817 uint8_t uj
= use_json(argc
, argv
);
1819 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1820 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1821 vty_out(vty
, "%% Malformed MAC address\n");
1824 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1828 DEFUN (show_evpn_rmac_vni
,
1829 show_evpn_rmac_vni_cmd
,
1830 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1839 uint8_t uj
= use_json(argc
, argv
);
1841 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1842 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1847 DEFUN (show_evpn_rmac_vni_all
,
1848 show_evpn_rmac_vni_all_cmd
,
1849 "show evpn rmac vni all [json]",
1857 uint8_t uj
= use_json(argc
, argv
);
1859 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1864 DEFUN (show_evpn_nh_vni_ip
,
1865 show_evpn_nh_vni_ip_cmd
,
1866 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1873 "Host address (ipv4 or ipv6)\n"
1878 uint8_t uj
= use_json(argc
, argv
);
1880 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1881 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1883 vty_out(vty
, "%% Malformed Neighbor address\n");
1886 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1891 DEFUN (show_evpn_nh_vni
,
1892 show_evpn_nh_vni_cmd
,
1893 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1902 uint8_t uj
= use_json(argc
, argv
);
1904 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1905 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1910 DEFUN (show_evpn_nh_vni_all
,
1911 show_evpn_nh_vni_all_cmd
,
1912 "show evpn next-hops vni all [json]",
1920 uint8_t uj
= use_json(argc
, argv
);
1922 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1927 DEFUN (show_evpn_mac_vni
,
1928 show_evpn_mac_vni_cmd
,
1929 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1933 "VxLAN Network Identifier\n"
1937 struct zebra_vrf
*zvrf
;
1939 uint8_t uj
= use_json(argc
, argv
);
1941 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1942 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1943 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1947 DEFUN (show_evpn_mac_vni_all
,
1948 show_evpn_mac_vni_all_cmd
,
1949 "show evpn mac vni all [json]",
1953 "VxLAN Network Identifier\n"
1957 struct zebra_vrf
*zvrf
;
1958 uint8_t uj
= use_json(argc
, argv
);
1960 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1961 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
1965 DEFUN (show_evpn_mac_vni_all_vtep
,
1966 show_evpn_mac_vni_all_vtep_cmd
,
1967 "show evpn mac vni all vtep A.B.C.D [json]",
1971 "VxLAN Network Identifier\n"
1974 "Remote VTEP IP address\n"
1977 struct zebra_vrf
*zvrf
;
1978 struct in_addr vtep_ip
;
1979 uint8_t uj
= use_json(argc
, argv
);
1981 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
1983 vty_out(vty
, "%% Malformed VTEP IP address\n");
1986 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1987 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
1993 DEFUN (show_evpn_mac_vni_mac
,
1994 show_evpn_mac_vni_mac_cmd
,
1995 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
1999 "VxLAN Network Identifier\n"
2002 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2004 struct zebra_vrf
*zvrf
;
2008 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2009 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2010 vty_out(vty
, "%% Malformed MAC address");
2013 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2014 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2018 DEFUN (show_evpn_mac_vni_vtep
,
2019 show_evpn_mac_vni_vtep_cmd
,
2020 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2024 "VxLAN Network Identifier\n"
2027 "Remote VTEP IP address\n"
2030 struct zebra_vrf
*zvrf
;
2032 struct in_addr vtep_ip
;
2033 uint8_t uj
= use_json(argc
, argv
);
2035 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2036 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2038 vty_out(vty
, "%% Malformed VTEP IP address\n");
2042 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2043 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2047 DEFUN (show_evpn_neigh_vni
,
2048 show_evpn_neigh_vni_cmd
,
2049 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2052 "ARP and ND cache\n"
2053 "VxLAN Network Identifier\n"
2057 struct zebra_vrf
*zvrf
;
2059 uint8_t uj
= use_json(argc
, argv
);
2061 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2062 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2063 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2067 DEFUN (show_evpn_neigh_vni_all
,
2068 show_evpn_neigh_vni_all_cmd
,
2069 "show evpn arp-cache vni all [json]",
2072 "ARP and ND cache\n"
2073 "VxLAN Network Identifier\n"
2077 struct zebra_vrf
*zvrf
;
2078 uint8_t uj
= use_json(argc
, argv
);
2080 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2081 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2085 DEFUN (show_evpn_neigh_vni_neigh
,
2086 show_evpn_neigh_vni_neigh_cmd
,
2087 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2090 "ARP and ND cache\n"
2091 "VxLAN Network Identifier\n"
2094 "Neighbor address (IPv4 or IPv6 address)\n"
2097 struct zebra_vrf
*zvrf
;
2100 uint8_t uj
= use_json(argc
, argv
);
2102 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2103 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2105 vty_out(vty
, "%% Malformed Neighbor address\n");
2108 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2109 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2113 DEFUN (show_evpn_neigh_vni_vtep
,
2114 show_evpn_neigh_vni_vtep_cmd
,
2115 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2118 "ARP and ND cache\n"
2119 "VxLAN Network Identifier\n"
2122 "Remote VTEP IP address\n"
2125 struct zebra_vrf
*zvrf
;
2127 struct in_addr vtep_ip
;
2128 uint8_t uj
= use_json(argc
, argv
);
2130 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2131 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2133 vty_out(vty
, "%% Malformed VTEP IP address\n");
2137 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2138 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2142 /* policy routing contexts */
2143 DEFUN (show_pbr_ipset
,
2145 "show pbr ipset [WORD]",
2147 "Policy-Based Routing\n"
2148 "IPset Context information\n"
2149 "IPset Name information\n")
2153 found
= argv_find(argv
, argc
, "WORD", &idx
);
2155 zebra_pbr_show_ipset_list(vty
, NULL
);
2157 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2161 /* policy routing contexts */
2162 DEFUN (show_pbr_iptable
,
2163 show_pbr_iptable_cmd
,
2164 "show pbr iptable [WORD]",
2166 "Policy-Based Routing\n"
2167 "IPtable Context information\n"
2168 "IPtable Name information\n")
2173 found
= argv_find(argv
, argc
, "WORD", &idx
);
2175 zebra_pbr_show_iptable(vty
, NULL
);
2177 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2181 /* Static ip route configuration write function. */
2182 static int zebra_ip_config(struct vty
*vty
)
2186 write
+= zebra_import_table_config(vty
);
2191 DEFUN (ip_zebra_import_table_distance
,
2192 ip_zebra_import_table_distance_cmd
,
2193 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2195 "import routes from non-main kernel table\n"
2196 "kernel routing table id\n"
2197 "Distance for imported routes\n"
2198 "Default distance value\n"
2199 "route-map for filtering\n"
2202 uint32_t table_id
= 0;
2204 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2205 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2207 strmatch(argv
[argc
- 2]->text
, "route-map")
2208 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2212 if (argc
== 7 || (argc
== 5 && !rmap
))
2213 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2215 if (!is_zebra_valid_kernel_table(table_id
)) {
2217 "Invalid routing table ID, %d. Must be in range 1-252\n",
2220 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2224 if (is_zebra_main_routing_table(table_id
)) {
2226 "Invalid routing table ID, %d. Must be non-default table\n",
2229 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2233 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2235 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2240 DEFUN_HIDDEN (zebra_packet_process
,
2241 zebra_packet_process_cmd
,
2242 "zebra zapi-packets (1-10000)",
2245 "Number of packets to process before relinquishing thread\n")
2247 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2249 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2250 memory_order_relaxed
);
2255 DEFUN_HIDDEN (no_zebra_packet_process
,
2256 no_zebra_packet_process_cmd
,
2257 "no zebra zapi-packets [(1-10000)]",
2261 "Number of packets to process before relinquishing thread\n")
2263 atomic_store_explicit(&zebrad
.packets_to_process
,
2264 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2265 memory_order_relaxed
);
2270 DEFUN_HIDDEN (zebra_workqueue_timer
,
2271 zebra_workqueue_timer_cmd
,
2272 "zebra work-queue (0-10000)",
2275 "Time in milliseconds\n")
2277 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2278 zebrad
.ribq
->spec
.hold
= timer
;
2283 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2284 no_zebra_workqueue_timer_cmd
,
2285 "no zebra work-queue [(0-10000)]",
2289 "Time in milliseconds\n")
2291 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2296 DEFUN (no_ip_zebra_import_table
,
2297 no_ip_zebra_import_table_cmd
,
2298 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2301 "import routes from non-main kernel table\n"
2302 "kernel routing table id\n"
2303 "Distance for imported routes\n"
2304 "Default distance value\n"
2305 "route-map for filtering\n"
2308 uint32_t table_id
= 0;
2309 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2311 if (!is_zebra_valid_kernel_table(table_id
)) {
2313 "Invalid routing table ID. Must be in range 1-252\n");
2317 if (is_zebra_main_routing_table(table_id
)) {
2319 "Invalid routing table ID, %d. Must be non-default table\n",
2324 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2327 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2330 static int config_write_protocol(struct vty
*vty
)
2333 vty_out(vty
, "allow-external-route-update\n");
2335 if (zebra_rnh_ip_default_route
)
2336 vty_out(vty
, "ip nht resolve-via-default\n");
2338 if (zebra_rnh_ipv6_default_route
)
2339 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2341 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2342 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2344 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2345 vty_out(vty
, "zebra zapi-packets %u\n",
2346 zebrad
.packets_to_process
);
2348 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2350 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2351 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2352 ipv4_multicast_mode
== MCAST_URIB_ONLY
2354 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2356 : ipv4_multicast_mode
2357 == MCAST_MIX_MRIB_FIRST
2359 : ipv4_multicast_mode
2360 == MCAST_MIX_DISTANCE
2364 zebra_routemap_config_write_protocol(vty
);
2370 /* Display default rtm_table for all clients. */
2375 "default routing table to use for all clients\n")
2377 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2381 DEFUN (config_table
,
2384 "Configure target kernel routing table\n"
2387 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2391 DEFUN (no_config_table
,
2392 no_config_table_cmd
,
2393 "no table [TABLENO]",
2395 "Configure target kernel routing table\n"
2398 zebrad
.rtm_table_default
= 0;
2412 " Route Route Neighbor LSP LSP\n");
2414 "VRF Installs Removals Updates Installs Removals\n");
2416 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2417 struct zebra_vrf
*zvrf
= vrf
->info
;
2419 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2420 " %10" PRIu64
" %10" PRIu64
"\n",
2421 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2422 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2423 zvrf
->lsp_removals
);
2429 DEFUN (ip_forwarding
,
2433 "Turn on IP forwarding\n")
2439 ret
= ipforward_on();
2442 vty_out(vty
, "Can't turn on IP forwarding\n");
2443 return CMD_WARNING_CONFIG_FAILED
;
2449 DEFUN (no_ip_forwarding
,
2450 no_ip_forwarding_cmd
,
2454 "Turn off IP forwarding\n")
2460 ret
= ipforward_off();
2463 vty_out(vty
, "Can't turn off IP forwarding\n");
2464 return CMD_WARNING_CONFIG_FAILED
;
2470 /* Only display ip forwarding is enabled or not. */
2471 DEFUN (show_ip_forwarding
,
2472 show_ip_forwarding_cmd
,
2473 "show ip forwarding",
2476 "IP forwarding status\n")
2483 vty_out(vty
, "IP forwarding is off\n");
2485 vty_out(vty
, "IP forwarding is on\n");
2489 /* Only display ipv6 forwarding is enabled or not. */
2490 DEFUN (show_ipv6_forwarding
,
2491 show_ipv6_forwarding_cmd
,
2492 "show ipv6 forwarding",
2494 "IPv6 information\n"
2495 "Forwarding status\n")
2499 ret
= ipforward_ipv6();
2503 vty_out(vty
, "ipv6 forwarding is unknown\n");
2506 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2509 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2512 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2518 DEFUN (ipv6_forwarding
,
2519 ipv6_forwarding_cmd
,
2522 "Turn on IPv6 forwarding\n")
2526 ret
= ipforward_ipv6();
2528 ret
= ipforward_ipv6_on();
2531 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2532 return CMD_WARNING_CONFIG_FAILED
;
2538 DEFUN (no_ipv6_forwarding
,
2539 no_ipv6_forwarding_cmd
,
2540 "no ipv6 forwarding",
2543 "Turn off IPv6 forwarding\n")
2547 ret
= ipforward_ipv6();
2549 ret
= ipforward_ipv6_off();
2552 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2553 return CMD_WARNING_CONFIG_FAILED
;
2559 /* Table configuration write function. */
2560 static int config_write_table(struct vty
*vty
)
2562 if (zebrad
.rtm_table_default
)
2563 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2567 /* IPForwarding configuration write function. */
2568 static int config_write_forwarding(struct vty
*vty
)
2570 /* FIXME: Find better place for that. */
2571 router_id_write(vty
);
2574 vty_out(vty
, "no ip forwarding\n");
2575 if (!ipforward_ipv6())
2576 vty_out(vty
, "no ipv6 forwarding\n");
2577 vty_out(vty
, "!\n");
2581 /* IP node for static routes. */
2582 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2583 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2584 /* table node for routing tables. */
2585 static struct cmd_node table_node
= {TABLE_NODE
,
2586 "", /* This node has no interface. */
2588 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2589 "", /* This node has no interface. */
2593 void zebra_vty_init(void)
2595 /* Install configuration write function. */
2596 install_node(&table_node
, config_write_table
);
2597 install_node(&forwarding_node
, config_write_forwarding
);
2599 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2600 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2601 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2602 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2605 install_element(VIEW_NODE
, &show_table_cmd
);
2606 install_element(CONFIG_NODE
, &config_table_cmd
);
2607 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2608 #endif /* HAVE_NETLINK */
2610 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2611 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2612 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2615 zebra_route_map_init();
2617 install_node(&ip_node
, zebra_ip_config
);
2618 install_node(&protocol_node
, config_write_protocol
);
2620 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2621 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2623 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2624 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2626 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2627 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2628 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2629 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2630 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2631 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2633 install_element(VIEW_NODE
, &show_vrf_cmd
);
2634 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2635 install_element(VIEW_NODE
, &show_route_cmd
);
2636 install_element(VIEW_NODE
, &show_route_table_cmd
);
2637 if (vrf_is_backend_netns())
2638 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2639 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2640 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2641 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2642 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2643 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2644 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2646 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2647 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2649 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2650 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2651 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2652 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2653 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2655 /* Commands for VRF */
2656 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2658 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2659 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2660 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2661 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2662 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2663 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2664 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2665 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2666 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2667 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2668 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2669 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2670 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2671 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2672 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2673 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2674 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2675 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2677 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2678 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2680 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2681 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2682 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2683 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);