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
);
407 json_object_int_add(json_route
, "internalStatus",
409 json_object_int_add(json_route
, "internalFlags",
411 if (uptime
< ONE_DAY_SECOND
)
412 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
414 else if (uptime
< ONE_WEEK_SECOND
)
415 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
418 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
419 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
422 json_object_string_add(json_route
, "uptime", buf
);
424 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
425 json_nexthop
= json_object_new_object();
427 json_object_int_add(json_nexthop
, "flags",
430 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
431 json_object_boolean_true_add(json_nexthop
,
434 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
435 json_object_boolean_true_add(json_nexthop
,
438 switch (nexthop
->type
) {
439 case NEXTHOP_TYPE_IPV4
:
440 case NEXTHOP_TYPE_IPV4_IFINDEX
:
441 json_object_string_add(
443 inet_ntoa(nexthop
->gate
.ipv4
));
444 json_object_string_add(json_nexthop
, "afi",
447 if (nexthop
->ifindex
) {
448 json_object_int_add(json_nexthop
,
451 json_object_string_add(
452 json_nexthop
, "interfaceName",
458 case NEXTHOP_TYPE_IPV6
:
459 case NEXTHOP_TYPE_IPV6_IFINDEX
:
460 json_object_string_add(
462 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
464 json_object_string_add(json_nexthop
, "afi",
467 if (nexthop
->ifindex
) {
468 json_object_int_add(json_nexthop
,
471 json_object_string_add(
472 json_nexthop
, "interfaceName",
479 case NEXTHOP_TYPE_IFINDEX
:
480 json_object_boolean_true_add(
481 json_nexthop
, "directlyConnected");
482 json_object_int_add(json_nexthop
,
485 json_object_string_add(
486 json_nexthop
, "interfaceName",
487 ifindex2ifname(nexthop
->ifindex
,
490 case NEXTHOP_TYPE_BLACKHOLE
:
491 json_object_boolean_true_add(json_nexthop
,
493 switch (nexthop
->bh_type
) {
494 case BLACKHOLE_REJECT
:
495 json_object_boolean_true_add(
496 json_nexthop
, "reject");
498 case BLACKHOLE_ADMINPROHIB
:
499 json_object_boolean_true_add(
504 json_object_boolean_true_add(
505 json_nexthop
, "blackhole");
507 case BLACKHOLE_UNSPEC
:
515 if ((nexthop
->vrf_id
!= re
->vrf_id
)
516 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
518 vrf_lookup_by_id(nexthop
->vrf_id
);
520 json_object_string_add(json_nexthop
, "vrf",
523 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
524 json_object_boolean_true_add(json_nexthop
,
527 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
528 json_object_boolean_true_add(json_nexthop
,
531 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
532 json_object_boolean_true_add(json_nexthop
,
535 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
536 json_object_boolean_true_add(json_nexthop
,
539 switch (nexthop
->type
) {
540 case NEXTHOP_TYPE_IPV4
:
541 case NEXTHOP_TYPE_IPV4_IFINDEX
:
542 if (nexthop
->src
.ipv4
.s_addr
) {
543 if (inet_ntop(AF_INET
,
544 &nexthop
->src
.ipv4
, buf
,
546 json_object_string_add(
547 json_nexthop
, "source",
551 case NEXTHOP_TYPE_IPV6
:
552 case NEXTHOP_TYPE_IPV6_IFINDEX
:
553 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
555 if (inet_ntop(AF_INET6
,
556 &nexthop
->src
.ipv6
, buf
,
558 json_object_string_add(
559 json_nexthop
, "source",
567 if (nexthop
->nh_label
568 && nexthop
->nh_label
->num_labels
) {
569 json_labels
= json_object_new_array();
571 for (int label_index
= 0;
573 < nexthop
->nh_label
->num_labels
;
575 json_object_array_add(
578 nexthop
->nh_label
->label
581 json_object_object_add(json_nexthop
, "labels",
585 json_object_array_add(json_nexthops
, json_nexthop
);
588 json_object_object_add(json_route
, "nexthops", json_nexthops
);
589 json_object_array_add(json
, json_route
);
593 /* Nexthop information. */
594 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
595 if (nexthop
== re
->ng
.nexthop
) {
596 /* Prefix information. */
597 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
599 len
+= vty_out(vty
, "[%d]", re
->instance
);
602 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
605 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
608 srcdest_rnode2str(rn
, buf
, sizeof buf
));
610 /* Distance and metric display. */
611 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
612 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
615 vty_out(vty
, " %c%*c",
616 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
617 ? CHECK_FLAG(nexthop
->flags
,
618 NEXTHOP_FLAG_DUPLICATE
)
622 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
625 switch (nexthop
->type
) {
626 case NEXTHOP_TYPE_IPV4
:
627 case NEXTHOP_TYPE_IPV4_IFINDEX
:
628 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
629 if (nexthop
->ifindex
)
631 ifindex2ifname(nexthop
->ifindex
,
634 case NEXTHOP_TYPE_IPV6
:
635 case NEXTHOP_TYPE_IPV6_IFINDEX
:
636 vty_out(vty
, " via %s",
637 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
639 if (nexthop
->ifindex
)
641 ifindex2ifname(nexthop
->ifindex
,
645 case NEXTHOP_TYPE_IFINDEX
:
646 vty_out(vty
, " is directly connected, %s",
647 ifindex2ifname(nexthop
->ifindex
,
650 case NEXTHOP_TYPE_BLACKHOLE
:
651 vty_out(vty
, " unreachable");
652 switch (nexthop
->bh_type
) {
653 case BLACKHOLE_REJECT
:
654 vty_out(vty
, " (ICMP unreachable)");
656 case BLACKHOLE_ADMINPROHIB
:
657 vty_out(vty
, " (ICMP admin-prohibited)");
660 vty_out(vty
, " (blackhole)");
662 case BLACKHOLE_UNSPEC
:
670 if ((nexthop
->vrf_id
!= re
->vrf_id
)
671 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
672 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
675 vty_out(vty
, "(vrf %s)", vrf
->name
);
677 vty_out(vty
, "(vrf UKNOWN)");
680 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
681 vty_out(vty
, " inactive");
683 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
684 vty_out(vty
, " onlink");
686 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
687 vty_out(vty
, " (recursive)");
689 switch (nexthop
->type
) {
690 case NEXTHOP_TYPE_IPV4
:
691 case NEXTHOP_TYPE_IPV4_IFINDEX
:
692 if (nexthop
->src
.ipv4
.s_addr
) {
693 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
695 vty_out(vty
, ", src %s", buf
);
698 case NEXTHOP_TYPE_IPV6
:
699 case NEXTHOP_TYPE_IPV6_IFINDEX
:
700 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
701 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
703 vty_out(vty
, ", src %s", buf
);
710 /* Label information */
711 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
712 vty_out(vty
, ", label %s",
713 mpls_label2str(nexthop
->nh_label
->num_labels
,
714 nexthop
->nh_label
->label
, buf
,
718 if (uptime
< ONE_DAY_SECOND
)
719 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
720 tm
->tm_min
, tm
->tm_sec
);
721 else if (uptime
< ONE_WEEK_SECOND
)
722 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
723 tm
->tm_hour
, tm
->tm_min
);
725 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
726 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
732 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
733 struct route_table
*table
, afi_t afi
,
734 bool use_fib
, route_tag_t tag
,
735 const struct prefix
*longer_prefix_p
,
736 bool supernets_only
, int type
,
737 unsigned short ospf_instance_id
,
740 struct route_node
*rn
;
741 struct route_entry
*re
;
744 json_object
*json
= NULL
;
745 json_object
*json_prefix
= NULL
;
750 json
= json_object_new_object();
752 /* Show all routes. */
753 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
754 dest
= rib_dest_from_rnode(rn
);
756 RNODE_FOREACH_RE (rn
, re
) {
757 if (use_fib
&& re
!= dest
->selected_fib
)
760 if (tag
&& re
->tag
!= tag
)
764 && !prefix_match(longer_prefix_p
, &rn
->p
))
767 /* This can only be true when the afi is IPv4 */
768 if (supernets_only
) {
769 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
771 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
774 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
777 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
781 if (type
&& re
->type
!= type
)
785 && (re
->type
!= ZEBRA_ROUTE_OSPF
786 || re
->instance
!= ospf_instance_id
))
791 json_prefix
= json_object_new_array();
796 SHOW_ROUTE_V4_HEADER
);
799 SHOW_ROUTE_V6_HEADER
);
801 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
802 vty_out(vty
, "\nVRF %s:\n",
809 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
813 prefix2str(&rn
->p
, buf
, sizeof buf
);
814 json_object_object_add(json
, buf
, json_prefix
);
820 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
821 json
, JSON_C_TO_STRING_PRETTY
));
822 json_object_free(json
);
826 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
827 safi_t safi
, bool use_fib
, uint8_t use_json
,
829 const struct prefix
*longer_prefix_p
,
830 bool supernets_only
, int type
,
831 unsigned short ospf_instance_id
)
833 struct route_table
*table
;
834 struct zebra_vrf
*zvrf
= NULL
;
836 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
838 vty_out(vty
, "{}\n");
840 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
844 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
846 vty_out(vty
, "{}\n");
848 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
852 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
855 vty_out(vty
, "{}\n");
859 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
860 longer_prefix_p
, supernets_only
, type
,
861 ospf_instance_id
, use_json
);
866 DEFPY (show_route_table
,
867 show_route_table_cmd
,
868 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
874 "The table number to display, if available\n"
877 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
878 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
879 struct route_table
*t
;
881 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
883 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
889 DEFPY (show_route_table_vrf
,
890 show_route_table_vrf_cmd
,
891 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
897 "The table number to display, if available\n"
901 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
902 struct zebra_vrf
*zvrf
;
903 struct route_table
*t
;
904 vrf_id_t vrf_id
= VRF_DEFAULT
;
907 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
908 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
910 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
912 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
920 "show ip nht [vrf NAME]",
923 "IP nexthop tracking table\n"
927 vrf_id_t vrf_id
= VRF_DEFAULT
;
930 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
932 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
937 DEFUN (show_ip_nht_vrf_all
,
938 show_ip_nht_vrf_all_cmd
,
939 "show ip nht vrf all",
942 "IP nexthop tracking table\n"
943 VRF_ALL_CMD_HELP_STR
)
946 struct zebra_vrf
*zvrf
;
948 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
949 if ((zvrf
= vrf
->info
) != NULL
) {
950 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
951 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
958 DEFUN (show_ipv6_nht
,
960 "show ipv6 nht [vrf NAME]",
963 "IPv6 nexthop tracking table\n"
967 vrf_id_t vrf_id
= VRF_DEFAULT
;
970 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
972 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
977 DEFUN (show_ipv6_nht_vrf_all
,
978 show_ipv6_nht_vrf_all_cmd
,
979 "show ipv6 nht vrf all",
982 "IPv6 nexthop tracking table\n"
983 VRF_ALL_CMD_HELP_STR
)
986 struct zebra_vrf
*zvrf
;
988 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
989 if ((zvrf
= vrf
->info
) != NULL
) {
990 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
991 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
998 DEFUN (ip_nht_default_route
,
999 ip_nht_default_route_cmd
,
1000 "ip nht resolve-via-default",
1002 "Filter Next Hop tracking route resolution\n"
1003 "Resolve via default route\n")
1005 if (zebra_rnh_ip_default_route
)
1008 zebra_rnh_ip_default_route
= 1;
1009 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1013 DEFUN (no_ip_nht_default_route
,
1014 no_ip_nht_default_route_cmd
,
1015 "no ip nht resolve-via-default",
1018 "Filter Next Hop tracking route resolution\n"
1019 "Resolve via default route\n")
1021 if (!zebra_rnh_ip_default_route
)
1024 zebra_rnh_ip_default_route
= 0;
1025 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1029 DEFUN (ipv6_nht_default_route
,
1030 ipv6_nht_default_route_cmd
,
1031 "ipv6 nht resolve-via-default",
1033 "Filter Next Hop tracking route resolution\n"
1034 "Resolve via default route\n")
1036 if (zebra_rnh_ipv6_default_route
)
1039 zebra_rnh_ipv6_default_route
= 1;
1040 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1044 DEFUN (no_ipv6_nht_default_route
,
1045 no_ipv6_nht_default_route_cmd
,
1046 "no ipv6 nht resolve-via-default",
1049 "Filter Next Hop tracking route resolution\n"
1050 "Resolve via default route\n")
1052 if (!zebra_rnh_ipv6_default_route
)
1055 zebra_rnh_ipv6_default_route
= 0;
1056 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1064 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1067 |A.B.C.D/M$prefix longer-prefixes\
1068 |supernets-only$supernets_only\
1071 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1072 |ospf$type_str (1-65535)$ospf_instance_id\
1074 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1077 |X:X::X:X/M$prefix longer-prefixes\
1079 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1084 "IP forwarding table\n"
1085 "IP routing table\n"
1086 VRF_FULL_CMD_HELP_STR
1087 "Show only routes with tag\n"
1089 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1090 "Show route matching the specified Network/Mask pair only\n"
1091 "Show supernet entries only\n"
1092 FRR_IP_REDIST_HELP_STR_ZEBRA
1093 "Open Shortest Path First (OSPFv2)\n"
1096 "IP forwarding table\n"
1097 "IP routing table\n"
1098 VRF_FULL_CMD_HELP_STR
1099 "Show only routes with tag\n"
1102 "Show route matching the specified Network/Mask pair only\n"
1103 FRR_IP6_REDIST_HELP_STR_ZEBRA
1106 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1111 type
= proto_redistnum(afi
, type_str
);
1113 vty_out(vty
, "Unknown route type\n");
1119 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1120 struct zebra_vrf
*zvrf
;
1121 struct route_table
*table
;
1123 if ((zvrf
= vrf
->info
) == NULL
1124 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1128 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1129 !!json
, tag
, prefix_str
? prefix
: NULL
,
1130 !!supernets_only
, type
, ospf_instance_id
);
1133 vrf_id_t vrf_id
= VRF_DEFAULT
;
1136 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1137 vrf
= vrf_lookup_by_id(vrf_id
);
1138 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1139 !!json
, tag
, prefix_str
? prefix
: NULL
,
1140 !!supernets_only
, type
, ospf_instance_id
);
1146 DEFPY (show_route_detail
,
1147 show_route_detail_cmd
,
1150 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1155 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1163 "IP routing table\n"
1164 VRF_FULL_CMD_HELP_STR
1165 "Network in the IP routing table to display\n"
1166 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1168 "IP routing table\n"
1169 VRF_FULL_CMD_HELP_STR
1173 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1174 struct route_table
*table
;
1176 struct route_node
*rn
;
1179 prefix_str
= address_str
;
1180 if (str2prefix(prefix_str
, &p
) < 0) {
1181 vty_out(vty
, "%% Malformed address\n");
1187 struct zebra_vrf
*zvrf
;
1189 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1190 if ((zvrf
= vrf
->info
) == NULL
1191 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1194 rn
= route_node_match(table
, &p
);
1197 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1198 route_unlock_node(rn
);
1202 vty_show_ip_route_detail(vty
, rn
, 0);
1204 route_unlock_node(rn
);
1207 vrf_id_t vrf_id
= VRF_DEFAULT
;
1210 VRF_GET_ID(vrf_id
, vrf_name
, false);
1212 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1216 rn
= route_node_match(table
, &p
);
1218 vty_out(vty
, "%% Network not in table\n");
1221 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1222 vty_out(vty
, "%% Network not in table\n");
1223 route_unlock_node(rn
);
1227 vty_show_ip_route_detail(vty
, rn
, 0);
1229 route_unlock_node(rn
);
1235 DEFPY (show_route_summary
,
1236 show_route_summary_cmd
,
1239 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1240 summary [prefix$prefix]\
1241 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1242 summary [prefix$prefix]\
1246 "IP routing table\n"
1247 VRF_FULL_CMD_HELP_STR
1248 "Summary of all routes\n"
1251 "IP routing table\n"
1252 VRF_FULL_CMD_HELP_STR
1253 "Summary of all routes\n"
1256 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1257 struct route_table
*table
;
1261 struct zebra_vrf
*zvrf
;
1263 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1264 if ((zvrf
= vrf
->info
) == NULL
1265 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1269 vty_show_ip_route_summary_prefix(vty
, table
);
1271 vty_show_ip_route_summary(vty
, table
);
1274 vrf_id_t vrf_id
= VRF_DEFAULT
;
1277 VRF_GET_ID(vrf_id
, vrf_name
, false);
1279 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1284 vty_show_ip_route_summary_prefix(vty
, table
);
1286 vty_show_ip_route_summary(vty
, table
);
1292 static void vty_show_ip_route_summary(struct vty
*vty
,
1293 struct route_table
*table
)
1295 struct route_node
*rn
;
1296 struct route_entry
*re
;
1297 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1298 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1299 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1300 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1304 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1305 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1306 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1307 RNODE_FOREACH_RE (rn
, re
) {
1308 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1309 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1311 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1313 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1315 rib_cnt
[re
->type
]++;
1317 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1318 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1321 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1323 fib_cnt
[re
->type
]++;
1327 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1328 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1330 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1331 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1332 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1333 if (i
== ZEBRA_ROUTE_BGP
) {
1334 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1335 rib_cnt
[ZEBRA_ROUTE_BGP
],
1336 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1337 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1338 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1339 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1341 vty_out(vty
, "%-20s %-20d %-20d \n",
1342 zebra_route_string(i
), rib_cnt
[i
],
1347 vty_out(vty
, "------\n");
1348 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1349 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1354 * Implementation of the ip route summary prefix command.
1356 * This command prints the primary prefixes that have been installed by various
1357 * protocols on the box.
1360 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1361 struct route_table
*table
)
1363 struct route_node
*rn
;
1364 struct route_entry
*re
;
1365 struct nexthop
*nexthop
;
1366 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1367 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1368 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1369 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1373 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1374 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1375 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1376 RNODE_FOREACH_RE (rn
, re
) {
1379 * In case of ECMP, count only once.
1382 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1383 nexthop
= nexthop
->next
) {
1385 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1386 rib_cnt
[re
->type
]++;
1387 if (CHECK_FLAG(nexthop
->flags
,
1388 NEXTHOP_FLAG_FIB
)) {
1389 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1390 fib_cnt
[re
->type
]++;
1392 if (re
->type
== ZEBRA_ROUTE_BGP
1393 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1394 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1395 if (CHECK_FLAG(nexthop
->flags
,
1397 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1402 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1403 "Prefix Routes", "FIB",
1404 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1406 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1407 if (rib_cnt
[i
] > 0) {
1408 if (i
== ZEBRA_ROUTE_BGP
) {
1409 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1410 rib_cnt
[ZEBRA_ROUTE_BGP
]
1411 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1412 fib_cnt
[ZEBRA_ROUTE_BGP
]
1413 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1414 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1415 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1416 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1418 vty_out(vty
, "%-20s %-20d %-20d \n",
1419 zebra_route_string(i
), rib_cnt
[i
],
1424 vty_out(vty
, "------\n");
1425 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1426 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1431 * Show IPv6 mroute command.Used to dump
1432 * the Multicast routing table.
1434 DEFUN (show_ipv6_mroute
,
1435 show_ipv6_mroute_cmd
,
1436 "show ipv6 mroute [vrf NAME]",
1439 "IPv6 Multicast routing table\n"
1442 struct route_table
*table
;
1443 struct route_node
*rn
;
1444 struct route_entry
*re
;
1446 vrf_id_t vrf_id
= VRF_DEFAULT
;
1449 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1451 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1455 /* Show all IPv6 route. */
1456 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1457 RNODE_FOREACH_RE (rn
, re
) {
1459 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1462 vty_show_ip_route(vty
, rn
, re
, NULL
);
1467 DEFUN (show_ipv6_mroute_vrf_all
,
1468 show_ipv6_mroute_vrf_all_cmd
,
1469 "show ipv6 mroute vrf all",
1472 "IPv6 Multicast routing table\n"
1473 VRF_ALL_CMD_HELP_STR
)
1475 struct route_table
*table
;
1476 struct route_node
*rn
;
1477 struct route_entry
*re
;
1479 struct zebra_vrf
*zvrf
;
1482 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1483 if ((zvrf
= vrf
->info
) == NULL
1484 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1487 /* Show all IPv6 route. */
1488 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1489 RNODE_FOREACH_RE (rn
, re
) {
1491 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1494 vty_show_ip_route(vty
, rn
, re
, NULL
);
1500 DEFUN (allow_external_route_update
,
1501 allow_external_route_update_cmd
,
1502 "allow-external-route-update",
1503 "Allow FRR routes to be overwritten by external processes\n")
1510 DEFUN (no_allow_external_route_update
,
1511 no_allow_external_route_update_cmd
,
1512 "no allow-external-route-update",
1514 "Allow FRR routes to be overwritten by external processes\n")
1529 struct zebra_vrf
*zvrf
;
1531 if (vrf_is_backend_netns())
1532 vty_out(vty
, "netns-based vrfs\n");
1534 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1535 if (!(zvrf
= vrf
->info
))
1537 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1540 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1541 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1542 vty_out(vty
, "inactive");
1543 else if (zvrf_ns_name(zvrf
))
1544 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1545 zvrf_ns_name(zvrf
));
1547 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1549 if (vrf_is_user_cfged(vrf
))
1550 vty_out(vty
, " (configured)");
1557 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1558 default_vrf_vni_mapping_cmd
,
1559 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1560 "VNI corresponding to the DEFAULT VRF\n"
1562 "Prefix routes only \n")
1565 char err
[ERR_STR_SZ
];
1566 struct zebra_vrf
*zvrf
= NULL
;
1567 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1570 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1577 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1580 vty_out(vty
, "%s\n", err
);
1587 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1588 no_default_vrf_vni_mapping_cmd
,
1589 "no vni " CMD_VNI_RANGE
,
1591 "VNI corresponding to DEFAULT VRF\n"
1595 char err
[ERR_STR_SZ
];
1596 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1597 struct zebra_vrf
*zvrf
= NULL
;
1599 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1603 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1605 vty_out(vty
, "%s\n", err
);
1612 DEFUN (vrf_vni_mapping
,
1613 vrf_vni_mapping_cmd
,
1614 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1615 "VNI corresponding to tenant VRF\n"
1617 "prefix-routes-only\n")
1622 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1623 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1624 char err
[ERR_STR_SZ
];
1632 /* Mark as having FRR configuration */
1633 vrf_set_user_cfged(vrf
);
1634 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1637 vty_out(vty
, "%s\n", err
);
1644 DEFUN (no_vrf_vni_mapping
,
1645 no_vrf_vni_mapping_cmd
,
1646 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1648 "VNI corresponding to tenant VRF\n"
1650 "prefix-routes-only\n")
1654 char err
[ERR_STR_SZ
];
1655 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1657 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1665 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1666 ERR_STR_SZ
, filter
, 0);
1668 vty_out(vty
, "%s\n", err
);
1672 /* If no other FRR config for this VRF, mark accordingly. */
1673 if (!zebra_vrf_has_config(zvrf
))
1674 vrf_reset_user_cfged(vrf
);
1680 DEFUN (show_vrf_vni
,
1682 "show vrf vni [json]",
1689 struct zebra_vrf
*zvrf
;
1690 json_object
*json
= NULL
;
1691 json_object
*json_vrfs
= NULL
;
1692 uint8_t uj
= use_json(argc
, argv
);
1695 json
= json_object_new_object();
1696 json_vrfs
= json_object_new_array();
1700 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1701 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1703 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1708 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1712 json_object_object_add(json
, "vrfs", json_vrfs
);
1713 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1714 json
, JSON_C_TO_STRING_PRETTY
));
1715 json_object_free(json
);
1721 DEFUN (show_evpn_global
,
1722 show_evpn_global_cmd
,
1728 uint8_t uj
= use_json(argc
, argv
);
1730 zebra_vxlan_print_evpn(vty
, uj
);
1734 DEFUN (show_evpn_vni
,
1736 "show evpn vni [json]",
1739 "VxLAN information\n"
1742 struct zebra_vrf
*zvrf
;
1743 uint8_t uj
= use_json(argc
, argv
);
1745 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1746 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1750 DEFUN (show_evpn_vni_vni
,
1751 show_evpn_vni_vni_cmd
,
1752 "show evpn vni " CMD_VNI_RANGE
"[json]",
1755 "VxLAN Network Identifier\n"
1759 struct zebra_vrf
*zvrf
;
1761 uint8_t uj
= use_json(argc
, argv
);
1763 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1764 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1765 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1769 DEFUN (show_evpn_rmac_vni_mac
,
1770 show_evpn_rmac_vni_mac_cmd
,
1771 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1778 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1783 uint8_t uj
= use_json(argc
, argv
);
1785 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1786 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1787 vty_out(vty
, "%% Malformed MAC address\n");
1790 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1794 DEFUN (show_evpn_rmac_vni
,
1795 show_evpn_rmac_vni_cmd
,
1796 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1805 uint8_t uj
= use_json(argc
, argv
);
1807 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1808 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1813 DEFUN (show_evpn_rmac_vni_all
,
1814 show_evpn_rmac_vni_all_cmd
,
1815 "show evpn rmac vni all [json]",
1823 uint8_t uj
= use_json(argc
, argv
);
1825 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1830 DEFUN (show_evpn_nh_vni_ip
,
1831 show_evpn_nh_vni_ip_cmd
,
1832 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1839 "Host address (ipv4 or ipv6)\n"
1844 uint8_t uj
= use_json(argc
, argv
);
1846 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1847 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1849 vty_out(vty
, "%% Malformed Neighbor address\n");
1852 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1857 DEFUN (show_evpn_nh_vni
,
1858 show_evpn_nh_vni_cmd
,
1859 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1868 uint8_t uj
= use_json(argc
, argv
);
1870 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1871 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1876 DEFUN (show_evpn_nh_vni_all
,
1877 show_evpn_nh_vni_all_cmd
,
1878 "show evpn next-hops vni all [json]",
1886 uint8_t uj
= use_json(argc
, argv
);
1888 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1893 DEFUN (show_evpn_mac_vni
,
1894 show_evpn_mac_vni_cmd
,
1895 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1899 "VxLAN Network Identifier\n"
1903 struct zebra_vrf
*zvrf
;
1905 uint8_t uj
= use_json(argc
, argv
);
1907 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1908 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1909 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1913 DEFUN (show_evpn_mac_vni_all
,
1914 show_evpn_mac_vni_all_cmd
,
1915 "show evpn mac vni all [json]",
1919 "VxLAN Network Identifier\n"
1923 struct zebra_vrf
*zvrf
;
1924 uint8_t uj
= use_json(argc
, argv
);
1926 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1927 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
1931 DEFUN (show_evpn_mac_vni_all_vtep
,
1932 show_evpn_mac_vni_all_vtep_cmd
,
1933 "show evpn mac vni all vtep A.B.C.D [json]",
1937 "VxLAN Network Identifier\n"
1940 "Remote VTEP IP address\n"
1943 struct zebra_vrf
*zvrf
;
1944 struct in_addr vtep_ip
;
1945 uint8_t uj
= use_json(argc
, argv
);
1947 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
1949 vty_out(vty
, "%% Malformed VTEP IP address\n");
1952 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1953 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
1959 DEFUN (show_evpn_mac_vni_mac
,
1960 show_evpn_mac_vni_mac_cmd
,
1961 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
1965 "VxLAN Network Identifier\n"
1968 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
1970 struct zebra_vrf
*zvrf
;
1974 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1975 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1976 vty_out(vty
, "%% Malformed MAC address");
1979 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1980 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
1984 DEFUN (show_evpn_mac_vni_vtep
,
1985 show_evpn_mac_vni_vtep_cmd
,
1986 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
1990 "VxLAN Network Identifier\n"
1993 "Remote VTEP IP address\n"
1996 struct zebra_vrf
*zvrf
;
1998 struct in_addr vtep_ip
;
1999 uint8_t uj
= use_json(argc
, argv
);
2001 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2002 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2004 vty_out(vty
, "%% Malformed VTEP IP address\n");
2008 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2009 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2013 DEFUN (show_evpn_neigh_vni
,
2014 show_evpn_neigh_vni_cmd
,
2015 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2018 "ARP and ND cache\n"
2019 "VxLAN Network Identifier\n"
2023 struct zebra_vrf
*zvrf
;
2025 uint8_t uj
= use_json(argc
, argv
);
2027 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2028 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2029 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2033 DEFUN (show_evpn_neigh_vni_all
,
2034 show_evpn_neigh_vni_all_cmd
,
2035 "show evpn arp-cache vni all [json]",
2038 "ARP and ND cache\n"
2039 "VxLAN Network Identifier\n"
2043 struct zebra_vrf
*zvrf
;
2044 uint8_t uj
= use_json(argc
, argv
);
2046 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2047 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2051 DEFUN (show_evpn_neigh_vni_neigh
,
2052 show_evpn_neigh_vni_neigh_cmd
,
2053 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2056 "ARP and ND cache\n"
2057 "VxLAN Network Identifier\n"
2060 "Neighbor address (IPv4 or IPv6 address)\n"
2063 struct zebra_vrf
*zvrf
;
2066 uint8_t uj
= use_json(argc
, argv
);
2068 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2069 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2071 vty_out(vty
, "%% Malformed Neighbor address\n");
2074 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2075 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2079 DEFUN (show_evpn_neigh_vni_vtep
,
2080 show_evpn_neigh_vni_vtep_cmd
,
2081 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2084 "ARP and ND cache\n"
2085 "VxLAN Network Identifier\n"
2088 "Remote VTEP IP address\n"
2091 struct zebra_vrf
*zvrf
;
2093 struct in_addr vtep_ip
;
2094 uint8_t uj
= use_json(argc
, argv
);
2096 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2097 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2099 vty_out(vty
, "%% Malformed VTEP IP address\n");
2103 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2104 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2108 /* policy routing contexts */
2109 DEFUN (show_pbr_ipset
,
2111 "show pbr ipset [WORD]",
2113 "Policy-Based Routing\n"
2114 "IPset Context information\n"
2115 "IPset Name information\n")
2119 found
= argv_find(argv
, argc
, "WORD", &idx
);
2121 zebra_pbr_show_ipset_list(vty
, NULL
);
2123 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2127 /* policy routing contexts */
2128 DEFUN (show_pbr_iptable
,
2129 show_pbr_iptable_cmd
,
2130 "show pbr iptable [WORD]",
2132 "Policy-Based Routing\n"
2133 "IPtable Context information\n"
2134 "IPtable Name information\n")
2139 found
= argv_find(argv
, argc
, "WORD", &idx
);
2141 zebra_pbr_show_iptable(vty
, NULL
);
2143 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2147 /* Static ip route configuration write function. */
2148 static int zebra_ip_config(struct vty
*vty
)
2152 write
+= zebra_import_table_config(vty
);
2157 DEFUN (ip_zebra_import_table_distance
,
2158 ip_zebra_import_table_distance_cmd
,
2159 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2161 "import routes from non-main kernel table\n"
2162 "kernel routing table id\n"
2163 "Distance for imported routes\n"
2164 "Default distance value\n"
2165 "route-map for filtering\n"
2168 uint32_t table_id
= 0;
2170 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2171 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2173 strmatch(argv
[argc
- 2]->text
, "route-map")
2174 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2178 if (argc
== 7 || (argc
== 5 && !rmap
))
2179 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2181 if (!is_zebra_valid_kernel_table(table_id
)) {
2183 "Invalid routing table ID, %d. Must be in range 1-252\n",
2186 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2190 if (is_zebra_main_routing_table(table_id
)) {
2192 "Invalid routing table ID, %d. Must be non-default table\n",
2195 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2199 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2201 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2206 DEFUN_HIDDEN (zebra_packet_process
,
2207 zebra_packet_process_cmd
,
2208 "zebra zapi-packets (1-10000)",
2211 "Number of packets to process before relinquishing thread\n")
2213 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2215 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2216 memory_order_relaxed
);
2221 DEFUN_HIDDEN (no_zebra_packet_process
,
2222 no_zebra_packet_process_cmd
,
2223 "no zebra zapi-packets [(1-10000)]",
2227 "Number of packets to process before relinquishing thread\n")
2229 atomic_store_explicit(&zebrad
.packets_to_process
,
2230 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2231 memory_order_relaxed
);
2236 DEFUN_HIDDEN (zebra_workqueue_timer
,
2237 zebra_workqueue_timer_cmd
,
2238 "zebra work-queue (0-10000)",
2241 "Time in milliseconds\n")
2243 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2244 zebrad
.ribq
->spec
.hold
= timer
;
2249 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2250 no_zebra_workqueue_timer_cmd
,
2251 "no zebra work-queue [(0-10000)]",
2255 "Time in milliseconds\n")
2257 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2262 DEFUN (no_ip_zebra_import_table
,
2263 no_ip_zebra_import_table_cmd
,
2264 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2267 "import routes from non-main kernel table\n"
2268 "kernel routing table id\n"
2269 "Distance for imported routes\n"
2270 "Default distance value\n"
2271 "route-map for filtering\n"
2274 uint32_t table_id
= 0;
2275 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2277 if (!is_zebra_valid_kernel_table(table_id
)) {
2279 "Invalid routing table ID. Must be in range 1-252\n");
2283 if (is_zebra_main_routing_table(table_id
)) {
2285 "Invalid routing table ID, %d. Must be non-default table\n",
2290 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2293 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2296 static int config_write_protocol(struct vty
*vty
)
2299 vty_out(vty
, "allow-external-route-update\n");
2301 if (zebra_rnh_ip_default_route
)
2302 vty_out(vty
, "ip nht resolve-via-default\n");
2304 if (zebra_rnh_ipv6_default_route
)
2305 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2307 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2308 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2310 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2311 vty_out(vty
, "zebra zapi-packets %u\n",
2312 zebrad
.packets_to_process
);
2314 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2316 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2317 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2318 ipv4_multicast_mode
== MCAST_URIB_ONLY
2320 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2322 : ipv4_multicast_mode
2323 == MCAST_MIX_MRIB_FIRST
2325 : ipv4_multicast_mode
2326 == MCAST_MIX_DISTANCE
2330 zebra_routemap_config_write_protocol(vty
);
2336 /* Display default rtm_table for all clients. */
2341 "default routing table to use for all clients\n")
2343 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2347 DEFUN (config_table
,
2350 "Configure target kernel routing table\n"
2353 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2357 DEFUN (no_config_table
,
2358 no_config_table_cmd
,
2359 "no table [TABLENO]",
2361 "Configure target kernel routing table\n"
2364 zebrad
.rtm_table_default
= 0;
2378 " Route Route Neighbor LSP LSP\n");
2380 "VRF Installs Removals Updates Installs Removals\n");
2382 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2383 struct zebra_vrf
*zvrf
= vrf
->info
;
2385 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2386 " %10" PRIu64
" %10" PRIu64
"\n",
2387 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2388 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2389 zvrf
->lsp_removals
);
2395 DEFUN (ip_forwarding
,
2399 "Turn on IP forwarding\n")
2405 ret
= ipforward_on();
2408 vty_out(vty
, "Can't turn on IP forwarding\n");
2409 return CMD_WARNING_CONFIG_FAILED
;
2415 DEFUN (no_ip_forwarding
,
2416 no_ip_forwarding_cmd
,
2420 "Turn off IP forwarding\n")
2426 ret
= ipforward_off();
2429 vty_out(vty
, "Can't turn off IP forwarding\n");
2430 return CMD_WARNING_CONFIG_FAILED
;
2436 /* Only display ip forwarding is enabled or not. */
2437 DEFUN (show_ip_forwarding
,
2438 show_ip_forwarding_cmd
,
2439 "show ip forwarding",
2442 "IP forwarding status\n")
2449 vty_out(vty
, "IP forwarding is off\n");
2451 vty_out(vty
, "IP forwarding is on\n");
2455 /* Only display ipv6 forwarding is enabled or not. */
2456 DEFUN (show_ipv6_forwarding
,
2457 show_ipv6_forwarding_cmd
,
2458 "show ipv6 forwarding",
2460 "IPv6 information\n"
2461 "Forwarding status\n")
2465 ret
= ipforward_ipv6();
2469 vty_out(vty
, "ipv6 forwarding is unknown\n");
2472 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2475 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2478 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2484 DEFUN (ipv6_forwarding
,
2485 ipv6_forwarding_cmd
,
2488 "Turn on IPv6 forwarding\n")
2492 ret
= ipforward_ipv6();
2494 ret
= ipforward_ipv6_on();
2497 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2498 return CMD_WARNING_CONFIG_FAILED
;
2504 DEFUN (no_ipv6_forwarding
,
2505 no_ipv6_forwarding_cmd
,
2506 "no ipv6 forwarding",
2509 "Turn off IPv6 forwarding\n")
2513 ret
= ipforward_ipv6();
2515 ret
= ipforward_ipv6_off();
2518 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2519 return CMD_WARNING_CONFIG_FAILED
;
2525 /* Table configuration write function. */
2526 static int config_write_table(struct vty
*vty
)
2528 if (zebrad
.rtm_table_default
)
2529 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2533 /* IPForwarding configuration write function. */
2534 static int config_write_forwarding(struct vty
*vty
)
2536 /* FIXME: Find better place for that. */
2537 router_id_write(vty
);
2540 vty_out(vty
, "no ip forwarding\n");
2541 if (!ipforward_ipv6())
2542 vty_out(vty
, "no ipv6 forwarding\n");
2543 vty_out(vty
, "!\n");
2547 /* IP node for static routes. */
2548 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2549 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2550 /* table node for routing tables. */
2551 static struct cmd_node table_node
= {TABLE_NODE
,
2552 "", /* This node has no interface. */
2554 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2555 "", /* This node has no interface. */
2559 void zebra_vty_init(void)
2561 /* Install configuration write function. */
2562 install_node(&table_node
, config_write_table
);
2563 install_node(&forwarding_node
, config_write_forwarding
);
2565 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2566 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2567 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2568 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2571 install_element(VIEW_NODE
, &show_table_cmd
);
2572 install_element(CONFIG_NODE
, &config_table_cmd
);
2573 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2574 #endif /* HAVE_NETLINK */
2576 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2577 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2578 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2581 zebra_route_map_init();
2583 install_node(&ip_node
, zebra_ip_config
);
2584 install_node(&protocol_node
, config_write_protocol
);
2586 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2587 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2589 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2590 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2592 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2593 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2594 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2595 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2596 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2597 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2599 install_element(VIEW_NODE
, &show_vrf_cmd
);
2600 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2601 install_element(VIEW_NODE
, &show_route_cmd
);
2602 install_element(VIEW_NODE
, &show_route_table_cmd
);
2603 if (vrf_is_backend_netns())
2604 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2605 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2606 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2607 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2608 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2609 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2610 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2612 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2613 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2615 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2616 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2617 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2618 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2619 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2621 /* Commands for VRF */
2622 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2624 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2625 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2626 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2627 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2628 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2629 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2630 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2631 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2632 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2633 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2634 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2635 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2636 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2637 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2638 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2639 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2640 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2641 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2643 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2644 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2646 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2647 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2648 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2649 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);