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
);
951 DEFPY (show_ip_import_check
,
952 show_ip_import_check_cmd
,
953 "show <ip$ipv4|ipv6$ipv6> import-check [vrf NAME$vrf_name|vrf all$vrf_all]",
957 "IP import check tracking table\n"
959 VRF_ALL_CMD_HELP_STR
)
961 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
962 vrf_id_t vrf_id
= VRF_DEFAULT
;
966 struct zebra_vrf
*zvrf
;
968 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
969 if ((zvrf
= vrf
->info
) != NULL
) {
970 vty_out(vty
, "\nVRF %s:\n",
972 zebra_print_rnh_table(zvrf_id(zvrf
),
979 VRF_GET_ID(vrf_id
, vrf_name
, false);
981 zebra_print_rnh_table(vrf_id
, afi
, vty
, RNH_IMPORT_CHECK_TYPE
);
985 DEFUN (show_ip_nht_vrf_all
,
986 show_ip_nht_vrf_all_cmd
,
987 "show ip nht vrf all",
990 "IP nexthop tracking table\n"
991 VRF_ALL_CMD_HELP_STR
)
994 struct zebra_vrf
*zvrf
;
996 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
997 if ((zvrf
= vrf
->info
) != NULL
) {
998 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
999 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1006 DEFUN (show_ipv6_nht
,
1008 "show ipv6 nht [vrf NAME]",
1011 "IPv6 nexthop tracking table\n"
1015 vrf_id_t vrf_id
= VRF_DEFAULT
;
1018 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
1020 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1025 DEFUN (show_ipv6_nht_vrf_all
,
1026 show_ipv6_nht_vrf_all_cmd
,
1027 "show ipv6 nht vrf all",
1030 "IPv6 nexthop tracking table\n"
1031 VRF_ALL_CMD_HELP_STR
)
1034 struct zebra_vrf
*zvrf
;
1036 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1037 if ((zvrf
= vrf
->info
) != NULL
) {
1038 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1039 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1046 DEFUN (ip_nht_default_route
,
1047 ip_nht_default_route_cmd
,
1048 "ip nht resolve-via-default",
1050 "Filter Next Hop tracking route resolution\n"
1051 "Resolve via default route\n")
1053 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1058 if (zebra_rnh_ip_default_route
)
1061 zebra_rnh_ip_default_route
= 1;
1063 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1067 DEFUN (no_ip_nht_default_route
,
1068 no_ip_nht_default_route_cmd
,
1069 "no ip nht resolve-via-default",
1072 "Filter Next Hop tracking route resolution\n"
1073 "Resolve via default route\n")
1075 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1080 if (!zebra_rnh_ip_default_route
)
1083 zebra_rnh_ip_default_route
= 0;
1084 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1088 DEFUN (ipv6_nht_default_route
,
1089 ipv6_nht_default_route_cmd
,
1090 "ipv6 nht resolve-via-default",
1092 "Filter Next Hop tracking route resolution\n"
1093 "Resolve via default route\n")
1095 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1100 if (zebra_rnh_ipv6_default_route
)
1103 zebra_rnh_ipv6_default_route
= 1;
1104 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1108 DEFUN (no_ipv6_nht_default_route
,
1109 no_ipv6_nht_default_route_cmd
,
1110 "no ipv6 nht resolve-via-default",
1113 "Filter Next Hop tracking route resolution\n"
1114 "Resolve via default route\n")
1117 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1122 if (!zebra_rnh_ipv6_default_route
)
1125 zebra_rnh_ipv6_default_route
= 0;
1126 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1134 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1137 |A.B.C.D/M$prefix longer-prefixes\
1138 |supernets-only$supernets_only\
1141 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1142 |ospf$type_str (1-65535)$ospf_instance_id\
1144 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1147 |X:X::X:X/M$prefix longer-prefixes\
1149 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1154 "IP forwarding table\n"
1155 "IP routing table\n"
1156 VRF_FULL_CMD_HELP_STR
1157 "Show only routes with tag\n"
1159 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1160 "Show route matching the specified Network/Mask pair only\n"
1161 "Show supernet entries only\n"
1162 FRR_IP_REDIST_HELP_STR_ZEBRA
1163 "Open Shortest Path First (OSPFv2)\n"
1166 "IP forwarding table\n"
1167 "IP routing table\n"
1168 VRF_FULL_CMD_HELP_STR
1169 "Show only routes with tag\n"
1172 "Show route matching the specified Network/Mask pair only\n"
1173 FRR_IP6_REDIST_HELP_STR_ZEBRA
1176 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1181 type
= proto_redistnum(afi
, type_str
);
1183 vty_out(vty
, "Unknown route type\n");
1189 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1190 struct zebra_vrf
*zvrf
;
1191 struct route_table
*table
;
1193 if ((zvrf
= vrf
->info
) == NULL
1194 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1198 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1199 !!json
, tag
, prefix_str
? prefix
: NULL
,
1200 !!supernets_only
, type
, ospf_instance_id
);
1203 vrf_id_t vrf_id
= VRF_DEFAULT
;
1206 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1207 vrf
= vrf_lookup_by_id(vrf_id
);
1208 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1209 !!json
, tag
, prefix_str
? prefix
: NULL
,
1210 !!supernets_only
, type
, ospf_instance_id
);
1216 DEFPY (show_route_detail
,
1217 show_route_detail_cmd
,
1220 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1225 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1234 "IP routing table\n"
1235 VRF_FULL_CMD_HELP_STR
1236 "Network in the IP routing table to display\n"
1237 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1239 "IP routing table\n"
1240 VRF_FULL_CMD_HELP_STR
1245 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1246 struct route_table
*table
;
1248 struct route_node
*rn
;
1251 prefix_str
= address_str
;
1252 if (str2prefix(prefix_str
, &p
) < 0) {
1253 vty_out(vty
, "%% Malformed address\n");
1259 struct zebra_vrf
*zvrf
;
1261 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1262 if ((zvrf
= vrf
->info
) == NULL
1263 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1266 rn
= route_node_match(table
, &p
);
1269 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1270 route_unlock_node(rn
);
1275 vty_show_ip_route_detail_json(vty
, rn
);
1277 vty_show_ip_route_detail(vty
, rn
, 0);
1279 route_unlock_node(rn
);
1282 vrf_id_t vrf_id
= VRF_DEFAULT
;
1285 VRF_GET_ID(vrf_id
, vrf_name
, false);
1287 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1291 rn
= route_node_match(table
, &p
);
1293 vty_out(vty
, "%% Network not in table\n");
1296 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1297 vty_out(vty
, "%% Network not in table\n");
1298 route_unlock_node(rn
);
1303 vty_show_ip_route_detail_json(vty
, rn
);
1305 vty_show_ip_route_detail(vty
, rn
, 0);
1307 route_unlock_node(rn
);
1313 DEFPY (show_route_summary
,
1314 show_route_summary_cmd
,
1317 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1318 summary [prefix$prefix]\
1319 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1320 summary [prefix$prefix]\
1324 "IP routing table\n"
1325 VRF_FULL_CMD_HELP_STR
1326 "Summary of all routes\n"
1329 "IP routing table\n"
1330 VRF_FULL_CMD_HELP_STR
1331 "Summary of all routes\n"
1334 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1335 struct route_table
*table
;
1339 struct zebra_vrf
*zvrf
;
1341 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1342 if ((zvrf
= vrf
->info
) == NULL
1343 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1347 vty_show_ip_route_summary_prefix(vty
, table
);
1349 vty_show_ip_route_summary(vty
, table
);
1352 vrf_id_t vrf_id
= VRF_DEFAULT
;
1355 VRF_GET_ID(vrf_id
, vrf_name
, false);
1357 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1362 vty_show_ip_route_summary_prefix(vty
, table
);
1364 vty_show_ip_route_summary(vty
, table
);
1370 static void vty_show_ip_route_summary(struct vty
*vty
,
1371 struct route_table
*table
)
1373 struct route_node
*rn
;
1374 struct route_entry
*re
;
1375 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1376 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1377 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1378 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1382 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1383 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1384 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1385 RNODE_FOREACH_RE (rn
, re
) {
1386 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1387 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1389 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1391 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1393 rib_cnt
[re
->type
]++;
1395 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1396 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1399 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1401 fib_cnt
[re
->type
]++;
1405 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1406 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1408 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1409 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1410 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1411 if (i
== ZEBRA_ROUTE_BGP
) {
1412 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1413 rib_cnt
[ZEBRA_ROUTE_BGP
],
1414 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1415 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1416 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1417 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1419 vty_out(vty
, "%-20s %-20d %-20d \n",
1420 zebra_route_string(i
), rib_cnt
[i
],
1425 vty_out(vty
, "------\n");
1426 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1427 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1432 * Implementation of the ip route summary prefix command.
1434 * This command prints the primary prefixes that have been installed by various
1435 * protocols on the box.
1438 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1439 struct route_table
*table
)
1441 struct route_node
*rn
;
1442 struct route_entry
*re
;
1443 struct nexthop
*nexthop
;
1444 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1445 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1446 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1447 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1451 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1452 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1453 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1454 RNODE_FOREACH_RE (rn
, re
) {
1457 * In case of ECMP, count only once.
1460 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1461 nexthop
= nexthop
->next
) {
1463 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1464 rib_cnt
[re
->type
]++;
1465 if (CHECK_FLAG(nexthop
->flags
,
1466 NEXTHOP_FLAG_FIB
)) {
1467 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1468 fib_cnt
[re
->type
]++;
1470 if (re
->type
== ZEBRA_ROUTE_BGP
1471 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1472 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1473 if (CHECK_FLAG(nexthop
->flags
,
1475 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1480 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1481 "Prefix Routes", "FIB",
1482 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1484 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1485 if (rib_cnt
[i
] > 0) {
1486 if (i
== ZEBRA_ROUTE_BGP
) {
1487 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1488 rib_cnt
[ZEBRA_ROUTE_BGP
]
1489 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1490 fib_cnt
[ZEBRA_ROUTE_BGP
]
1491 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1492 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1493 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1494 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1496 vty_out(vty
, "%-20s %-20d %-20d \n",
1497 zebra_route_string(i
), rib_cnt
[i
],
1502 vty_out(vty
, "------\n");
1503 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1504 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1509 * Show IPv6 mroute command.Used to dump
1510 * the Multicast routing table.
1512 DEFUN (show_ipv6_mroute
,
1513 show_ipv6_mroute_cmd
,
1514 "show ipv6 mroute [vrf NAME]",
1517 "IPv6 Multicast routing table\n"
1520 struct route_table
*table
;
1521 struct route_node
*rn
;
1522 struct route_entry
*re
;
1524 vrf_id_t vrf_id
= VRF_DEFAULT
;
1527 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1529 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1533 /* Show all IPv6 route. */
1534 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1535 RNODE_FOREACH_RE (rn
, re
) {
1537 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1540 vty_show_ip_route(vty
, rn
, re
, NULL
);
1545 DEFUN (show_ipv6_mroute_vrf_all
,
1546 show_ipv6_mroute_vrf_all_cmd
,
1547 "show ipv6 mroute vrf all",
1550 "IPv6 Multicast routing table\n"
1551 VRF_ALL_CMD_HELP_STR
)
1553 struct route_table
*table
;
1554 struct route_node
*rn
;
1555 struct route_entry
*re
;
1557 struct zebra_vrf
*zvrf
;
1560 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1561 if ((zvrf
= vrf
->info
) == NULL
1562 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1565 /* Show all IPv6 route. */
1566 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1567 RNODE_FOREACH_RE (rn
, re
) {
1569 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1572 vty_show_ip_route(vty
, rn
, re
, NULL
);
1578 DEFUN (allow_external_route_update
,
1579 allow_external_route_update_cmd
,
1580 "allow-external-route-update",
1581 "Allow FRR routes to be overwritten by external processes\n")
1588 DEFUN (no_allow_external_route_update
,
1589 no_allow_external_route_update_cmd
,
1590 "no allow-external-route-update",
1592 "Allow FRR routes to be overwritten by external processes\n")
1607 struct zebra_vrf
*zvrf
;
1609 if (vrf_is_backend_netns())
1610 vty_out(vty
, "netns-based vrfs\n");
1612 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1613 if (!(zvrf
= vrf
->info
))
1615 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1618 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1619 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1620 vty_out(vty
, "inactive");
1621 else if (zvrf_ns_name(zvrf
))
1622 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1623 zvrf_ns_name(zvrf
));
1625 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1627 if (vrf_is_user_cfged(vrf
))
1628 vty_out(vty
, " (configured)");
1635 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1636 default_vrf_vni_mapping_cmd
,
1637 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1638 "VNI corresponding to the DEFAULT VRF\n"
1640 "Prefix routes only \n")
1643 char err
[ERR_STR_SZ
];
1644 struct zebra_vrf
*zvrf
= NULL
;
1645 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1648 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1655 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1658 vty_out(vty
, "%s\n", err
);
1665 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1666 no_default_vrf_vni_mapping_cmd
,
1667 "no vni " CMD_VNI_RANGE
,
1669 "VNI corresponding to DEFAULT VRF\n"
1673 char err
[ERR_STR_SZ
];
1674 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1675 struct zebra_vrf
*zvrf
= NULL
;
1677 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1681 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1683 vty_out(vty
, "%s\n", err
);
1690 DEFUN (vrf_vni_mapping
,
1691 vrf_vni_mapping_cmd
,
1692 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1693 "VNI corresponding to tenant VRF\n"
1695 "prefix-routes-only\n")
1700 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1701 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1702 char err
[ERR_STR_SZ
];
1710 /* Mark as having FRR configuration */
1711 vrf_set_user_cfged(vrf
);
1712 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1715 vty_out(vty
, "%s\n", err
);
1722 DEFUN (no_vrf_vni_mapping
,
1723 no_vrf_vni_mapping_cmd
,
1724 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1726 "VNI corresponding to tenant VRF\n"
1728 "prefix-routes-only\n")
1732 char err
[ERR_STR_SZ
];
1733 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1735 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1743 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1744 ERR_STR_SZ
, filter
, 0);
1746 vty_out(vty
, "%s\n", err
);
1750 /* If no other FRR config for this VRF, mark accordingly. */
1751 if (!zebra_vrf_has_config(zvrf
))
1752 vrf_reset_user_cfged(vrf
);
1758 DEFUN (show_vrf_vni
,
1760 "show vrf vni [json]",
1767 struct zebra_vrf
*zvrf
;
1768 json_object
*json
= NULL
;
1769 json_object
*json_vrfs
= NULL
;
1770 bool uj
= use_json(argc
, argv
);
1773 json
= json_object_new_object();
1774 json_vrfs
= json_object_new_array();
1778 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1779 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1781 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1786 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1790 json_object_object_add(json
, "vrfs", json_vrfs
);
1791 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1792 json
, JSON_C_TO_STRING_PRETTY
));
1793 json_object_free(json
);
1799 DEFUN (show_evpn_global
,
1800 show_evpn_global_cmd
,
1806 bool uj
= use_json(argc
, argv
);
1808 zebra_vxlan_print_evpn(vty
, uj
);
1812 DEFUN (show_evpn_vni
,
1814 "show evpn vni [json]",
1817 "VxLAN Network Identifier\n"
1820 struct zebra_vrf
*zvrf
;
1821 bool uj
= use_json(argc
, argv
);
1823 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1824 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1828 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1829 "show evpn vni detail [json]",
1832 "VxLAN Network Identifier\n"
1833 "Detailed Information On Each VNI\n"
1836 struct zebra_vrf
*zvrf
;
1837 bool uj
= use_json(argc
, argv
);
1839 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1840 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1844 DEFUN (show_evpn_vni_vni
,
1845 show_evpn_vni_vni_cmd
,
1846 "show evpn vni " CMD_VNI_RANGE
"[json]",
1849 "VxLAN Network Identifier\n"
1853 struct zebra_vrf
*zvrf
;
1855 bool uj
= use_json(argc
, argv
);
1857 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1858 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1859 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1863 DEFUN (show_evpn_rmac_vni_mac
,
1864 show_evpn_rmac_vni_mac_cmd
,
1865 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1872 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1877 bool uj
= use_json(argc
, argv
);
1879 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1880 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1881 vty_out(vty
, "%% Malformed MAC address\n");
1884 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1888 DEFUN (show_evpn_rmac_vni
,
1889 show_evpn_rmac_vni_cmd
,
1890 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1899 bool uj
= use_json(argc
, argv
);
1901 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1902 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1907 DEFUN (show_evpn_rmac_vni_all
,
1908 show_evpn_rmac_vni_all_cmd
,
1909 "show evpn rmac vni all [json]",
1917 bool uj
= use_json(argc
, argv
);
1919 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1924 DEFUN (show_evpn_nh_vni_ip
,
1925 show_evpn_nh_vni_ip_cmd
,
1926 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1933 "Host address (ipv4 or ipv6)\n"
1938 bool uj
= use_json(argc
, argv
);
1940 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1941 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1943 vty_out(vty
, "%% Malformed Neighbor address\n");
1946 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1951 DEFUN (show_evpn_nh_vni
,
1952 show_evpn_nh_vni_cmd
,
1953 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1962 bool uj
= use_json(argc
, argv
);
1964 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1965 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1970 DEFUN (show_evpn_nh_vni_all
,
1971 show_evpn_nh_vni_all_cmd
,
1972 "show evpn next-hops vni all [json]",
1980 bool uj
= use_json(argc
, argv
);
1982 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1987 DEFUN (show_evpn_mac_vni
,
1988 show_evpn_mac_vni_cmd
,
1989 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1993 "VxLAN Network Identifier\n"
1997 struct zebra_vrf
*zvrf
;
1999 bool uj
= use_json(argc
, argv
);
2001 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2002 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2003 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2007 DEFUN (show_evpn_mac_vni_all
,
2008 show_evpn_mac_vni_all_cmd
,
2009 "show evpn mac vni all [json]",
2013 "VxLAN Network Identifier\n"
2017 struct zebra_vrf
*zvrf
;
2018 bool uj
= use_json(argc
, argv
);
2020 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2021 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2025 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2026 "show evpn mac vni all detail [json]",
2030 "VxLAN Network Identifier\n"
2032 "Detailed Information On Each VNI MAC\n"
2035 struct zebra_vrf
*zvrf
;
2036 bool uj
= use_json(argc
, argv
);
2038 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2039 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2043 DEFUN (show_evpn_mac_vni_all_vtep
,
2044 show_evpn_mac_vni_all_vtep_cmd
,
2045 "show evpn mac vni all vtep A.B.C.D [json]",
2049 "VxLAN Network Identifier\n"
2052 "Remote VTEP IP address\n"
2055 struct zebra_vrf
*zvrf
;
2056 struct in_addr vtep_ip
;
2057 bool uj
= use_json(argc
, argv
);
2059 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2061 vty_out(vty
, "%% Malformed VTEP IP address\n");
2064 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2065 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2071 DEFUN (show_evpn_mac_vni_mac
,
2072 show_evpn_mac_vni_mac_cmd
,
2073 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2077 "VxLAN Network Identifier\n"
2080 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2084 struct zebra_vrf
*zvrf
;
2087 bool uj
= use_json(argc
, argv
);
2089 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2090 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2091 vty_out(vty
, "%% Malformed MAC address");
2094 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2095 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2099 DEFUN (show_evpn_mac_vni_vtep
,
2100 show_evpn_mac_vni_vtep_cmd
,
2101 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2105 "VxLAN Network Identifier\n"
2108 "Remote VTEP IP address\n"
2111 struct zebra_vrf
*zvrf
;
2113 struct in_addr vtep_ip
;
2114 bool uj
= use_json(argc
, argv
);
2116 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2117 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2119 vty_out(vty
, "%% Malformed VTEP IP address\n");
2123 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2124 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2128 DEFPY (show_evpn_mac_vni_all_dad
,
2129 show_evpn_mac_vni_all_dad_cmd
,
2130 "show evpn mac vni all duplicate [json]",
2134 "VxLAN Network Identifier\n"
2136 "Duplicate address list\n"
2139 struct zebra_vrf
*zvrf
;
2140 bool uj
= use_json(argc
, argv
);
2142 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2143 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2148 DEFPY (show_evpn_mac_vni_dad
,
2149 show_evpn_mac_vni_dad_cmd
,
2150 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2154 "VxLAN Network Identifier\n"
2156 "Duplicate address list\n"
2159 struct zebra_vrf
*zvrf
;
2161 bool uj
= use_json(argc
, argv
);
2163 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2164 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2166 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2171 DEFPY (show_evpn_neigh_vni_dad
,
2172 show_evpn_neigh_vni_dad_cmd
,
2173 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2176 "ARP and ND cache\n"
2177 "VxLAN Network Identifier\n"
2179 "Duplicate address list\n"
2182 struct zebra_vrf
*zvrf
;
2184 bool uj
= use_json(argc
, argv
);
2186 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2187 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2188 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2192 DEFPY (show_evpn_neigh_vni_all_dad
,
2193 show_evpn_neigh_vni_all_dad_cmd
,
2194 "show evpn arp-cache vni all duplicate [json]",
2197 "ARP and ND cache\n"
2198 "VxLAN Network Identifier\n"
2200 "Duplicate address list\n"
2203 struct zebra_vrf
*zvrf
;
2204 bool uj
= use_json(argc
, argv
);
2206 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2207 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2212 DEFUN (show_evpn_neigh_vni
,
2213 show_evpn_neigh_vni_cmd
,
2214 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2217 "ARP and ND cache\n"
2218 "VxLAN Network Identifier\n"
2222 struct zebra_vrf
*zvrf
;
2224 bool uj
= use_json(argc
, argv
);
2226 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2227 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2228 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2232 DEFUN (show_evpn_neigh_vni_all
,
2233 show_evpn_neigh_vni_all_cmd
,
2234 "show evpn arp-cache vni all [json]",
2237 "ARP and ND cache\n"
2238 "VxLAN Network Identifier\n"
2242 struct zebra_vrf
*zvrf
;
2243 bool uj
= use_json(argc
, argv
);
2245 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2246 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2250 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2251 "show evpn arp-cache vni all detail [json]",
2254 "ARP and ND cache\n"
2255 "VxLAN Network Identifier\n"
2257 "Neighbor details for all vnis in detail\n" JSON_STR
)
2259 struct zebra_vrf
*zvrf
;
2260 bool uj
= use_json(argc
, argv
);
2262 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2263 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2267 DEFUN (show_evpn_neigh_vni_neigh
,
2268 show_evpn_neigh_vni_neigh_cmd
,
2269 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2272 "ARP and ND cache\n"
2273 "VxLAN Network Identifier\n"
2276 "Neighbor address (IPv4 or IPv6 address)\n"
2279 struct zebra_vrf
*zvrf
;
2282 bool uj
= use_json(argc
, argv
);
2284 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2285 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2287 vty_out(vty
, "%% Malformed Neighbor address\n");
2290 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2291 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2295 DEFUN (show_evpn_neigh_vni_vtep
,
2296 show_evpn_neigh_vni_vtep_cmd
,
2297 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2300 "ARP and ND cache\n"
2301 "VxLAN Network Identifier\n"
2304 "Remote VTEP IP address\n"
2307 struct zebra_vrf
*zvrf
;
2309 struct in_addr vtep_ip
;
2310 bool uj
= use_json(argc
, argv
);
2312 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2313 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2315 vty_out(vty
, "%% Malformed VTEP IP address\n");
2319 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2320 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2324 /* policy routing contexts */
2325 DEFUN (show_pbr_ipset
,
2327 "show pbr ipset [WORD]",
2329 "Policy-Based Routing\n"
2330 "IPset Context information\n"
2331 "IPset Name information\n")
2335 found
= argv_find(argv
, argc
, "WORD", &idx
);
2337 zebra_pbr_show_ipset_list(vty
, NULL
);
2339 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2343 /* policy routing contexts */
2344 DEFUN (show_pbr_iptable
,
2345 show_pbr_iptable_cmd
,
2346 "show pbr iptable [WORD]",
2348 "Policy-Based Routing\n"
2349 "IPtable Context information\n"
2350 "IPtable Name information\n")
2355 found
= argv_find(argv
, argc
, "WORD", &idx
);
2357 zebra_pbr_show_iptable(vty
, NULL
);
2359 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2363 DEFPY (clear_evpn_dup_addr
,
2364 clear_evpn_dup_addr_cmd
,
2365 "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>]>",
2368 "Duplicate address \n"
2369 "VxLAN Network Identifier\n"
2373 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2378 struct zebra_vrf
*zvrf
;
2380 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2381 struct ethaddr mac_addr
;
2382 int ret
= CMD_SUCCESS
;
2384 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2386 vni
= strtoul(vni_val
, NULL
, 10);
2389 prefix_str2mac(mac_val
, &mac_addr
);
2390 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2394 if (sockunion_family(ip
) == AF_INET
) {
2395 host_ip
.ipa_type
= IPADDR_V4
;
2396 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2398 host_ip
.ipa_type
= IPADDR_V6
;
2399 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2400 sizeof(struct in6_addr
));
2402 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2406 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2409 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2415 /* Static ip route configuration write function. */
2416 static int zebra_ip_config(struct vty
*vty
)
2420 write
+= zebra_import_table_config(vty
);
2425 DEFUN (ip_zebra_import_table_distance
,
2426 ip_zebra_import_table_distance_cmd
,
2427 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2429 "import routes from non-main kernel table\n"
2430 "kernel routing table id\n"
2431 "Distance for imported routes\n"
2432 "Default distance value\n"
2433 "route-map for filtering\n"
2436 uint32_t table_id
= 0;
2438 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2439 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2441 strmatch(argv
[argc
- 2]->text
, "route-map")
2442 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2446 if (argc
== 7 || (argc
== 5 && !rmap
))
2447 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2449 if (!is_zebra_valid_kernel_table(table_id
)) {
2451 "Invalid routing table ID, %d. Must be in range 1-252\n",
2454 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2458 if (is_zebra_main_routing_table(table_id
)) {
2460 "Invalid routing table ID, %d. Must be non-default table\n",
2463 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2467 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2469 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2474 DEFUN_HIDDEN (zebra_packet_process
,
2475 zebra_packet_process_cmd
,
2476 "zebra zapi-packets (1-10000)",
2479 "Number of packets to process before relinquishing thread\n")
2481 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2483 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2484 memory_order_relaxed
);
2489 DEFUN_HIDDEN (no_zebra_packet_process
,
2490 no_zebra_packet_process_cmd
,
2491 "no zebra zapi-packets [(1-10000)]",
2495 "Number of packets to process before relinquishing thread\n")
2497 atomic_store_explicit(&zebrad
.packets_to_process
,
2498 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2499 memory_order_relaxed
);
2504 DEFUN_HIDDEN (zebra_workqueue_timer
,
2505 zebra_workqueue_timer_cmd
,
2506 "zebra work-queue (0-10000)",
2509 "Time in milliseconds\n")
2511 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2512 zebrad
.ribq
->spec
.hold
= timer
;
2517 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2518 no_zebra_workqueue_timer_cmd
,
2519 "no zebra work-queue [(0-10000)]",
2523 "Time in milliseconds\n")
2525 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2530 DEFUN (no_ip_zebra_import_table
,
2531 no_ip_zebra_import_table_cmd
,
2532 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2535 "import routes from non-main kernel table\n"
2536 "kernel routing table id\n"
2537 "Distance for imported routes\n"
2538 "Default distance value\n"
2539 "route-map for filtering\n"
2542 uint32_t table_id
= 0;
2543 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2545 if (!is_zebra_valid_kernel_table(table_id
)) {
2547 "Invalid routing table ID. Must be in range 1-252\n");
2551 if (is_zebra_main_routing_table(table_id
)) {
2553 "Invalid routing table ID, %d. Must be non-default table\n",
2558 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2561 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2564 static int config_write_protocol(struct vty
*vty
)
2567 vty_out(vty
, "allow-external-route-update\n");
2569 if (zebra_rnh_ip_default_route
)
2570 vty_out(vty
, "ip nht resolve-via-default\n");
2572 if (zebra_rnh_ipv6_default_route
)
2573 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2575 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2576 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2578 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2579 vty_out(vty
, "zebra zapi-packets %u\n",
2580 zebrad
.packets_to_process
);
2582 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2584 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2585 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2586 ipv4_multicast_mode
== MCAST_URIB_ONLY
2588 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2590 : ipv4_multicast_mode
2591 == MCAST_MIX_MRIB_FIRST
2593 : ipv4_multicast_mode
2594 == MCAST_MIX_DISTANCE
2601 /* Display default rtm_table for all clients. */
2606 "default routing table to use for all clients\n")
2608 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2612 DEFUN (config_table
,
2615 "Configure target kernel routing table\n"
2618 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2622 DEFUN (no_config_table
,
2623 no_config_table_cmd
,
2624 "no table [TABLENO]",
2626 "Configure target kernel routing table\n"
2629 zebrad
.rtm_table_default
= 0;
2643 " Route Route Neighbor LSP LSP\n");
2645 "VRF Installs Removals Updates Installs Removals\n");
2647 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2648 struct zebra_vrf
*zvrf
= vrf
->info
;
2650 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2651 " %10" PRIu64
" %10" PRIu64
"\n",
2652 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2653 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2654 zvrf
->lsp_removals
);
2660 DEFUN (ip_forwarding
,
2664 "Turn on IP forwarding\n")
2670 ret
= ipforward_on();
2673 vty_out(vty
, "Can't turn on IP forwarding\n");
2674 return CMD_WARNING_CONFIG_FAILED
;
2680 DEFUN (no_ip_forwarding
,
2681 no_ip_forwarding_cmd
,
2685 "Turn off IP forwarding\n")
2691 ret
= ipforward_off();
2694 vty_out(vty
, "Can't turn off IP forwarding\n");
2695 return CMD_WARNING_CONFIG_FAILED
;
2701 /* Only display ip forwarding is enabled or not. */
2702 DEFUN (show_ip_forwarding
,
2703 show_ip_forwarding_cmd
,
2704 "show ip forwarding",
2707 "IP forwarding status\n")
2714 vty_out(vty
, "IP forwarding is off\n");
2716 vty_out(vty
, "IP forwarding is on\n");
2720 /* Only display ipv6 forwarding is enabled or not. */
2721 DEFUN (show_ipv6_forwarding
,
2722 show_ipv6_forwarding_cmd
,
2723 "show ipv6 forwarding",
2725 "IPv6 information\n"
2726 "Forwarding status\n")
2730 ret
= ipforward_ipv6();
2734 vty_out(vty
, "ipv6 forwarding is unknown\n");
2737 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2740 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2743 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2749 DEFUN (ipv6_forwarding
,
2750 ipv6_forwarding_cmd
,
2753 "Turn on IPv6 forwarding\n")
2757 ret
= ipforward_ipv6();
2759 ret
= ipforward_ipv6_on();
2762 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2763 return CMD_WARNING_CONFIG_FAILED
;
2769 DEFUN (no_ipv6_forwarding
,
2770 no_ipv6_forwarding_cmd
,
2771 "no ipv6 forwarding",
2774 "Turn off IPv6 forwarding\n")
2778 ret
= ipforward_ipv6();
2780 ret
= ipforward_ipv6_off();
2783 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2784 return CMD_WARNING_CONFIG_FAILED
;
2790 /* Display dataplane info */
2791 DEFUN (show_dataplane
,
2793 "show zebra dplane [detailed]",
2796 "Zebra dataplane information\n"
2797 "Detailed output\n")
2800 bool detailed
= false;
2802 if (argv_find(argv
, argc
, "detailed", &idx
))
2805 return dplane_show_helper(vty
, detailed
);
2808 /* Display dataplane providers info */
2809 DEFUN (show_dataplane_providers
,
2810 show_dataplane_providers_cmd
,
2811 "show zebra dplane providers [detailed]",
2814 "Zebra dataplane information\n"
2815 "Zebra dataplane provider information\n"
2816 "Detailed output\n")
2819 bool detailed
= false;
2821 if (argv_find(argv
, argc
, "detailed", &idx
))
2824 return dplane_show_provs_helper(vty
, detailed
);
2827 /* Configure dataplane incoming queue limit */
2828 DEFUN (zebra_dplane_queue_limit
,
2829 zebra_dplane_queue_limit_cmd
,
2830 "zebra dplane limit (0-10000)",
2833 "Limit incoming queued updates\n"
2834 "Number of queued updates\n")
2838 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2840 dplane_set_in_queue_limit(limit
, true);
2845 /* Reset dataplane queue limit to default value */
2846 DEFUN (no_zebra_dplane_queue_limit
,
2847 no_zebra_dplane_queue_limit_cmd
,
2848 "no zebra dplane limit [(0-10000)]",
2852 "Limit incoming queued updates\n"
2853 "Number of queued updates\n")
2855 dplane_set_in_queue_limit(0, false);
2860 /* Table configuration write function. */
2861 static int config_write_table(struct vty
*vty
)
2863 if (zebrad
.rtm_table_default
)
2864 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2868 /* IPForwarding configuration write function. */
2869 static int config_write_forwarding(struct vty
*vty
)
2871 /* FIXME: Find better place for that. */
2872 router_id_write(vty
);
2875 vty_out(vty
, "no ip forwarding\n");
2876 if (!ipforward_ipv6())
2877 vty_out(vty
, "no ipv6 forwarding\n");
2878 vty_out(vty
, "!\n");
2882 /* IP node for static routes. */
2883 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2884 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2885 /* table node for routing tables. */
2886 static struct cmd_node table_node
= {TABLE_NODE
,
2887 "", /* This node has no interface. */
2889 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2890 "", /* This node has no interface. */
2894 void zebra_vty_init(void)
2896 /* Install configuration write function. */
2897 install_node(&table_node
, config_write_table
);
2898 install_node(&forwarding_node
, config_write_forwarding
);
2900 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2901 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2902 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2903 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2906 install_element(VIEW_NODE
, &show_table_cmd
);
2907 install_element(CONFIG_NODE
, &config_table_cmd
);
2908 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2909 #endif /* HAVE_NETLINK */
2911 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2912 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2913 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2916 zebra_route_map_init();
2918 install_node(&ip_node
, zebra_ip_config
);
2919 install_node(&protocol_node
, config_write_protocol
);
2921 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2922 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2924 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2925 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2927 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2928 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2929 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2930 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2931 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2932 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2934 install_element(VIEW_NODE
, &show_vrf_cmd
);
2935 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2936 install_element(VIEW_NODE
, &show_route_cmd
);
2937 install_element(VIEW_NODE
, &show_route_table_cmd
);
2938 if (vrf_is_backend_netns())
2939 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2940 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2941 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2942 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2943 install_element(VIEW_NODE
, &show_ip_import_check_cmd
);
2944 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2945 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2946 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2948 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2949 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2951 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2952 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2953 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2954 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2955 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2956 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2957 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2958 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2959 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2961 /* Commands for VRF */
2962 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2964 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2965 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2966 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
2967 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2968 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2969 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2970 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2971 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2972 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2973 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2974 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2975 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2976 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
2977 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2978 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2979 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2980 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2981 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2982 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2983 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2984 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2985 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2986 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2987 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
2988 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
2989 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
2991 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2992 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2994 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2995 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2996 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2997 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2999 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3000 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3001 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3002 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);