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
, AFI_IP
, 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
), afi
, vty
,
973 RNH_IMPORT_CHECK_TYPE
);
978 VRF_GET_ID(vrf_id
, vrf_name
, false);
980 zebra_print_rnh_table(vrf_id
, afi
, vty
, RNH_IMPORT_CHECK_TYPE
);
984 DEFUN (show_ip_nht_vrf_all
,
985 show_ip_nht_vrf_all_cmd
,
986 "show ip nht vrf all",
989 "IP nexthop tracking table\n"
990 VRF_ALL_CMD_HELP_STR
)
993 struct zebra_vrf
*zvrf
;
995 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
996 if ((zvrf
= vrf
->info
) != NULL
) {
997 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
998 zebra_print_rnh_table(zvrf_id(zvrf
), AFI_IP
, vty
,
1005 DEFUN (show_ipv6_nht
,
1007 "show ipv6 nht [vrf NAME]",
1010 "IPv6 nexthop tracking table\n"
1014 vrf_id_t vrf_id
= VRF_DEFAULT
;
1017 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
1019 zebra_print_rnh_table(vrf_id
, AFI_IP6
, vty
, RNH_NEXTHOP_TYPE
);
1024 DEFUN (show_ipv6_nht_vrf_all
,
1025 show_ipv6_nht_vrf_all_cmd
,
1026 "show ipv6 nht vrf all",
1029 "IPv6 nexthop tracking table\n"
1030 VRF_ALL_CMD_HELP_STR
)
1033 struct zebra_vrf
*zvrf
;
1035 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1036 if ((zvrf
= vrf
->info
) != NULL
) {
1037 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1038 zebra_print_rnh_table(zvrf_id(zvrf
), AFI_IP6
, vty
,
1045 DEFUN (ip_nht_default_route
,
1046 ip_nht_default_route_cmd
,
1047 "ip nht resolve-via-default",
1049 "Filter Next Hop tracking route resolution\n"
1050 "Resolve via default route\n")
1052 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1057 if (zebra_rnh_ip_default_route
)
1060 zebra_rnh_ip_default_route
= 1;
1062 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1066 DEFUN (no_ip_nht_default_route
,
1067 no_ip_nht_default_route_cmd
,
1068 "no ip nht resolve-via-default",
1071 "Filter Next Hop tracking route resolution\n"
1072 "Resolve via default route\n")
1074 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1079 if (!zebra_rnh_ip_default_route
)
1082 zebra_rnh_ip_default_route
= 0;
1083 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1087 DEFUN (ipv6_nht_default_route
,
1088 ipv6_nht_default_route_cmd
,
1089 "ipv6 nht resolve-via-default",
1091 "Filter Next Hop tracking route resolution\n"
1092 "Resolve via default route\n")
1094 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1099 if (zebra_rnh_ipv6_default_route
)
1102 zebra_rnh_ipv6_default_route
= 1;
1103 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1107 DEFUN (no_ipv6_nht_default_route
,
1108 no_ipv6_nht_default_route_cmd
,
1109 "no ipv6 nht resolve-via-default",
1112 "Filter Next Hop tracking route resolution\n"
1113 "Resolve via default route\n")
1116 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1121 if (!zebra_rnh_ipv6_default_route
)
1124 zebra_rnh_ipv6_default_route
= 0;
1125 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1133 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1136 |A.B.C.D/M$prefix longer-prefixes\
1137 |supernets-only$supernets_only\
1140 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1141 |ospf$type_str (1-65535)$ospf_instance_id\
1143 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1146 |X:X::X:X/M$prefix longer-prefixes\
1148 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1153 "IP forwarding table\n"
1154 "IP routing table\n"
1155 VRF_FULL_CMD_HELP_STR
1156 "Show only routes with tag\n"
1158 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1159 "Show route matching the specified Network/Mask pair only\n"
1160 "Show supernet entries only\n"
1161 FRR_IP_REDIST_HELP_STR_ZEBRA
1162 "Open Shortest Path First (OSPFv2)\n"
1165 "IP forwarding table\n"
1166 "IP routing table\n"
1167 VRF_FULL_CMD_HELP_STR
1168 "Show only routes with tag\n"
1171 "Show route matching the specified Network/Mask pair only\n"
1172 FRR_IP6_REDIST_HELP_STR_ZEBRA
1175 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1180 type
= proto_redistnum(afi
, type_str
);
1182 vty_out(vty
, "Unknown route type\n");
1188 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1189 struct zebra_vrf
*zvrf
;
1190 struct route_table
*table
;
1192 if ((zvrf
= vrf
->info
) == NULL
1193 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1197 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1198 !!json
, tag
, prefix_str
? prefix
: NULL
,
1199 !!supernets_only
, type
, ospf_instance_id
);
1202 vrf_id_t vrf_id
= VRF_DEFAULT
;
1205 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1206 vrf
= vrf_lookup_by_id(vrf_id
);
1207 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1208 !!json
, tag
, prefix_str
? prefix
: NULL
,
1209 !!supernets_only
, type
, ospf_instance_id
);
1215 DEFPY (show_route_detail
,
1216 show_route_detail_cmd
,
1219 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1224 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1233 "IP routing table\n"
1234 VRF_FULL_CMD_HELP_STR
1235 "Network in the IP routing table to display\n"
1236 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1238 "IP routing table\n"
1239 VRF_FULL_CMD_HELP_STR
1244 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1245 struct route_table
*table
;
1247 struct route_node
*rn
;
1250 prefix_str
= address_str
;
1251 if (str2prefix(prefix_str
, &p
) < 0) {
1252 vty_out(vty
, "%% Malformed address\n");
1258 struct zebra_vrf
*zvrf
;
1260 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1261 if ((zvrf
= vrf
->info
) == NULL
1262 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1265 rn
= route_node_match(table
, &p
);
1268 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1269 route_unlock_node(rn
);
1274 vty_show_ip_route_detail_json(vty
, rn
);
1276 vty_show_ip_route_detail(vty
, rn
, 0);
1278 route_unlock_node(rn
);
1281 vrf_id_t vrf_id
= VRF_DEFAULT
;
1284 VRF_GET_ID(vrf_id
, vrf_name
, false);
1286 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1290 rn
= route_node_match(table
, &p
);
1292 vty_out(vty
, "%% Network not in table\n");
1295 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1296 vty_out(vty
, "%% Network not in table\n");
1297 route_unlock_node(rn
);
1302 vty_show_ip_route_detail_json(vty
, rn
);
1304 vty_show_ip_route_detail(vty
, rn
, 0);
1306 route_unlock_node(rn
);
1312 DEFPY (show_route_summary
,
1313 show_route_summary_cmd
,
1316 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1317 summary [prefix$prefix]\
1318 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1319 summary [prefix$prefix]\
1323 "IP routing table\n"
1324 VRF_FULL_CMD_HELP_STR
1325 "Summary of all routes\n"
1328 "IP routing table\n"
1329 VRF_FULL_CMD_HELP_STR
1330 "Summary of all routes\n"
1333 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1334 struct route_table
*table
;
1338 struct zebra_vrf
*zvrf
;
1340 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1341 if ((zvrf
= vrf
->info
) == NULL
1342 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1346 vty_show_ip_route_summary_prefix(vty
, table
);
1348 vty_show_ip_route_summary(vty
, table
);
1351 vrf_id_t vrf_id
= VRF_DEFAULT
;
1354 VRF_GET_ID(vrf_id
, vrf_name
, false);
1356 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1361 vty_show_ip_route_summary_prefix(vty
, table
);
1363 vty_show_ip_route_summary(vty
, table
);
1369 static void vty_show_ip_route_summary(struct vty
*vty
,
1370 struct route_table
*table
)
1372 struct route_node
*rn
;
1373 struct route_entry
*re
;
1374 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1375 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1376 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1377 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1381 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1382 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1383 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1384 RNODE_FOREACH_RE (rn
, re
) {
1385 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1386 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1388 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1390 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1392 rib_cnt
[re
->type
]++;
1394 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1395 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1398 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1400 fib_cnt
[re
->type
]++;
1404 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1405 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1407 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1408 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1409 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1410 if (i
== ZEBRA_ROUTE_BGP
) {
1411 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1412 rib_cnt
[ZEBRA_ROUTE_BGP
],
1413 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1414 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1415 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1416 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1418 vty_out(vty
, "%-20s %-20d %-20d \n",
1419 zebra_route_string(i
), rib_cnt
[i
],
1424 vty_out(vty
, "------\n");
1425 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1426 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1431 * Implementation of the ip route summary prefix command.
1433 * This command prints the primary prefixes that have been installed by various
1434 * protocols on the box.
1437 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1438 struct route_table
*table
)
1440 struct route_node
*rn
;
1441 struct route_entry
*re
;
1442 struct nexthop
*nexthop
;
1443 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1444 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1445 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1446 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1450 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1451 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1452 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1453 RNODE_FOREACH_RE (rn
, re
) {
1456 * In case of ECMP, count only once.
1459 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1460 nexthop
= nexthop
->next
) {
1462 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1463 rib_cnt
[re
->type
]++;
1464 if (CHECK_FLAG(nexthop
->flags
,
1465 NEXTHOP_FLAG_FIB
)) {
1466 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1467 fib_cnt
[re
->type
]++;
1469 if (re
->type
== ZEBRA_ROUTE_BGP
1470 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1471 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1472 if (CHECK_FLAG(nexthop
->flags
,
1474 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1479 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1480 "Prefix Routes", "FIB",
1481 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1483 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1484 if (rib_cnt
[i
] > 0) {
1485 if (i
== ZEBRA_ROUTE_BGP
) {
1486 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1487 rib_cnt
[ZEBRA_ROUTE_BGP
]
1488 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1489 fib_cnt
[ZEBRA_ROUTE_BGP
]
1490 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1491 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1492 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1493 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1495 vty_out(vty
, "%-20s %-20d %-20d \n",
1496 zebra_route_string(i
), rib_cnt
[i
],
1501 vty_out(vty
, "------\n");
1502 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1503 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1508 * Show IPv6 mroute command.Used to dump
1509 * the Multicast routing table.
1511 DEFUN (show_ipv6_mroute
,
1512 show_ipv6_mroute_cmd
,
1513 "show ipv6 mroute [vrf NAME]",
1516 "IPv6 Multicast routing table\n"
1519 struct route_table
*table
;
1520 struct route_node
*rn
;
1521 struct route_entry
*re
;
1523 vrf_id_t vrf_id
= VRF_DEFAULT
;
1526 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1528 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
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
);
1544 DEFUN (show_ipv6_mroute_vrf_all
,
1545 show_ipv6_mroute_vrf_all_cmd
,
1546 "show ipv6 mroute vrf all",
1549 "IPv6 Multicast routing table\n"
1550 VRF_ALL_CMD_HELP_STR
)
1552 struct route_table
*table
;
1553 struct route_node
*rn
;
1554 struct route_entry
*re
;
1556 struct zebra_vrf
*zvrf
;
1559 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1560 if ((zvrf
= vrf
->info
) == NULL
1561 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1564 /* Show all IPv6 route. */
1565 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1566 RNODE_FOREACH_RE (rn
, re
) {
1568 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1571 vty_show_ip_route(vty
, rn
, re
, NULL
);
1577 DEFUN (allow_external_route_update
,
1578 allow_external_route_update_cmd
,
1579 "allow-external-route-update",
1580 "Allow FRR routes to be overwritten by external processes\n")
1587 DEFUN (no_allow_external_route_update
,
1588 no_allow_external_route_update_cmd
,
1589 "no allow-external-route-update",
1591 "Allow FRR routes to be overwritten by external processes\n")
1606 struct zebra_vrf
*zvrf
;
1608 if (vrf_is_backend_netns())
1609 vty_out(vty
, "netns-based vrfs\n");
1611 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1612 if (!(zvrf
= vrf
->info
))
1614 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1617 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1618 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1619 vty_out(vty
, "inactive");
1620 else if (zvrf_ns_name(zvrf
))
1621 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1622 zvrf_ns_name(zvrf
));
1624 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1626 if (vrf_is_user_cfged(vrf
))
1627 vty_out(vty
, " (configured)");
1634 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1635 default_vrf_vni_mapping_cmd
,
1636 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1637 "VNI corresponding to the DEFAULT VRF\n"
1639 "Prefix routes only \n")
1642 char err
[ERR_STR_SZ
];
1643 struct zebra_vrf
*zvrf
= NULL
;
1644 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1647 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1654 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1657 vty_out(vty
, "%s\n", err
);
1664 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1665 no_default_vrf_vni_mapping_cmd
,
1666 "no vni " CMD_VNI_RANGE
,
1668 "VNI corresponding to DEFAULT VRF\n"
1672 char err
[ERR_STR_SZ
];
1673 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1674 struct zebra_vrf
*zvrf
= NULL
;
1676 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1680 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1682 vty_out(vty
, "%s\n", err
);
1689 DEFUN (vrf_vni_mapping
,
1690 vrf_vni_mapping_cmd
,
1691 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1692 "VNI corresponding to tenant VRF\n"
1694 "prefix-routes-only\n")
1699 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1700 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1701 char err
[ERR_STR_SZ
];
1709 /* Mark as having FRR configuration */
1710 vrf_set_user_cfged(vrf
);
1711 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1714 vty_out(vty
, "%s\n", err
);
1721 DEFUN (no_vrf_vni_mapping
,
1722 no_vrf_vni_mapping_cmd
,
1723 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1725 "VNI corresponding to tenant VRF\n"
1727 "prefix-routes-only\n")
1731 char err
[ERR_STR_SZ
];
1732 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1734 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1742 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1743 ERR_STR_SZ
, filter
, 0);
1745 vty_out(vty
, "%s\n", err
);
1749 /* If no other FRR config for this VRF, mark accordingly. */
1750 if (!zebra_vrf_has_config(zvrf
))
1751 vrf_reset_user_cfged(vrf
);
1757 DEFUN (show_vrf_vni
,
1759 "show vrf vni [json]",
1766 struct zebra_vrf
*zvrf
;
1767 json_object
*json
= NULL
;
1768 json_object
*json_vrfs
= NULL
;
1769 bool uj
= use_json(argc
, argv
);
1772 json
= json_object_new_object();
1773 json_vrfs
= json_object_new_array();
1777 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1778 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1780 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1785 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1789 json_object_object_add(json
, "vrfs", json_vrfs
);
1790 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1791 json
, JSON_C_TO_STRING_PRETTY
));
1792 json_object_free(json
);
1798 DEFUN (show_evpn_global
,
1799 show_evpn_global_cmd
,
1805 bool uj
= use_json(argc
, argv
);
1807 zebra_vxlan_print_evpn(vty
, uj
);
1811 DEFUN (show_evpn_vni
,
1813 "show evpn vni [json]",
1816 "VxLAN Network Identifier\n"
1819 struct zebra_vrf
*zvrf
;
1820 bool uj
= use_json(argc
, argv
);
1822 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1823 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1827 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1828 "show evpn vni detail [json]",
1831 "VxLAN Network Identifier\n"
1832 "Detailed Information On Each VNI\n"
1835 struct zebra_vrf
*zvrf
;
1836 bool uj
= use_json(argc
, argv
);
1838 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1839 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1843 DEFUN (show_evpn_vni_vni
,
1844 show_evpn_vni_vni_cmd
,
1845 "show evpn vni " CMD_VNI_RANGE
"[json]",
1848 "VxLAN Network Identifier\n"
1852 struct zebra_vrf
*zvrf
;
1854 bool uj
= use_json(argc
, argv
);
1856 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1857 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1858 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1862 DEFUN (show_evpn_rmac_vni_mac
,
1863 show_evpn_rmac_vni_mac_cmd
,
1864 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1871 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1876 bool uj
= use_json(argc
, argv
);
1878 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1879 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1880 vty_out(vty
, "%% Malformed MAC address\n");
1883 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1887 DEFUN (show_evpn_rmac_vni
,
1888 show_evpn_rmac_vni_cmd
,
1889 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1898 bool uj
= use_json(argc
, argv
);
1900 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1901 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1906 DEFUN (show_evpn_rmac_vni_all
,
1907 show_evpn_rmac_vni_all_cmd
,
1908 "show evpn rmac vni all [json]",
1916 bool uj
= use_json(argc
, argv
);
1918 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1923 DEFUN (show_evpn_nh_vni_ip
,
1924 show_evpn_nh_vni_ip_cmd
,
1925 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1932 "Host address (ipv4 or ipv6)\n"
1937 bool uj
= use_json(argc
, argv
);
1939 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1940 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1942 vty_out(vty
, "%% Malformed Neighbor address\n");
1945 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1950 DEFUN (show_evpn_nh_vni
,
1951 show_evpn_nh_vni_cmd
,
1952 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1961 bool uj
= use_json(argc
, argv
);
1963 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1964 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1969 DEFUN (show_evpn_nh_vni_all
,
1970 show_evpn_nh_vni_all_cmd
,
1971 "show evpn next-hops vni all [json]",
1979 bool uj
= use_json(argc
, argv
);
1981 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1986 DEFUN (show_evpn_mac_vni
,
1987 show_evpn_mac_vni_cmd
,
1988 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1992 "VxLAN Network Identifier\n"
1996 struct zebra_vrf
*zvrf
;
1998 bool uj
= use_json(argc
, argv
);
2000 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2001 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2002 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2006 DEFUN (show_evpn_mac_vni_all
,
2007 show_evpn_mac_vni_all_cmd
,
2008 "show evpn mac vni all [json]",
2012 "VxLAN Network Identifier\n"
2016 struct zebra_vrf
*zvrf
;
2017 bool uj
= use_json(argc
, argv
);
2019 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2020 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2024 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2025 "show evpn mac vni all detail [json]",
2029 "VxLAN Network Identifier\n"
2031 "Detailed Information On Each VNI MAC\n"
2034 struct zebra_vrf
*zvrf
;
2035 bool uj
= use_json(argc
, argv
);
2037 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2038 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2042 DEFUN (show_evpn_mac_vni_all_vtep
,
2043 show_evpn_mac_vni_all_vtep_cmd
,
2044 "show evpn mac vni all vtep A.B.C.D [json]",
2048 "VxLAN Network Identifier\n"
2051 "Remote VTEP IP address\n"
2054 struct zebra_vrf
*zvrf
;
2055 struct in_addr vtep_ip
;
2056 bool uj
= use_json(argc
, argv
);
2058 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2060 vty_out(vty
, "%% Malformed VTEP IP address\n");
2063 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2064 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2070 DEFUN (show_evpn_mac_vni_mac
,
2071 show_evpn_mac_vni_mac_cmd
,
2072 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2076 "VxLAN Network Identifier\n"
2079 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2083 struct zebra_vrf
*zvrf
;
2086 bool uj
= use_json(argc
, argv
);
2088 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2089 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2090 vty_out(vty
, "%% Malformed MAC address");
2093 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2094 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2098 DEFUN (show_evpn_mac_vni_vtep
,
2099 show_evpn_mac_vni_vtep_cmd
,
2100 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2104 "VxLAN Network Identifier\n"
2107 "Remote VTEP IP address\n"
2110 struct zebra_vrf
*zvrf
;
2112 struct in_addr vtep_ip
;
2113 bool uj
= use_json(argc
, argv
);
2115 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2116 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2118 vty_out(vty
, "%% Malformed VTEP IP address\n");
2122 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2123 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2127 DEFPY (show_evpn_mac_vni_all_dad
,
2128 show_evpn_mac_vni_all_dad_cmd
,
2129 "show evpn mac vni all duplicate [json]",
2133 "VxLAN Network Identifier\n"
2135 "Duplicate address list\n"
2138 struct zebra_vrf
*zvrf
;
2139 bool uj
= use_json(argc
, argv
);
2141 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2142 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2147 DEFPY (show_evpn_mac_vni_dad
,
2148 show_evpn_mac_vni_dad_cmd
,
2149 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2153 "VxLAN Network Identifier\n"
2155 "Duplicate address list\n"
2158 struct zebra_vrf
*zvrf
;
2160 bool uj
= use_json(argc
, argv
);
2162 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2163 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2165 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2170 DEFPY (show_evpn_neigh_vni_dad
,
2171 show_evpn_neigh_vni_dad_cmd
,
2172 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2175 "ARP and ND cache\n"
2176 "VxLAN Network Identifier\n"
2178 "Duplicate address list\n"
2181 struct zebra_vrf
*zvrf
;
2183 bool uj
= use_json(argc
, argv
);
2185 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2186 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2187 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2191 DEFPY (show_evpn_neigh_vni_all_dad
,
2192 show_evpn_neigh_vni_all_dad_cmd
,
2193 "show evpn arp-cache vni all duplicate [json]",
2196 "ARP and ND cache\n"
2197 "VxLAN Network Identifier\n"
2199 "Duplicate address list\n"
2202 struct zebra_vrf
*zvrf
;
2203 bool uj
= use_json(argc
, argv
);
2205 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2206 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2211 DEFUN (show_evpn_neigh_vni
,
2212 show_evpn_neigh_vni_cmd
,
2213 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2216 "ARP and ND cache\n"
2217 "VxLAN Network Identifier\n"
2221 struct zebra_vrf
*zvrf
;
2223 bool uj
= use_json(argc
, argv
);
2225 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2226 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2227 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2231 DEFUN (show_evpn_neigh_vni_all
,
2232 show_evpn_neigh_vni_all_cmd
,
2233 "show evpn arp-cache vni all [json]",
2236 "ARP and ND cache\n"
2237 "VxLAN Network Identifier\n"
2241 struct zebra_vrf
*zvrf
;
2242 bool uj
= use_json(argc
, argv
);
2244 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2245 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2249 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2250 "show evpn arp-cache vni all detail [json]",
2253 "ARP and ND cache\n"
2254 "VxLAN Network Identifier\n"
2256 "Neighbor details for all vnis in detail\n" JSON_STR
)
2258 struct zebra_vrf
*zvrf
;
2259 bool uj
= use_json(argc
, argv
);
2261 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2262 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2266 DEFUN (show_evpn_neigh_vni_neigh
,
2267 show_evpn_neigh_vni_neigh_cmd
,
2268 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2271 "ARP and ND cache\n"
2272 "VxLAN Network Identifier\n"
2275 "Neighbor address (IPv4 or IPv6 address)\n"
2278 struct zebra_vrf
*zvrf
;
2281 bool uj
= use_json(argc
, argv
);
2283 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2284 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2286 vty_out(vty
, "%% Malformed Neighbor address\n");
2289 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2290 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2294 DEFUN (show_evpn_neigh_vni_vtep
,
2295 show_evpn_neigh_vni_vtep_cmd
,
2296 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2299 "ARP and ND cache\n"
2300 "VxLAN Network Identifier\n"
2303 "Remote VTEP IP address\n"
2306 struct zebra_vrf
*zvrf
;
2308 struct in_addr vtep_ip
;
2309 bool uj
= use_json(argc
, argv
);
2311 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2312 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2314 vty_out(vty
, "%% Malformed VTEP IP address\n");
2318 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2319 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2323 /* policy routing contexts */
2324 DEFUN (show_pbr_ipset
,
2326 "show pbr ipset [WORD]",
2328 "Policy-Based Routing\n"
2329 "IPset Context information\n"
2330 "IPset Name information\n")
2334 found
= argv_find(argv
, argc
, "WORD", &idx
);
2336 zebra_pbr_show_ipset_list(vty
, NULL
);
2338 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2342 /* policy routing contexts */
2343 DEFUN (show_pbr_iptable
,
2344 show_pbr_iptable_cmd
,
2345 "show pbr iptable [WORD]",
2347 "Policy-Based Routing\n"
2348 "IPtable Context information\n"
2349 "IPtable Name information\n")
2354 found
= argv_find(argv
, argc
, "WORD", &idx
);
2356 zebra_pbr_show_iptable(vty
, NULL
);
2358 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2362 DEFPY (clear_evpn_dup_addr
,
2363 clear_evpn_dup_addr_cmd
,
2364 "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>]>",
2367 "Duplicate address \n"
2368 "VxLAN Network Identifier\n"
2372 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2377 struct zebra_vrf
*zvrf
;
2379 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2380 struct ethaddr mac_addr
;
2381 int ret
= CMD_SUCCESS
;
2383 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2385 vni
= strtoul(vni_val
, NULL
, 10);
2388 prefix_str2mac(mac_val
, &mac_addr
);
2389 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2393 if (sockunion_family(ip
) == AF_INET
) {
2394 host_ip
.ipa_type
= IPADDR_V4
;
2395 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2397 host_ip
.ipa_type
= IPADDR_V6
;
2398 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2399 sizeof(struct in6_addr
));
2401 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2405 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2408 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2414 /* Static ip route configuration write function. */
2415 static int zebra_ip_config(struct vty
*vty
)
2419 write
+= zebra_import_table_config(vty
);
2424 DEFUN (ip_zebra_import_table_distance
,
2425 ip_zebra_import_table_distance_cmd
,
2426 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2428 "import routes from non-main kernel table\n"
2429 "kernel routing table id\n"
2430 "Distance for imported routes\n"
2431 "Default distance value\n"
2432 "route-map for filtering\n"
2435 uint32_t table_id
= 0;
2437 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2438 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2440 strmatch(argv
[argc
- 2]->text
, "route-map")
2441 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2445 if (argc
== 7 || (argc
== 5 && !rmap
))
2446 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2448 if (!is_zebra_valid_kernel_table(table_id
)) {
2450 "Invalid routing table ID, %d. Must be in range 1-252\n",
2453 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2457 if (is_zebra_main_routing_table(table_id
)) {
2459 "Invalid routing table ID, %d. Must be non-default table\n",
2462 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2466 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2468 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2473 DEFUN_HIDDEN (zebra_packet_process
,
2474 zebra_packet_process_cmd
,
2475 "zebra zapi-packets (1-10000)",
2478 "Number of packets to process before relinquishing thread\n")
2480 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2482 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2483 memory_order_relaxed
);
2488 DEFUN_HIDDEN (no_zebra_packet_process
,
2489 no_zebra_packet_process_cmd
,
2490 "no zebra zapi-packets [(1-10000)]",
2494 "Number of packets to process before relinquishing thread\n")
2496 atomic_store_explicit(&zebrad
.packets_to_process
,
2497 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2498 memory_order_relaxed
);
2503 DEFUN_HIDDEN (zebra_workqueue_timer
,
2504 zebra_workqueue_timer_cmd
,
2505 "zebra work-queue (0-10000)",
2508 "Time in milliseconds\n")
2510 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2511 zebrad
.ribq
->spec
.hold
= timer
;
2516 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2517 no_zebra_workqueue_timer_cmd
,
2518 "no zebra work-queue [(0-10000)]",
2522 "Time in milliseconds\n")
2524 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2529 DEFUN (no_ip_zebra_import_table
,
2530 no_ip_zebra_import_table_cmd
,
2531 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2534 "import routes from non-main kernel table\n"
2535 "kernel routing table id\n"
2536 "Distance for imported routes\n"
2537 "Default distance value\n"
2538 "route-map for filtering\n"
2541 uint32_t table_id
= 0;
2542 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2544 if (!is_zebra_valid_kernel_table(table_id
)) {
2546 "Invalid routing table ID. Must be in range 1-252\n");
2550 if (is_zebra_main_routing_table(table_id
)) {
2552 "Invalid routing table ID, %d. Must be non-default table\n",
2557 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2560 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2563 static int config_write_protocol(struct vty
*vty
)
2566 vty_out(vty
, "allow-external-route-update\n");
2568 if (zebra_rnh_ip_default_route
)
2569 vty_out(vty
, "ip nht resolve-via-default\n");
2571 if (zebra_rnh_ipv6_default_route
)
2572 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2574 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2575 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2577 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2578 vty_out(vty
, "zebra zapi-packets %u\n",
2579 zebrad
.packets_to_process
);
2581 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2583 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2584 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2585 ipv4_multicast_mode
== MCAST_URIB_ONLY
2587 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2589 : ipv4_multicast_mode
2590 == MCAST_MIX_MRIB_FIRST
2592 : ipv4_multicast_mode
2593 == MCAST_MIX_DISTANCE
2600 /* Display default rtm_table for all clients. */
2605 "default routing table to use for all clients\n")
2607 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2611 DEFUN (config_table
,
2614 "Configure target kernel routing table\n"
2617 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2621 DEFUN (no_config_table
,
2622 no_config_table_cmd
,
2623 "no table [TABLENO]",
2625 "Configure target kernel routing table\n"
2628 zebrad
.rtm_table_default
= 0;
2642 " Route Route Neighbor LSP LSP\n");
2644 "VRF Installs Removals Updates Installs Removals\n");
2646 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2647 struct zebra_vrf
*zvrf
= vrf
->info
;
2649 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2650 " %10" PRIu64
" %10" PRIu64
"\n",
2651 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2652 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2653 zvrf
->lsp_removals
);
2659 DEFUN (ip_forwarding
,
2663 "Turn on IP forwarding\n")
2669 ret
= ipforward_on();
2672 vty_out(vty
, "Can't turn on IP forwarding\n");
2673 return CMD_WARNING_CONFIG_FAILED
;
2679 DEFUN (no_ip_forwarding
,
2680 no_ip_forwarding_cmd
,
2684 "Turn off IP forwarding\n")
2690 ret
= ipforward_off();
2693 vty_out(vty
, "Can't turn off IP forwarding\n");
2694 return CMD_WARNING_CONFIG_FAILED
;
2700 /* Only display ip forwarding is enabled or not. */
2701 DEFUN (show_ip_forwarding
,
2702 show_ip_forwarding_cmd
,
2703 "show ip forwarding",
2706 "IP forwarding status\n")
2713 vty_out(vty
, "IP forwarding is off\n");
2715 vty_out(vty
, "IP forwarding is on\n");
2719 /* Only display ipv6 forwarding is enabled or not. */
2720 DEFUN (show_ipv6_forwarding
,
2721 show_ipv6_forwarding_cmd
,
2722 "show ipv6 forwarding",
2724 "IPv6 information\n"
2725 "Forwarding status\n")
2729 ret
= ipforward_ipv6();
2733 vty_out(vty
, "ipv6 forwarding is unknown\n");
2736 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2739 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2742 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2748 DEFUN (ipv6_forwarding
,
2749 ipv6_forwarding_cmd
,
2752 "Turn on IPv6 forwarding\n")
2756 ret
= ipforward_ipv6();
2758 ret
= ipforward_ipv6_on();
2761 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2762 return CMD_WARNING_CONFIG_FAILED
;
2768 DEFUN (no_ipv6_forwarding
,
2769 no_ipv6_forwarding_cmd
,
2770 "no ipv6 forwarding",
2773 "Turn off IPv6 forwarding\n")
2777 ret
= ipforward_ipv6();
2779 ret
= ipforward_ipv6_off();
2782 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2783 return CMD_WARNING_CONFIG_FAILED
;
2789 /* Display dataplane info */
2790 DEFUN (show_dataplane
,
2792 "show zebra dplane [detailed]",
2795 "Zebra dataplane information\n"
2796 "Detailed output\n")
2799 bool detailed
= false;
2801 if (argv_find(argv
, argc
, "detailed", &idx
))
2804 return dplane_show_helper(vty
, detailed
);
2807 /* Display dataplane providers info */
2808 DEFUN (show_dataplane_providers
,
2809 show_dataplane_providers_cmd
,
2810 "show zebra dplane providers [detailed]",
2813 "Zebra dataplane information\n"
2814 "Zebra dataplane provider information\n"
2815 "Detailed output\n")
2818 bool detailed
= false;
2820 if (argv_find(argv
, argc
, "detailed", &idx
))
2823 return dplane_show_provs_helper(vty
, detailed
);
2826 /* Configure dataplane incoming queue limit */
2827 DEFUN (zebra_dplane_queue_limit
,
2828 zebra_dplane_queue_limit_cmd
,
2829 "zebra dplane limit (0-10000)",
2832 "Limit incoming queued updates\n"
2833 "Number of queued updates\n")
2837 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2839 dplane_set_in_queue_limit(limit
, true);
2844 /* Reset dataplane queue limit to default value */
2845 DEFUN (no_zebra_dplane_queue_limit
,
2846 no_zebra_dplane_queue_limit_cmd
,
2847 "no zebra dplane limit [(0-10000)]",
2851 "Limit incoming queued updates\n"
2852 "Number of queued updates\n")
2854 dplane_set_in_queue_limit(0, false);
2859 DEFUN (zebra_show_routing_tables_summary
,
2860 zebra_show_routing_tables_summary_cmd
,
2861 "show zebra router table summary",
2864 "The Zebra Router Information\n"
2865 "Table Information about this Zebra Router\n"
2866 "Summary Information\n")
2868 zebra_router_show_table_summary(vty
);
2873 /* Table configuration write function. */
2874 static int config_write_table(struct vty
*vty
)
2876 if (zebrad
.rtm_table_default
)
2877 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2881 /* IPForwarding configuration write function. */
2882 static int config_write_forwarding(struct vty
*vty
)
2884 /* FIXME: Find better place for that. */
2885 router_id_write(vty
);
2888 vty_out(vty
, "no ip forwarding\n");
2889 if (!ipforward_ipv6())
2890 vty_out(vty
, "no ipv6 forwarding\n");
2891 vty_out(vty
, "!\n");
2895 /* IP node for static routes. */
2896 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2897 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2898 /* table node for routing tables. */
2899 static struct cmd_node table_node
= {TABLE_NODE
,
2900 "", /* This node has no interface. */
2902 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2903 "", /* This node has no interface. */
2907 void zebra_vty_init(void)
2909 /* Install configuration write function. */
2910 install_node(&table_node
, config_write_table
);
2911 install_node(&forwarding_node
, config_write_forwarding
);
2913 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2914 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2915 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2916 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2919 install_element(VIEW_NODE
, &show_table_cmd
);
2920 install_element(CONFIG_NODE
, &config_table_cmd
);
2921 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2922 #endif /* HAVE_NETLINK */
2924 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2925 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2926 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2929 zebra_route_map_init();
2931 install_node(&ip_node
, zebra_ip_config
);
2932 install_node(&protocol_node
, config_write_protocol
);
2934 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2935 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2937 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2938 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2940 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2941 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2942 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2943 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2944 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2945 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2947 install_element(VIEW_NODE
, &show_vrf_cmd
);
2948 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2949 install_element(VIEW_NODE
, &show_route_cmd
);
2950 install_element(VIEW_NODE
, &show_route_table_cmd
);
2951 if (vrf_is_backend_netns())
2952 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2953 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2954 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2955 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2956 install_element(VIEW_NODE
, &show_ip_import_check_cmd
);
2957 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2958 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2959 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2961 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2962 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2964 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2965 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2966 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2967 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2968 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2969 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2970 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2971 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2972 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2974 /* Commands for VRF */
2975 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2977 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2978 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2979 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
2980 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2981 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2982 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2983 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2984 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2985 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2986 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2987 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2988 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2989 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
2990 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2991 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2992 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2993 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2994 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2995 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2996 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2997 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2998 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2999 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3000 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3001 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3002 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3004 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3005 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3007 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3008 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3009 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3010 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3012 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3013 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3014 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3015 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3017 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);