2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "zebra_memory.h"
35 #include "srcdest_table.h"
38 #include "zebra/zebra_router.h"
39 #include "zebra/zserv.h"
40 #include "zebra/zebra_vrf.h"
41 #include "zebra/zebra_mpls.h"
42 #include "zebra/zebra_rnh.h"
43 #include "zebra/redistribute.h"
44 #include "zebra/zebra_routemap.h"
46 #include "zebra/zebra_vxlan.h"
47 #ifndef VTYSH_EXTRACT_PL
48 #include "zebra/zebra_vty_clippy.c"
50 #include "zebra/zserv.h"
51 #include "zebra/router-id.h"
52 #include "zebra/ipforward.h"
53 #include "zebra/zebra_vxlan_private.h"
54 #include "zebra/zebra_pbr.h"
56 extern int allow_delete
;
58 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
59 safi_t safi
, bool use_fib
, bool use_json
,
61 const struct prefix
*longer_prefix_p
,
62 bool supernets_only
, int type
,
63 unsigned short ospf_instance_id
);
64 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
66 static void vty_show_ip_route_summary(struct vty
*vty
,
67 struct route_table
*table
);
68 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
69 struct route_table
*table
);
71 DEFUN (ip_multicast_mode
,
72 ip_multicast_mode_cmd
,
73 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
76 "RPF lookup behavior\n"
77 "Lookup in unicast RIB only\n"
78 "Lookup in multicast RIB only\n"
79 "Try multicast RIB first, fall back to unicast RIB\n"
80 "Lookup both, use entry with lower distance\n"
81 "Lookup both, use entry with longer prefix\n")
83 char *mode
= argv
[3]->text
;
85 if (strmatch(mode
, "urib-only"))
86 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
87 else if (strmatch(mode
, "mrib-only"))
88 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
89 else if (strmatch(mode
, "mrib-then-urib"))
90 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
91 else if (strmatch(mode
, "lower-distance"))
92 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
93 else if (strmatch(mode
, "longer-prefix"))
94 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
96 vty_out(vty
, "Invalid mode specified\n");
97 return CMD_WARNING_CONFIG_FAILED
;
103 DEFUN (no_ip_multicast_mode
,
104 no_ip_multicast_mode_cmd
,
105 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
108 "Multicast options\n"
109 "RPF lookup behavior\n"
110 "Lookup in unicast RIB only\n"
111 "Lookup in multicast RIB only\n"
112 "Try multicast RIB first, fall back to unicast RIB\n"
113 "Lookup both, use entry with lower distance\n"
114 "Lookup both, use entry with longer prefix\n")
116 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
123 "show ip rpf [json]",
126 "Display RPF information for multicast source\n"
129 bool uj
= use_json(argc
, argv
);
130 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
131 false, uj
, 0, NULL
, false, 0, 0);
134 DEFUN (show_ip_rpf_addr
,
135 show_ip_rpf_addr_cmd
,
136 "show ip rpf A.B.C.D",
139 "Display RPF information for multicast source\n"
140 "IP multicast source address (e.g. 10.0.0.0)\n")
144 struct route_node
*rn
;
145 struct route_entry
*re
;
148 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
150 vty_out(vty
, "%% Malformed address\n");
154 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
157 vty_show_ip_route_detail(vty
, rn
, 1);
159 vty_out(vty
, "%% No match for RPF lookup\n");
164 /* New RIB. Detailed information for IPv4 route. */
165 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
168 struct route_entry
*re
;
169 struct nexthop
*nexthop
;
170 char buf
[SRCDEST2STR_BUFFER
];
171 struct zebra_vrf
*zvrf
;
173 RNODE_FOREACH_RE (rn
, re
) {
174 const char *mcast_info
= "";
176 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
177 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
178 ? " using Multicast RIB"
179 : " using Unicast RIB";
182 vty_out(vty
, "Routing entry for %s%s\n",
183 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
184 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
186 vty_out(vty
, "[%d]", re
->instance
);
188 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
191 vty_out(vty
, ", tag %u", re
->tag
);
192 #if defined(SUPPORT_REALMS)
193 if (re
->tag
> 0 && re
->tag
<= 255)
194 vty_out(vty
, "(realm)");
198 vty_out(vty
, ", mtu %u", re
->mtu
);
199 if (re
->vrf_id
!= VRF_DEFAULT
) {
200 zvrf
= vrf_info_lookup(re
->vrf_id
);
201 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
203 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
204 vty_out(vty
, ", best");
211 uptime
-= re
->uptime
;
212 tm
= gmtime(&uptime
);
214 vty_out(vty
, " Last update ");
216 if (uptime
< ONE_DAY_SECOND
)
217 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
219 else if (uptime
< ONE_WEEK_SECOND
)
220 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
223 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
224 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
226 vty_out(vty
, " ago\n");
228 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
231 vty_out(vty
, " %c%s",
232 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
233 ? CHECK_FLAG(nexthop
->flags
,
234 NEXTHOP_FLAG_DUPLICATE
)
238 nexthop
->rparent
? " " : "");
240 switch (nexthop
->type
) {
241 case NEXTHOP_TYPE_IPV4
:
242 case NEXTHOP_TYPE_IPV4_IFINDEX
:
244 inet_ntoa(nexthop
->gate
.ipv4
));
245 if (nexthop
->ifindex
)
246 vty_out(vty
, ", via %s",
251 case NEXTHOP_TYPE_IPV6
:
252 case NEXTHOP_TYPE_IPV6_IFINDEX
:
254 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
256 if (nexthop
->ifindex
)
257 vty_out(vty
, ", via %s",
262 case NEXTHOP_TYPE_IFINDEX
:
263 vty_out(vty
, " directly connected, %s",
264 ifindex2ifname(nexthop
->ifindex
,
267 case NEXTHOP_TYPE_BLACKHOLE
:
268 vty_out(vty
, " unreachable");
269 switch (nexthop
->bh_type
) {
270 case BLACKHOLE_REJECT
:
271 vty_out(vty
, " (ICMP unreachable)");
273 case BLACKHOLE_ADMINPROHIB
:
275 " (ICMP admin-prohibited)");
278 vty_out(vty
, " (blackhole)");
280 case BLACKHOLE_UNSPEC
:
288 if ((re
->vrf_id
!= nexthop
->vrf_id
)
289 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
291 vrf_lookup_by_id(nexthop
->vrf_id
);
294 vty_out(vty
, "(vrf %s)", vrf
->name
);
296 vty_out(vty
, "(vrf UNKNOWN)");
299 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
300 vty_out(vty
, " (duplicate nexthop removed)");
302 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
303 vty_out(vty
, " inactive");
305 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
306 vty_out(vty
, " onlink");
308 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
309 vty_out(vty
, " (recursive)");
311 switch (nexthop
->type
) {
312 case NEXTHOP_TYPE_IPV4
:
313 case NEXTHOP_TYPE_IPV4_IFINDEX
:
314 if (nexthop
->src
.ipv4
.s_addr
) {
315 if (inet_ntop(AF_INET
,
317 addrstr
, sizeof addrstr
))
318 vty_out(vty
, ", src %s",
322 case NEXTHOP_TYPE_IPV6
:
323 case NEXTHOP_TYPE_IPV6_IFINDEX
:
324 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
326 if (inet_ntop(AF_INET6
,
328 addrstr
, sizeof addrstr
))
329 vty_out(vty
, ", src %s",
338 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
340 /* Label information */
341 if (nexthop
->nh_label
342 && nexthop
->nh_label
->num_labels
) {
343 vty_out(vty
, ", label %s",
345 nexthop
->nh_label
->num_labels
,
346 nexthop
->nh_label
->label
, buf
,
356 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
357 struct route_entry
*re
, json_object
*json
)
359 struct nexthop
*nexthop
;
361 char buf
[SRCDEST2STR_BUFFER
];
362 json_object
*json_nexthops
= NULL
;
363 json_object
*json_nexthop
= NULL
;
364 json_object
*json_route
= NULL
;
365 json_object
*json_labels
= NULL
;
370 uptime
-= re
->uptime
;
371 tm
= gmtime(&uptime
);
374 json_route
= json_object_new_object();
375 json_nexthops
= json_object_new_array();
377 json_object_string_add(json_route
, "prefix",
378 srcdest_rnode2str(rn
, buf
, sizeof buf
));
379 json_object_string_add(json_route
, "protocol",
380 zebra_route_string(re
->type
));
383 json_object_int_add(json_route
, "instance",
387 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
389 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
390 json_object_boolean_true_add(json_route
, "selected");
392 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
393 json_object_int_add(json_route
, "distance",
395 json_object_int_add(json_route
, "metric", re
->metric
);
399 json_object_int_add(json_route
, "tag", re
->tag
);
401 json_object_int_add(json_route
, "internalStatus",
403 json_object_int_add(json_route
, "internalFlags",
405 if (uptime
< ONE_DAY_SECOND
)
406 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
408 else if (uptime
< ONE_WEEK_SECOND
)
409 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
412 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
413 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
416 json_object_string_add(json_route
, "uptime", buf
);
418 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
419 json_nexthop
= json_object_new_object();
421 json_object_int_add(json_nexthop
, "flags",
424 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
425 json_object_boolean_true_add(json_nexthop
,
428 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
429 json_object_boolean_true_add(json_nexthop
,
432 switch (nexthop
->type
) {
433 case NEXTHOP_TYPE_IPV4
:
434 case NEXTHOP_TYPE_IPV4_IFINDEX
:
435 json_object_string_add(
437 inet_ntoa(nexthop
->gate
.ipv4
));
438 json_object_string_add(json_nexthop
, "afi",
441 if (nexthop
->ifindex
) {
442 json_object_int_add(json_nexthop
,
445 json_object_string_add(
446 json_nexthop
, "interfaceName",
452 case NEXTHOP_TYPE_IPV6
:
453 case NEXTHOP_TYPE_IPV6_IFINDEX
:
454 json_object_string_add(
456 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
458 json_object_string_add(json_nexthop
, "afi",
461 if (nexthop
->ifindex
) {
462 json_object_int_add(json_nexthop
,
465 json_object_string_add(
466 json_nexthop
, "interfaceName",
473 case NEXTHOP_TYPE_IFINDEX
:
474 json_object_boolean_true_add(
475 json_nexthop
, "directlyConnected");
476 json_object_int_add(json_nexthop
,
479 json_object_string_add(
480 json_nexthop
, "interfaceName",
481 ifindex2ifname(nexthop
->ifindex
,
484 case NEXTHOP_TYPE_BLACKHOLE
:
485 json_object_boolean_true_add(json_nexthop
,
487 switch (nexthop
->bh_type
) {
488 case BLACKHOLE_REJECT
:
489 json_object_boolean_true_add(
490 json_nexthop
, "reject");
492 case BLACKHOLE_ADMINPROHIB
:
493 json_object_boolean_true_add(
498 json_object_boolean_true_add(
499 json_nexthop
, "blackhole");
501 case BLACKHOLE_UNSPEC
:
509 if ((nexthop
->vrf_id
!= re
->vrf_id
)
510 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
512 vrf_lookup_by_id(nexthop
->vrf_id
);
514 json_object_string_add(json_nexthop
, "vrf",
517 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
518 json_object_boolean_true_add(json_nexthop
,
521 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
522 json_object_boolean_true_add(json_nexthop
,
525 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
526 json_object_boolean_true_add(json_nexthop
,
529 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
530 json_object_boolean_true_add(json_nexthop
,
533 switch (nexthop
->type
) {
534 case NEXTHOP_TYPE_IPV4
:
535 case NEXTHOP_TYPE_IPV4_IFINDEX
:
536 if (nexthop
->src
.ipv4
.s_addr
) {
537 if (inet_ntop(AF_INET
,
538 &nexthop
->src
.ipv4
, buf
,
540 json_object_string_add(
541 json_nexthop
, "source",
545 case NEXTHOP_TYPE_IPV6
:
546 case NEXTHOP_TYPE_IPV6_IFINDEX
:
547 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
549 if (inet_ntop(AF_INET6
,
550 &nexthop
->src
.ipv6
, buf
,
552 json_object_string_add(
553 json_nexthop
, "source",
561 if (nexthop
->nh_label
562 && nexthop
->nh_label
->num_labels
) {
563 json_labels
= json_object_new_array();
565 for (int label_index
= 0;
567 < nexthop
->nh_label
->num_labels
;
569 json_object_array_add(
572 nexthop
->nh_label
->label
575 json_object_object_add(json_nexthop
, "labels",
579 json_object_array_add(json_nexthops
, json_nexthop
);
582 json_object_object_add(json_route
, "nexthops", json_nexthops
);
583 json_object_array_add(json
, json_route
);
587 /* Nexthop information. */
588 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
589 if (nexthop
== re
->ng
.nexthop
) {
590 /* Prefix information. */
591 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
593 len
+= vty_out(vty
, "[%d]", re
->instance
);
596 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
599 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
602 srcdest_rnode2str(rn
, buf
, sizeof buf
));
604 /* Distance and metric display. */
605 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
606 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
609 vty_out(vty
, " %c%*c",
610 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
611 ? CHECK_FLAG(nexthop
->flags
,
612 NEXTHOP_FLAG_DUPLICATE
)
616 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
619 switch (nexthop
->type
) {
620 case NEXTHOP_TYPE_IPV4
:
621 case NEXTHOP_TYPE_IPV4_IFINDEX
:
622 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
623 if (nexthop
->ifindex
)
625 ifindex2ifname(nexthop
->ifindex
,
628 case NEXTHOP_TYPE_IPV6
:
629 case NEXTHOP_TYPE_IPV6_IFINDEX
:
630 vty_out(vty
, " via %s",
631 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
633 if (nexthop
->ifindex
)
635 ifindex2ifname(nexthop
->ifindex
,
639 case NEXTHOP_TYPE_IFINDEX
:
640 vty_out(vty
, " is directly connected, %s",
641 ifindex2ifname(nexthop
->ifindex
,
644 case NEXTHOP_TYPE_BLACKHOLE
:
645 vty_out(vty
, " unreachable");
646 switch (nexthop
->bh_type
) {
647 case BLACKHOLE_REJECT
:
648 vty_out(vty
, " (ICMP unreachable)");
650 case BLACKHOLE_ADMINPROHIB
:
651 vty_out(vty
, " (ICMP admin-prohibited)");
654 vty_out(vty
, " (blackhole)");
656 case BLACKHOLE_UNSPEC
:
664 if ((nexthop
->vrf_id
!= re
->vrf_id
)
665 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
666 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
669 vty_out(vty
, "(vrf %s)", vrf
->name
);
671 vty_out(vty
, "(vrf UNKNOWN)");
674 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
675 vty_out(vty
, " inactive");
677 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
678 vty_out(vty
, " onlink");
680 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
681 vty_out(vty
, " (recursive)");
683 switch (nexthop
->type
) {
684 case NEXTHOP_TYPE_IPV4
:
685 case NEXTHOP_TYPE_IPV4_IFINDEX
:
686 if (nexthop
->src
.ipv4
.s_addr
) {
687 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
689 vty_out(vty
, ", src %s", buf
);
692 case NEXTHOP_TYPE_IPV6
:
693 case NEXTHOP_TYPE_IPV6_IFINDEX
:
694 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
695 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
697 vty_out(vty
, ", src %s", buf
);
704 /* Label information */
705 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
706 vty_out(vty
, ", label %s",
707 mpls_label2str(nexthop
->nh_label
->num_labels
,
708 nexthop
->nh_label
->label
, buf
,
712 if (uptime
< ONE_DAY_SECOND
)
713 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
714 tm
->tm_min
, tm
->tm_sec
);
715 else if (uptime
< ONE_WEEK_SECOND
)
716 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
717 tm
->tm_hour
, tm
->tm_min
);
719 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
720 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
726 static void vty_show_ip_route_detail_json(struct vty
*vty
,
727 struct route_node
*rn
)
729 json_object
*json
= NULL
;
730 json_object
*json_prefix
= NULL
;
731 struct route_entry
*re
;
734 json
= json_object_new_object();
735 json_prefix
= json_object_new_array();
737 RNODE_FOREACH_RE (rn
, re
) {
738 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
741 prefix2str(&rn
->p
, buf
, sizeof(buf
));
742 json_object_object_add(json
, buf
, json_prefix
);
743 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
744 json
, JSON_C_TO_STRING_PRETTY
));
745 json_object_free(json
);
748 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
749 struct route_table
*table
, afi_t afi
,
750 bool use_fib
, route_tag_t tag
,
751 const struct prefix
*longer_prefix_p
,
752 bool supernets_only
, int type
,
753 unsigned short ospf_instance_id
, bool use_json
)
755 struct route_node
*rn
;
756 struct route_entry
*re
;
759 json_object
*json
= NULL
;
760 json_object
*json_prefix
= NULL
;
765 json
= json_object_new_object();
767 /* Show all routes. */
768 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
769 dest
= rib_dest_from_rnode(rn
);
771 RNODE_FOREACH_RE (rn
, re
) {
772 if (use_fib
&& re
!= dest
->selected_fib
)
775 if (tag
&& re
->tag
!= tag
)
779 && !prefix_match(longer_prefix_p
, &rn
->p
))
782 /* This can only be true when the afi is IPv4 */
783 if (supernets_only
) {
784 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
786 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
789 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
792 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
796 if (type
&& re
->type
!= type
)
800 && (re
->type
!= ZEBRA_ROUTE_OSPF
801 || re
->instance
!= ospf_instance_id
))
806 json_prefix
= json_object_new_array();
811 SHOW_ROUTE_V4_HEADER
);
814 SHOW_ROUTE_V6_HEADER
);
816 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
817 vty_out(vty
, "\nVRF %s:\n",
824 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
828 prefix2str(&rn
->p
, buf
, sizeof(buf
));
829 json_object_object_add(json
, buf
, json_prefix
);
835 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
836 JSON_C_TO_STRING_PRETTY
));
837 json_object_free(json
);
841 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
842 safi_t safi
, bool use_fib
, bool use_json
,
844 const struct prefix
*longer_prefix_p
,
845 bool supernets_only
, int type
,
846 unsigned short ospf_instance_id
)
848 struct route_table
*table
;
849 struct zebra_vrf
*zvrf
= NULL
;
851 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
853 vty_out(vty
, "{}\n");
855 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
859 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
861 vty_out(vty
, "{}\n");
863 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
867 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
870 vty_out(vty
, "{}\n");
874 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
875 longer_prefix_p
, supernets_only
, type
,
876 ospf_instance_id
, use_json
);
881 DEFPY (show_route_table
,
882 show_route_table_cmd
,
883 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
889 "The table number to display, if available\n"
892 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
893 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
894 struct route_table
*t
;
896 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
898 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
904 DEFPY (show_route_table_vrf
,
905 show_route_table_vrf_cmd
,
906 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
912 "The table number to display, if available\n"
916 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
917 struct zebra_vrf
*zvrf
;
918 struct route_table
*t
;
919 vrf_id_t vrf_id
= VRF_DEFAULT
;
922 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
923 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
925 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
927 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
935 "show ip nht [vrf NAME]",
938 "IP nexthop tracking table\n"
942 vrf_id_t vrf_id
= VRF_DEFAULT
;
945 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
947 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
952 DEFUN (show_ip_nht_vrf_all
,
953 show_ip_nht_vrf_all_cmd
,
954 "show ip nht vrf all",
957 "IP nexthop tracking table\n"
958 VRF_ALL_CMD_HELP_STR
)
961 struct zebra_vrf
*zvrf
;
963 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
964 if ((zvrf
= vrf
->info
) != NULL
) {
965 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
966 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
973 DEFUN (show_ipv6_nht
,
975 "show ipv6 nht [vrf NAME]",
978 "IPv6 nexthop tracking table\n"
982 vrf_id_t vrf_id
= VRF_DEFAULT
;
985 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
987 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
992 DEFUN (show_ipv6_nht_vrf_all
,
993 show_ipv6_nht_vrf_all_cmd
,
994 "show ipv6 nht vrf all",
997 "IPv6 nexthop tracking table\n"
998 VRF_ALL_CMD_HELP_STR
)
1001 struct zebra_vrf
*zvrf
;
1003 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1004 if ((zvrf
= vrf
->info
) != NULL
) {
1005 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1006 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1013 DEFUN (ip_nht_default_route
,
1014 ip_nht_default_route_cmd
,
1015 "ip nht resolve-via-default",
1017 "Filter Next Hop tracking route resolution\n"
1018 "Resolve via default route\n")
1020 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1025 if (zebra_rnh_ip_default_route
)
1028 zebra_rnh_ip_default_route
= 1;
1030 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1034 DEFUN (no_ip_nht_default_route
,
1035 no_ip_nht_default_route_cmd
,
1036 "no ip nht resolve-via-default",
1039 "Filter Next Hop tracking route resolution\n"
1040 "Resolve via default route\n")
1042 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1047 if (!zebra_rnh_ip_default_route
)
1050 zebra_rnh_ip_default_route
= 0;
1051 zebra_evaluate_rnh(zvrf
, 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 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1067 if (zebra_rnh_ipv6_default_route
)
1070 zebra_rnh_ipv6_default_route
= 1;
1071 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1075 DEFUN (no_ipv6_nht_default_route
,
1076 no_ipv6_nht_default_route_cmd
,
1077 "no ipv6 nht resolve-via-default",
1080 "Filter Next Hop tracking route resolution\n"
1081 "Resolve via default route\n")
1084 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1089 if (!zebra_rnh_ipv6_default_route
)
1092 zebra_rnh_ipv6_default_route
= 0;
1093 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1101 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1104 |A.B.C.D/M$prefix longer-prefixes\
1105 |supernets-only$supernets_only\
1108 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1109 |ospf$type_str (1-65535)$ospf_instance_id\
1111 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1114 |X:X::X:X/M$prefix longer-prefixes\
1116 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1121 "IP forwarding table\n"
1122 "IP routing table\n"
1123 VRF_FULL_CMD_HELP_STR
1124 "Show only routes with tag\n"
1126 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1127 "Show route matching the specified Network/Mask pair only\n"
1128 "Show supernet entries only\n"
1129 FRR_IP_REDIST_HELP_STR_ZEBRA
1130 "Open Shortest Path First (OSPFv2)\n"
1133 "IP forwarding table\n"
1134 "IP routing table\n"
1135 VRF_FULL_CMD_HELP_STR
1136 "Show only routes with tag\n"
1139 "Show route matching the specified Network/Mask pair only\n"
1140 FRR_IP6_REDIST_HELP_STR_ZEBRA
1143 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1148 type
= proto_redistnum(afi
, type_str
);
1150 vty_out(vty
, "Unknown route type\n");
1156 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1157 struct zebra_vrf
*zvrf
;
1158 struct route_table
*table
;
1160 if ((zvrf
= vrf
->info
) == NULL
1161 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1165 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1166 !!json
, tag
, prefix_str
? prefix
: NULL
,
1167 !!supernets_only
, type
, ospf_instance_id
);
1170 vrf_id_t vrf_id
= VRF_DEFAULT
;
1173 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1174 vrf
= vrf_lookup_by_id(vrf_id
);
1175 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1176 !!json
, tag
, prefix_str
? prefix
: NULL
,
1177 !!supernets_only
, type
, ospf_instance_id
);
1183 DEFPY (show_route_detail
,
1184 show_route_detail_cmd
,
1187 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1192 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1201 "IP routing table\n"
1202 VRF_FULL_CMD_HELP_STR
1203 "Network in the IP routing table to display\n"
1204 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1206 "IP routing table\n"
1207 VRF_FULL_CMD_HELP_STR
1212 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1213 struct route_table
*table
;
1215 struct route_node
*rn
;
1218 prefix_str
= address_str
;
1219 if (str2prefix(prefix_str
, &p
) < 0) {
1220 vty_out(vty
, "%% Malformed address\n");
1226 struct zebra_vrf
*zvrf
;
1228 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1229 if ((zvrf
= vrf
->info
) == NULL
1230 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1233 rn
= route_node_match(table
, &p
);
1236 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1237 route_unlock_node(rn
);
1242 vty_show_ip_route_detail_json(vty
, rn
);
1244 vty_show_ip_route_detail(vty
, rn
, 0);
1246 route_unlock_node(rn
);
1249 vrf_id_t vrf_id
= VRF_DEFAULT
;
1252 VRF_GET_ID(vrf_id
, vrf_name
, false);
1254 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1258 rn
= route_node_match(table
, &p
);
1260 vty_out(vty
, "%% Network not in table\n");
1263 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1264 vty_out(vty
, "%% Network not in table\n");
1265 route_unlock_node(rn
);
1270 vty_show_ip_route_detail_json(vty
, rn
);
1272 vty_show_ip_route_detail(vty
, rn
, 0);
1274 route_unlock_node(rn
);
1280 DEFPY (show_route_summary
,
1281 show_route_summary_cmd
,
1284 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1285 summary [prefix$prefix]\
1286 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1287 summary [prefix$prefix]\
1291 "IP routing table\n"
1292 VRF_FULL_CMD_HELP_STR
1293 "Summary of all routes\n"
1296 "IP routing table\n"
1297 VRF_FULL_CMD_HELP_STR
1298 "Summary of all routes\n"
1301 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1302 struct route_table
*table
;
1306 struct zebra_vrf
*zvrf
;
1308 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1309 if ((zvrf
= vrf
->info
) == NULL
1310 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1314 vty_show_ip_route_summary_prefix(vty
, table
);
1316 vty_show_ip_route_summary(vty
, table
);
1319 vrf_id_t vrf_id
= VRF_DEFAULT
;
1322 VRF_GET_ID(vrf_id
, vrf_name
, false);
1324 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1329 vty_show_ip_route_summary_prefix(vty
, table
);
1331 vty_show_ip_route_summary(vty
, table
);
1337 static void vty_show_ip_route_summary(struct vty
*vty
,
1338 struct route_table
*table
)
1340 struct route_node
*rn
;
1341 struct route_entry
*re
;
1342 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1343 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1344 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1345 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1349 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1350 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1351 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1352 RNODE_FOREACH_RE (rn
, re
) {
1353 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1354 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1356 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1358 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1360 rib_cnt
[re
->type
]++;
1362 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1363 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1366 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1368 fib_cnt
[re
->type
]++;
1372 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1373 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1375 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1376 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1377 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1378 if (i
== ZEBRA_ROUTE_BGP
) {
1379 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1380 rib_cnt
[ZEBRA_ROUTE_BGP
],
1381 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1382 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1383 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1384 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1386 vty_out(vty
, "%-20s %-20d %-20d \n",
1387 zebra_route_string(i
), rib_cnt
[i
],
1392 vty_out(vty
, "------\n");
1393 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1394 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1399 * Implementation of the ip route summary prefix command.
1401 * This command prints the primary prefixes that have been installed by various
1402 * protocols on the box.
1405 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1406 struct route_table
*table
)
1408 struct route_node
*rn
;
1409 struct route_entry
*re
;
1410 struct nexthop
*nexthop
;
1411 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1412 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1413 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1414 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1418 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1419 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1420 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1421 RNODE_FOREACH_RE (rn
, re
) {
1424 * In case of ECMP, count only once.
1427 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1428 nexthop
= nexthop
->next
) {
1430 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1431 rib_cnt
[re
->type
]++;
1432 if (CHECK_FLAG(nexthop
->flags
,
1433 NEXTHOP_FLAG_FIB
)) {
1434 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1435 fib_cnt
[re
->type
]++;
1437 if (re
->type
== ZEBRA_ROUTE_BGP
1438 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1439 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1440 if (CHECK_FLAG(nexthop
->flags
,
1442 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1447 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1448 "Prefix Routes", "FIB",
1449 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1451 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1452 if (rib_cnt
[i
] > 0) {
1453 if (i
== ZEBRA_ROUTE_BGP
) {
1454 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1455 rib_cnt
[ZEBRA_ROUTE_BGP
]
1456 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1457 fib_cnt
[ZEBRA_ROUTE_BGP
]
1458 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1459 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1460 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1461 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1463 vty_out(vty
, "%-20s %-20d %-20d \n",
1464 zebra_route_string(i
), rib_cnt
[i
],
1469 vty_out(vty
, "------\n");
1470 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1471 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1476 * Show IPv6 mroute command.Used to dump
1477 * the Multicast routing table.
1479 DEFUN (show_ipv6_mroute
,
1480 show_ipv6_mroute_cmd
,
1481 "show ipv6 mroute [vrf NAME]",
1484 "IPv6 Multicast routing table\n"
1487 struct route_table
*table
;
1488 struct route_node
*rn
;
1489 struct route_entry
*re
;
1491 vrf_id_t vrf_id
= VRF_DEFAULT
;
1494 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1496 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1500 /* Show all IPv6 route. */
1501 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1502 RNODE_FOREACH_RE (rn
, re
) {
1504 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1507 vty_show_ip_route(vty
, rn
, re
, NULL
);
1512 DEFUN (show_ipv6_mroute_vrf_all
,
1513 show_ipv6_mroute_vrf_all_cmd
,
1514 "show ipv6 mroute vrf all",
1517 "IPv6 Multicast routing table\n"
1518 VRF_ALL_CMD_HELP_STR
)
1520 struct route_table
*table
;
1521 struct route_node
*rn
;
1522 struct route_entry
*re
;
1524 struct zebra_vrf
*zvrf
;
1527 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1528 if ((zvrf
= vrf
->info
) == NULL
1529 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1532 /* Show all IPv6 route. */
1533 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1534 RNODE_FOREACH_RE (rn
, re
) {
1536 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1539 vty_show_ip_route(vty
, rn
, re
, NULL
);
1545 DEFUN (allow_external_route_update
,
1546 allow_external_route_update_cmd
,
1547 "allow-external-route-update",
1548 "Allow FRR routes to be overwritten by external processes\n")
1555 DEFUN (no_allow_external_route_update
,
1556 no_allow_external_route_update_cmd
,
1557 "no allow-external-route-update",
1559 "Allow FRR routes to be overwritten by external processes\n")
1574 struct zebra_vrf
*zvrf
;
1576 if (vrf_is_backend_netns())
1577 vty_out(vty
, "netns-based vrfs\n");
1579 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1580 if (!(zvrf
= vrf
->info
))
1582 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1585 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1586 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1587 vty_out(vty
, "inactive");
1588 else if (zvrf_ns_name(zvrf
))
1589 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1590 zvrf_ns_name(zvrf
));
1592 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1594 if (vrf_is_user_cfged(vrf
))
1595 vty_out(vty
, " (configured)");
1602 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1603 default_vrf_vni_mapping_cmd
,
1604 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1605 "VNI corresponding to the DEFAULT VRF\n"
1607 "Prefix routes only \n")
1610 char err
[ERR_STR_SZ
];
1611 struct zebra_vrf
*zvrf
= NULL
;
1612 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1615 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1622 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1625 vty_out(vty
, "%s\n", err
);
1632 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1633 no_default_vrf_vni_mapping_cmd
,
1634 "no vni " CMD_VNI_RANGE
,
1636 "VNI corresponding to DEFAULT VRF\n"
1640 char err
[ERR_STR_SZ
];
1641 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1642 struct zebra_vrf
*zvrf
= NULL
;
1644 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1648 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1650 vty_out(vty
, "%s\n", err
);
1657 DEFUN (vrf_vni_mapping
,
1658 vrf_vni_mapping_cmd
,
1659 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1660 "VNI corresponding to tenant VRF\n"
1662 "prefix-routes-only\n")
1667 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1668 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1669 char err
[ERR_STR_SZ
];
1677 /* Mark as having FRR configuration */
1678 vrf_set_user_cfged(vrf
);
1679 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1682 vty_out(vty
, "%s\n", err
);
1689 DEFUN (no_vrf_vni_mapping
,
1690 no_vrf_vni_mapping_cmd
,
1691 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1693 "VNI corresponding to tenant VRF\n"
1695 "prefix-routes-only\n")
1699 char err
[ERR_STR_SZ
];
1700 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1702 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1710 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1711 ERR_STR_SZ
, filter
, 0);
1713 vty_out(vty
, "%s\n", err
);
1717 /* If no other FRR config for this VRF, mark accordingly. */
1718 if (!zebra_vrf_has_config(zvrf
))
1719 vrf_reset_user_cfged(vrf
);
1725 DEFUN (show_vrf_vni
,
1727 "show vrf vni [json]",
1734 struct zebra_vrf
*zvrf
;
1735 json_object
*json
= NULL
;
1736 json_object
*json_vrfs
= NULL
;
1737 bool uj
= use_json(argc
, argv
);
1740 json
= json_object_new_object();
1741 json_vrfs
= json_object_new_array();
1745 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1746 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1748 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1753 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1757 json_object_object_add(json
, "vrfs", json_vrfs
);
1758 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1759 json
, JSON_C_TO_STRING_PRETTY
));
1760 json_object_free(json
);
1766 DEFUN (show_evpn_global
,
1767 show_evpn_global_cmd
,
1773 bool uj
= use_json(argc
, argv
);
1775 zebra_vxlan_print_evpn(vty
, uj
);
1779 DEFUN (show_evpn_vni
,
1781 "show evpn vni [json]",
1784 "VxLAN Network Identifier\n"
1787 struct zebra_vrf
*zvrf
;
1788 bool uj
= use_json(argc
, argv
);
1790 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1791 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1795 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1796 "show evpn vni detail [json]",
1799 "VxLAN Network Identifier\n"
1800 "Detailed Information On Each VNI\n"
1803 struct zebra_vrf
*zvrf
;
1804 bool uj
= use_json(argc
, argv
);
1806 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1807 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1811 DEFUN (show_evpn_vni_vni
,
1812 show_evpn_vni_vni_cmd
,
1813 "show evpn vni " CMD_VNI_RANGE
"[json]",
1816 "VxLAN Network Identifier\n"
1820 struct zebra_vrf
*zvrf
;
1822 bool uj
= use_json(argc
, argv
);
1824 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1825 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1826 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1830 DEFUN (show_evpn_rmac_vni_mac
,
1831 show_evpn_rmac_vni_mac_cmd
,
1832 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1839 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1844 bool uj
= use_json(argc
, argv
);
1846 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1847 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1848 vty_out(vty
, "%% Malformed MAC address\n");
1851 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1855 DEFUN (show_evpn_rmac_vni
,
1856 show_evpn_rmac_vni_cmd
,
1857 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1866 bool uj
= use_json(argc
, argv
);
1868 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1869 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1874 DEFUN (show_evpn_rmac_vni_all
,
1875 show_evpn_rmac_vni_all_cmd
,
1876 "show evpn rmac vni all [json]",
1884 bool uj
= use_json(argc
, argv
);
1886 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1891 DEFUN (show_evpn_nh_vni_ip
,
1892 show_evpn_nh_vni_ip_cmd
,
1893 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1900 "Host address (ipv4 or ipv6)\n"
1905 bool uj
= use_json(argc
, argv
);
1907 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1908 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1910 vty_out(vty
, "%% Malformed Neighbor address\n");
1913 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1918 DEFUN (show_evpn_nh_vni
,
1919 show_evpn_nh_vni_cmd
,
1920 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1929 bool uj
= use_json(argc
, argv
);
1931 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1932 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1937 DEFUN (show_evpn_nh_vni_all
,
1938 show_evpn_nh_vni_all_cmd
,
1939 "show evpn next-hops vni all [json]",
1947 bool uj
= use_json(argc
, argv
);
1949 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1954 DEFUN (show_evpn_mac_vni
,
1955 show_evpn_mac_vni_cmd
,
1956 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1960 "VxLAN Network Identifier\n"
1964 struct zebra_vrf
*zvrf
;
1966 bool uj
= use_json(argc
, argv
);
1968 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1969 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1970 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1974 DEFUN (show_evpn_mac_vni_all
,
1975 show_evpn_mac_vni_all_cmd
,
1976 "show evpn mac vni all [json]",
1980 "VxLAN Network Identifier\n"
1984 struct zebra_vrf
*zvrf
;
1985 bool uj
= use_json(argc
, argv
);
1987 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1988 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
1992 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
1993 "show evpn mac vni all detail [json]",
1997 "VxLAN Network Identifier\n"
1999 "Detailed Information On Each VNI MAC\n"
2002 struct zebra_vrf
*zvrf
;
2003 bool uj
= use_json(argc
, argv
);
2005 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2006 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2010 DEFUN (show_evpn_mac_vni_all_vtep
,
2011 show_evpn_mac_vni_all_vtep_cmd
,
2012 "show evpn mac vni all vtep A.B.C.D [json]",
2016 "VxLAN Network Identifier\n"
2019 "Remote VTEP IP address\n"
2022 struct zebra_vrf
*zvrf
;
2023 struct in_addr vtep_ip
;
2024 bool uj
= use_json(argc
, argv
);
2026 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2028 vty_out(vty
, "%% Malformed VTEP IP address\n");
2031 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2032 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2038 DEFUN (show_evpn_mac_vni_mac
,
2039 show_evpn_mac_vni_mac_cmd
,
2040 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2044 "VxLAN Network Identifier\n"
2047 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2051 struct zebra_vrf
*zvrf
;
2054 bool uj
= use_json(argc
, argv
);
2056 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2057 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2058 vty_out(vty
, "%% Malformed MAC address");
2061 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2062 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2066 DEFUN (show_evpn_mac_vni_vtep
,
2067 show_evpn_mac_vni_vtep_cmd
,
2068 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2072 "VxLAN Network Identifier\n"
2075 "Remote VTEP IP address\n"
2078 struct zebra_vrf
*zvrf
;
2080 struct in_addr vtep_ip
;
2081 bool uj
= use_json(argc
, argv
);
2083 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2084 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2086 vty_out(vty
, "%% Malformed VTEP IP address\n");
2090 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2091 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2095 DEFPY (show_evpn_mac_vni_all_dad
,
2096 show_evpn_mac_vni_all_dad_cmd
,
2097 "show evpn mac vni all duplicate [json]",
2101 "VxLAN Network Identifier\n"
2103 "Duplicate address list\n"
2106 struct zebra_vrf
*zvrf
;
2107 bool uj
= use_json(argc
, argv
);
2109 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2110 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2115 DEFPY (show_evpn_mac_vni_dad
,
2116 show_evpn_mac_vni_dad_cmd
,
2117 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2121 "VxLAN Network Identifier\n"
2123 "Duplicate address list\n"
2126 struct zebra_vrf
*zvrf
;
2128 bool uj
= use_json(argc
, argv
);
2130 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2131 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2133 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2138 DEFPY (show_evpn_neigh_vni_dad
,
2139 show_evpn_neigh_vni_dad_cmd
,
2140 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2143 "ARP and ND cache\n"
2144 "VxLAN Network Identifier\n"
2146 "Duplicate address list\n"
2149 struct zebra_vrf
*zvrf
;
2151 bool uj
= use_json(argc
, argv
);
2153 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2154 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2155 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2159 DEFPY (show_evpn_neigh_vni_all_dad
,
2160 show_evpn_neigh_vni_all_dad_cmd
,
2161 "show evpn arp-cache vni all duplicate [json]",
2164 "ARP and ND cache\n"
2165 "VxLAN Network Identifier\n"
2167 "Duplicate address list\n"
2170 struct zebra_vrf
*zvrf
;
2171 bool uj
= use_json(argc
, argv
);
2173 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2174 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2179 DEFUN (show_evpn_neigh_vni
,
2180 show_evpn_neigh_vni_cmd
,
2181 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2184 "ARP and ND cache\n"
2185 "VxLAN Network Identifier\n"
2189 struct zebra_vrf
*zvrf
;
2191 bool uj
= use_json(argc
, argv
);
2193 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2194 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2195 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2199 DEFUN (show_evpn_neigh_vni_all
,
2200 show_evpn_neigh_vni_all_cmd
,
2201 "show evpn arp-cache vni all [json]",
2204 "ARP and ND cache\n"
2205 "VxLAN Network Identifier\n"
2209 struct zebra_vrf
*zvrf
;
2210 bool uj
= use_json(argc
, argv
);
2212 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2213 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2217 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2218 "show evpn arp-cache vni all detail [json]",
2221 "ARP and ND cache\n"
2222 "VxLAN Network Identifier\n"
2224 "Neighbor details for all vnis in detail\n" JSON_STR
)
2226 struct zebra_vrf
*zvrf
;
2227 bool uj
= use_json(argc
, argv
);
2229 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2230 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2234 DEFUN (show_evpn_neigh_vni_neigh
,
2235 show_evpn_neigh_vni_neigh_cmd
,
2236 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2239 "ARP and ND cache\n"
2240 "VxLAN Network Identifier\n"
2243 "Neighbor address (IPv4 or IPv6 address)\n"
2246 struct zebra_vrf
*zvrf
;
2249 bool uj
= use_json(argc
, argv
);
2251 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2252 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2254 vty_out(vty
, "%% Malformed Neighbor address\n");
2257 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2258 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2262 DEFUN (show_evpn_neigh_vni_vtep
,
2263 show_evpn_neigh_vni_vtep_cmd
,
2264 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2267 "ARP and ND cache\n"
2268 "VxLAN Network Identifier\n"
2271 "Remote VTEP IP address\n"
2274 struct zebra_vrf
*zvrf
;
2276 struct in_addr vtep_ip
;
2277 bool uj
= use_json(argc
, argv
);
2279 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2280 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2282 vty_out(vty
, "%% Malformed VTEP IP address\n");
2286 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2287 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2291 /* policy routing contexts */
2292 DEFUN (show_pbr_ipset
,
2294 "show pbr ipset [WORD]",
2296 "Policy-Based Routing\n"
2297 "IPset Context information\n"
2298 "IPset Name information\n")
2302 found
= argv_find(argv
, argc
, "WORD", &idx
);
2304 zebra_pbr_show_ipset_list(vty
, NULL
);
2306 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2310 /* policy routing contexts */
2311 DEFUN (show_pbr_iptable
,
2312 show_pbr_iptable_cmd
,
2313 "show pbr iptable [WORD]",
2315 "Policy-Based Routing\n"
2316 "IPtable Context information\n"
2317 "IPtable Name information\n")
2322 found
= argv_find(argv
, argc
, "WORD", &idx
);
2324 zebra_pbr_show_iptable(vty
, NULL
);
2326 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2330 DEFPY (clear_evpn_dup_addr
,
2331 clear_evpn_dup_addr_cmd
,
2332 "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE
"$vni_val [mac M:A:C$mac_val | ip <A.B.C.D|X:X::X:X>]>",
2335 "Duplicate address \n"
2336 "VxLAN Network Identifier\n"
2340 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2345 struct zebra_vrf
*zvrf
;
2347 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2348 struct ethaddr mac_addr
;
2349 int ret
= CMD_SUCCESS
;
2351 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2353 vni
= strtoul(vni_val
, NULL
, 10);
2356 prefix_str2mac(mac_val
, &mac_addr
);
2357 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2361 if (sockunion_family(ip
) == AF_INET
) {
2362 host_ip
.ipa_type
= IPADDR_V4
;
2363 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2365 host_ip
.ipa_type
= IPADDR_V6
;
2366 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2367 sizeof(struct in6_addr
));
2369 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2373 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2376 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2382 /* Static ip route configuration write function. */
2383 static int zebra_ip_config(struct vty
*vty
)
2387 write
+= zebra_import_table_config(vty
);
2392 DEFUN (ip_zebra_import_table_distance
,
2393 ip_zebra_import_table_distance_cmd
,
2394 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2396 "import routes from non-main kernel table\n"
2397 "kernel routing table id\n"
2398 "Distance for imported routes\n"
2399 "Default distance value\n"
2400 "route-map for filtering\n"
2403 uint32_t table_id
= 0;
2405 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2406 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2408 strmatch(argv
[argc
- 2]->text
, "route-map")
2409 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2413 if (argc
== 7 || (argc
== 5 && !rmap
))
2414 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2416 if (!is_zebra_valid_kernel_table(table_id
)) {
2418 "Invalid routing table ID, %d. Must be in range 1-252\n",
2421 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2425 if (is_zebra_main_routing_table(table_id
)) {
2427 "Invalid routing table ID, %d. Must be non-default table\n",
2430 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2434 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2436 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2441 DEFUN_HIDDEN (zebra_packet_process
,
2442 zebra_packet_process_cmd
,
2443 "zebra zapi-packets (1-10000)",
2446 "Number of packets to process before relinquishing thread\n")
2448 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2450 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2451 memory_order_relaxed
);
2456 DEFUN_HIDDEN (no_zebra_packet_process
,
2457 no_zebra_packet_process_cmd
,
2458 "no zebra zapi-packets [(1-10000)]",
2462 "Number of packets to process before relinquishing thread\n")
2464 atomic_store_explicit(&zebrad
.packets_to_process
,
2465 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2466 memory_order_relaxed
);
2471 DEFUN_HIDDEN (zebra_workqueue_timer
,
2472 zebra_workqueue_timer_cmd
,
2473 "zebra work-queue (0-10000)",
2476 "Time in milliseconds\n")
2478 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2479 zebrad
.ribq
->spec
.hold
= timer
;
2484 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2485 no_zebra_workqueue_timer_cmd
,
2486 "no zebra work-queue [(0-10000)]",
2490 "Time in milliseconds\n")
2492 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2497 DEFUN (no_ip_zebra_import_table
,
2498 no_ip_zebra_import_table_cmd
,
2499 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2502 "import routes from non-main kernel table\n"
2503 "kernel routing table id\n"
2504 "Distance for imported routes\n"
2505 "Default distance value\n"
2506 "route-map for filtering\n"
2509 uint32_t table_id
= 0;
2510 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2512 if (!is_zebra_valid_kernel_table(table_id
)) {
2514 "Invalid routing table ID. Must be in range 1-252\n");
2518 if (is_zebra_main_routing_table(table_id
)) {
2520 "Invalid routing table ID, %d. Must be non-default table\n",
2525 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2528 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2531 static int config_write_protocol(struct vty
*vty
)
2534 vty_out(vty
, "allow-external-route-update\n");
2536 if (zebra_rnh_ip_default_route
)
2537 vty_out(vty
, "ip nht resolve-via-default\n");
2539 if (zebra_rnh_ipv6_default_route
)
2540 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2542 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2543 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2545 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2546 vty_out(vty
, "zebra zapi-packets %u\n",
2547 zebrad
.packets_to_process
);
2549 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2551 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2552 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2553 ipv4_multicast_mode
== MCAST_URIB_ONLY
2555 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2557 : ipv4_multicast_mode
2558 == MCAST_MIX_MRIB_FIRST
2560 : ipv4_multicast_mode
2561 == MCAST_MIX_DISTANCE
2568 /* Display default rtm_table for all clients. */
2573 "default routing table to use for all clients\n")
2575 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2579 DEFUN (config_table
,
2582 "Configure target kernel routing table\n"
2585 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2589 DEFUN (no_config_table
,
2590 no_config_table_cmd
,
2591 "no table [TABLENO]",
2593 "Configure target kernel routing table\n"
2596 zebrad
.rtm_table_default
= 0;
2610 " Route Route Neighbor LSP LSP\n");
2612 "VRF Installs Removals Updates Installs Removals\n");
2614 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2615 struct zebra_vrf
*zvrf
= vrf
->info
;
2617 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2618 " %10" PRIu64
" %10" PRIu64
"\n",
2619 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2620 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2621 zvrf
->lsp_removals
);
2627 DEFUN (ip_forwarding
,
2631 "Turn on IP forwarding\n")
2637 ret
= ipforward_on();
2640 vty_out(vty
, "Can't turn on IP forwarding\n");
2641 return CMD_WARNING_CONFIG_FAILED
;
2647 DEFUN (no_ip_forwarding
,
2648 no_ip_forwarding_cmd
,
2652 "Turn off IP forwarding\n")
2658 ret
= ipforward_off();
2661 vty_out(vty
, "Can't turn off IP forwarding\n");
2662 return CMD_WARNING_CONFIG_FAILED
;
2668 /* Only display ip forwarding is enabled or not. */
2669 DEFUN (show_ip_forwarding
,
2670 show_ip_forwarding_cmd
,
2671 "show ip forwarding",
2674 "IP forwarding status\n")
2681 vty_out(vty
, "IP forwarding is off\n");
2683 vty_out(vty
, "IP forwarding is on\n");
2687 /* Only display ipv6 forwarding is enabled or not. */
2688 DEFUN (show_ipv6_forwarding
,
2689 show_ipv6_forwarding_cmd
,
2690 "show ipv6 forwarding",
2692 "IPv6 information\n"
2693 "Forwarding status\n")
2697 ret
= ipforward_ipv6();
2701 vty_out(vty
, "ipv6 forwarding is unknown\n");
2704 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2707 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2710 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2716 DEFUN (ipv6_forwarding
,
2717 ipv6_forwarding_cmd
,
2720 "Turn on IPv6 forwarding\n")
2724 ret
= ipforward_ipv6();
2726 ret
= ipforward_ipv6_on();
2729 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2730 return CMD_WARNING_CONFIG_FAILED
;
2736 DEFUN (no_ipv6_forwarding
,
2737 no_ipv6_forwarding_cmd
,
2738 "no ipv6 forwarding",
2741 "Turn off IPv6 forwarding\n")
2745 ret
= ipforward_ipv6();
2747 ret
= ipforward_ipv6_off();
2750 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2751 return CMD_WARNING_CONFIG_FAILED
;
2757 /* Display dataplane info */
2758 DEFUN (show_dataplane
,
2760 "show zebra dplane [detailed]",
2763 "Zebra dataplane information\n"
2764 "Detailed output\n")
2767 bool detailed
= false;
2769 if (argv_find(argv
, argc
, "detailed", &idx
))
2772 return dplane_show_helper(vty
, detailed
);
2775 /* Display dataplane providers info */
2776 DEFUN (show_dataplane_providers
,
2777 show_dataplane_providers_cmd
,
2778 "show zebra dplane providers [detailed]",
2781 "Zebra dataplane information\n"
2782 "Zebra dataplane provider information\n"
2783 "Detailed output\n")
2786 bool detailed
= false;
2788 if (argv_find(argv
, argc
, "detailed", &idx
))
2791 return dplane_show_provs_helper(vty
, detailed
);
2794 /* Configure dataplane incoming queue limit */
2795 DEFUN (zebra_dplane_queue_limit
,
2796 zebra_dplane_queue_limit_cmd
,
2797 "zebra dplane limit (0-10000)",
2800 "Limit incoming queued updates\n"
2801 "Number of queued updates\n")
2805 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2807 dplane_set_in_queue_limit(limit
, true);
2812 /* Reset dataplane queue limit to default value */
2813 DEFUN (no_zebra_dplane_queue_limit
,
2814 no_zebra_dplane_queue_limit_cmd
,
2815 "no zebra dplane limit [(0-10000)]",
2819 "Limit incoming queued updates\n"
2820 "Number of queued updates\n")
2822 dplane_set_in_queue_limit(0, false);
2827 /* Table configuration write function. */
2828 static int config_write_table(struct vty
*vty
)
2830 if (zebrad
.rtm_table_default
)
2831 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2835 /* IPForwarding configuration write function. */
2836 static int config_write_forwarding(struct vty
*vty
)
2838 /* FIXME: Find better place for that. */
2839 router_id_write(vty
);
2842 vty_out(vty
, "no ip forwarding\n");
2843 if (!ipforward_ipv6())
2844 vty_out(vty
, "no ipv6 forwarding\n");
2845 vty_out(vty
, "!\n");
2849 /* IP node for static routes. */
2850 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2851 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2852 /* table node for routing tables. */
2853 static struct cmd_node table_node
= {TABLE_NODE
,
2854 "", /* This node has no interface. */
2856 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2857 "", /* This node has no interface. */
2861 void zebra_vty_init(void)
2863 /* Install configuration write function. */
2864 install_node(&table_node
, config_write_table
);
2865 install_node(&forwarding_node
, config_write_forwarding
);
2867 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2868 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2869 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2870 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2873 install_element(VIEW_NODE
, &show_table_cmd
);
2874 install_element(CONFIG_NODE
, &config_table_cmd
);
2875 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2876 #endif /* HAVE_NETLINK */
2878 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2879 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2880 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2883 zebra_route_map_init();
2885 install_node(&ip_node
, zebra_ip_config
);
2886 install_node(&protocol_node
, config_write_protocol
);
2888 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2889 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2891 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2892 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2894 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2895 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2896 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2897 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2898 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2899 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2901 install_element(VIEW_NODE
, &show_vrf_cmd
);
2902 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2903 install_element(VIEW_NODE
, &show_route_cmd
);
2904 install_element(VIEW_NODE
, &show_route_table_cmd
);
2905 if (vrf_is_backend_netns())
2906 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2907 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2908 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2909 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2910 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2911 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2912 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2914 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2915 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2917 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2918 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2919 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2920 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2921 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2922 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2923 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2924 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2925 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2927 /* Commands for VRF */
2928 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2930 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2931 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2932 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
2933 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2934 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2935 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2936 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2937 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2938 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2939 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2940 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2941 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2942 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
2943 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2944 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2945 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2946 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2947 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2948 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2949 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2950 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2951 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2952 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2953 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
2954 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
2955 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
2957 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2958 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2960 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2961 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2962 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2963 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2965 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2966 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2967 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2968 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);