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$ipv4|ipv6$ipv6> nht [vrf NAME$vrf_name|vrf all$vrf_all]",
939 "IP nexthop tracking table\n"
941 VRF_ALL_CMD_HELP_STR
)
943 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
944 vrf_id_t vrf_id
= VRF_DEFAULT
;
948 struct zebra_vrf
*zvrf
;
950 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
951 if ((zvrf
= vrf
->info
) != NULL
) {
952 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
953 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
959 VRF_GET_ID(vrf_id
, vrf_name
, false);
961 zebra_print_rnh_table(vrf_id
, afi
, vty
, RNH_NEXTHOP_TYPE
);
965 DEFPY (show_ip_import_check
,
966 show_ip_import_check_cmd
,
967 "show <ip$ipv4|ipv6$ipv6> import-check [vrf NAME$vrf_name|vrf all$vrf_all]",
971 "IP import check tracking table\n"
973 VRF_ALL_CMD_HELP_STR
)
975 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
976 vrf_id_t vrf_id
= VRF_DEFAULT
;
980 struct zebra_vrf
*zvrf
;
982 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
983 if ((zvrf
= vrf
->info
) != NULL
) {
984 vty_out(vty
, "\nVRF %s:\n",
986 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
987 RNH_IMPORT_CHECK_TYPE
);
992 VRF_GET_ID(vrf_id
, vrf_name
, false);
994 zebra_print_rnh_table(vrf_id
, afi
, vty
, RNH_IMPORT_CHECK_TYPE
);
998 DEFUN (ip_nht_default_route
,
999 ip_nht_default_route_cmd
,
1000 "ip nht resolve-via-default",
1002 "Filter Next Hop tracking route resolution\n"
1003 "Resolve via default route\n")
1005 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1010 if (zebra_rnh_ip_default_route
)
1013 zebra_rnh_ip_default_route
= 1;
1015 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1019 DEFUN (no_ip_nht_default_route
,
1020 no_ip_nht_default_route_cmd
,
1021 "no ip nht resolve-via-default",
1024 "Filter Next Hop tracking route resolution\n"
1025 "Resolve via default route\n")
1027 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1032 if (!zebra_rnh_ip_default_route
)
1035 zebra_rnh_ip_default_route
= 0;
1036 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1040 DEFUN (ipv6_nht_default_route
,
1041 ipv6_nht_default_route_cmd
,
1042 "ipv6 nht resolve-via-default",
1044 "Filter Next Hop tracking route resolution\n"
1045 "Resolve via default route\n")
1047 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1052 if (zebra_rnh_ipv6_default_route
)
1055 zebra_rnh_ipv6_default_route
= 1;
1056 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1060 DEFUN (no_ipv6_nht_default_route
,
1061 no_ipv6_nht_default_route_cmd
,
1062 "no ipv6 nht resolve-via-default",
1065 "Filter Next Hop tracking route resolution\n"
1066 "Resolve via default route\n")
1069 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1074 if (!zebra_rnh_ipv6_default_route
)
1077 zebra_rnh_ipv6_default_route
= 0;
1078 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1086 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1089 |A.B.C.D/M$prefix longer-prefixes\
1090 |supernets-only$supernets_only\
1093 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1094 |ospf$type_str (1-65535)$ospf_instance_id\
1096 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1099 |X:X::X:X/M$prefix longer-prefixes\
1101 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1106 "IP forwarding table\n"
1107 "IP routing table\n"
1108 VRF_FULL_CMD_HELP_STR
1109 "Show only routes with tag\n"
1111 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1112 "Show route matching the specified Network/Mask pair only\n"
1113 "Show supernet entries only\n"
1114 FRR_IP_REDIST_HELP_STR_ZEBRA
1115 "Open Shortest Path First (OSPFv2)\n"
1118 "IP forwarding table\n"
1119 "IP routing table\n"
1120 VRF_FULL_CMD_HELP_STR
1121 "Show only routes with tag\n"
1124 "Show route matching the specified Network/Mask pair only\n"
1125 FRR_IP6_REDIST_HELP_STR_ZEBRA
1128 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1133 type
= proto_redistnum(afi
, type_str
);
1135 vty_out(vty
, "Unknown route type\n");
1141 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1142 struct zebra_vrf
*zvrf
;
1143 struct route_table
*table
;
1145 if ((zvrf
= vrf
->info
) == NULL
1146 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1150 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1151 !!json
, tag
, prefix_str
? prefix
: NULL
,
1152 !!supernets_only
, type
, ospf_instance_id
);
1155 vrf_id_t vrf_id
= VRF_DEFAULT
;
1158 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1159 vrf
= vrf_lookup_by_id(vrf_id
);
1160 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1161 !!json
, tag
, prefix_str
? prefix
: NULL
,
1162 !!supernets_only
, type
, ospf_instance_id
);
1168 DEFPY (show_route_detail
,
1169 show_route_detail_cmd
,
1172 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1177 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1186 "IP routing table\n"
1187 VRF_FULL_CMD_HELP_STR
1188 "Network in the IP routing table to display\n"
1189 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1191 "IP routing table\n"
1192 VRF_FULL_CMD_HELP_STR
1197 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1198 struct route_table
*table
;
1200 struct route_node
*rn
;
1203 prefix_str
= address_str
;
1204 if (str2prefix(prefix_str
, &p
) < 0) {
1205 vty_out(vty
, "%% Malformed address\n");
1211 struct zebra_vrf
*zvrf
;
1213 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1214 if ((zvrf
= vrf
->info
) == NULL
1215 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1218 rn
= route_node_match(table
, &p
);
1221 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1222 route_unlock_node(rn
);
1227 vty_show_ip_route_detail_json(vty
, rn
);
1229 vty_show_ip_route_detail(vty
, rn
, 0);
1231 route_unlock_node(rn
);
1234 vrf_id_t vrf_id
= VRF_DEFAULT
;
1237 VRF_GET_ID(vrf_id
, vrf_name
, false);
1239 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1243 rn
= route_node_match(table
, &p
);
1245 vty_out(vty
, "%% Network not in table\n");
1248 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1249 vty_out(vty
, "%% Network not in table\n");
1250 route_unlock_node(rn
);
1255 vty_show_ip_route_detail_json(vty
, rn
);
1257 vty_show_ip_route_detail(vty
, rn
, 0);
1259 route_unlock_node(rn
);
1265 DEFPY (show_route_summary
,
1266 show_route_summary_cmd
,
1269 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1270 summary [prefix$prefix]\
1271 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1272 summary [prefix$prefix]\
1276 "IP routing table\n"
1277 VRF_FULL_CMD_HELP_STR
1278 "Summary of all routes\n"
1281 "IP routing table\n"
1282 VRF_FULL_CMD_HELP_STR
1283 "Summary of all routes\n"
1286 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1287 struct route_table
*table
;
1291 struct zebra_vrf
*zvrf
;
1293 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1294 if ((zvrf
= vrf
->info
) == NULL
1295 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1299 vty_show_ip_route_summary_prefix(vty
, table
);
1301 vty_show_ip_route_summary(vty
, table
);
1304 vrf_id_t vrf_id
= VRF_DEFAULT
;
1307 VRF_GET_ID(vrf_id
, vrf_name
, false);
1309 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1314 vty_show_ip_route_summary_prefix(vty
, table
);
1316 vty_show_ip_route_summary(vty
, table
);
1322 static void vty_show_ip_route_summary(struct vty
*vty
,
1323 struct route_table
*table
)
1325 struct route_node
*rn
;
1326 struct route_entry
*re
;
1327 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1328 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1329 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1330 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1334 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1335 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1336 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1337 RNODE_FOREACH_RE (rn
, re
) {
1338 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1339 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1341 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1343 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1345 rib_cnt
[re
->type
]++;
1347 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1348 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1351 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1353 fib_cnt
[re
->type
]++;
1357 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1358 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1360 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1361 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1362 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1363 if (i
== ZEBRA_ROUTE_BGP
) {
1364 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1365 rib_cnt
[ZEBRA_ROUTE_BGP
],
1366 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1367 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1368 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1369 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1371 vty_out(vty
, "%-20s %-20d %-20d \n",
1372 zebra_route_string(i
), rib_cnt
[i
],
1377 vty_out(vty
, "------\n");
1378 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1379 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1384 * Implementation of the ip route summary prefix command.
1386 * This command prints the primary prefixes that have been installed by various
1387 * protocols on the box.
1390 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1391 struct route_table
*table
)
1393 struct route_node
*rn
;
1394 struct route_entry
*re
;
1395 struct nexthop
*nexthop
;
1396 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1397 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1398 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1399 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1403 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1404 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1405 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1406 RNODE_FOREACH_RE (rn
, re
) {
1409 * In case of ECMP, count only once.
1412 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1413 nexthop
= nexthop
->next
) {
1415 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1416 rib_cnt
[re
->type
]++;
1417 if (CHECK_FLAG(nexthop
->flags
,
1418 NEXTHOP_FLAG_FIB
)) {
1419 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1420 fib_cnt
[re
->type
]++;
1422 if (re
->type
== ZEBRA_ROUTE_BGP
1423 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1424 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1425 if (CHECK_FLAG(nexthop
->flags
,
1427 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1432 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1433 "Prefix Routes", "FIB",
1434 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1436 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1437 if (rib_cnt
[i
] > 0) {
1438 if (i
== ZEBRA_ROUTE_BGP
) {
1439 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1440 rib_cnt
[ZEBRA_ROUTE_BGP
]
1441 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1442 fib_cnt
[ZEBRA_ROUTE_BGP
]
1443 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1444 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1445 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1446 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1448 vty_out(vty
, "%-20s %-20d %-20d \n",
1449 zebra_route_string(i
), rib_cnt
[i
],
1454 vty_out(vty
, "------\n");
1455 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1456 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1461 * Show IPv6 mroute command.Used to dump
1462 * the Multicast routing table.
1464 DEFUN (show_ipv6_mroute
,
1465 show_ipv6_mroute_cmd
,
1466 "show ipv6 mroute [vrf NAME]",
1469 "IPv6 Multicast routing table\n"
1472 struct route_table
*table
;
1473 struct route_node
*rn
;
1474 struct route_entry
*re
;
1476 vrf_id_t vrf_id
= VRF_DEFAULT
;
1479 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1481 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1485 /* Show all IPv6 route. */
1486 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1487 RNODE_FOREACH_RE (rn
, re
) {
1489 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1492 vty_show_ip_route(vty
, rn
, re
, NULL
);
1497 DEFUN (show_ipv6_mroute_vrf_all
,
1498 show_ipv6_mroute_vrf_all_cmd
,
1499 "show ipv6 mroute vrf all",
1502 "IPv6 Multicast routing table\n"
1503 VRF_ALL_CMD_HELP_STR
)
1505 struct route_table
*table
;
1506 struct route_node
*rn
;
1507 struct route_entry
*re
;
1509 struct zebra_vrf
*zvrf
;
1512 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1513 if ((zvrf
= vrf
->info
) == NULL
1514 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1517 /* Show all IPv6 route. */
1518 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1519 RNODE_FOREACH_RE (rn
, re
) {
1521 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1524 vty_show_ip_route(vty
, rn
, re
, NULL
);
1530 DEFUN (allow_external_route_update
,
1531 allow_external_route_update_cmd
,
1532 "allow-external-route-update",
1533 "Allow FRR routes to be overwritten by external processes\n")
1540 DEFUN (no_allow_external_route_update
,
1541 no_allow_external_route_update_cmd
,
1542 "no allow-external-route-update",
1544 "Allow FRR routes to be overwritten by external processes\n")
1559 struct zebra_vrf
*zvrf
;
1561 if (vrf_is_backend_netns())
1562 vty_out(vty
, "netns-based vrfs\n");
1564 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1565 if (!(zvrf
= vrf
->info
))
1567 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1570 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1571 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1572 vty_out(vty
, "inactive");
1573 else if (zvrf_ns_name(zvrf
))
1574 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1575 zvrf_ns_name(zvrf
));
1577 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1579 if (vrf_is_user_cfged(vrf
))
1580 vty_out(vty
, " (configured)");
1587 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1588 default_vrf_vni_mapping_cmd
,
1589 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1590 "VNI corresponding to the DEFAULT VRF\n"
1592 "Prefix routes only \n")
1595 char err
[ERR_STR_SZ
];
1596 struct zebra_vrf
*zvrf
= NULL
;
1597 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1600 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1607 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1610 vty_out(vty
, "%s\n", err
);
1617 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1618 no_default_vrf_vni_mapping_cmd
,
1619 "no vni " CMD_VNI_RANGE
,
1621 "VNI corresponding to DEFAULT VRF\n"
1625 char err
[ERR_STR_SZ
];
1626 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1627 struct zebra_vrf
*zvrf
= NULL
;
1629 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1633 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1635 vty_out(vty
, "%s\n", err
);
1642 DEFUN (vrf_vni_mapping
,
1643 vrf_vni_mapping_cmd
,
1644 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1645 "VNI corresponding to tenant VRF\n"
1647 "prefix-routes-only\n")
1652 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1653 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1654 char err
[ERR_STR_SZ
];
1662 /* Mark as having FRR configuration */
1663 vrf_set_user_cfged(vrf
);
1664 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1667 vty_out(vty
, "%s\n", err
);
1674 DEFUN (no_vrf_vni_mapping
,
1675 no_vrf_vni_mapping_cmd
,
1676 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1678 "VNI corresponding to tenant VRF\n"
1680 "prefix-routes-only\n")
1684 char err
[ERR_STR_SZ
];
1685 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1687 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1695 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1696 ERR_STR_SZ
, filter
, 0);
1698 vty_out(vty
, "%s\n", err
);
1702 /* If no other FRR config for this VRF, mark accordingly. */
1703 if (!zebra_vrf_has_config(zvrf
))
1704 vrf_reset_user_cfged(vrf
);
1710 DEFUN (show_vrf_vni
,
1712 "show vrf vni [json]",
1719 struct zebra_vrf
*zvrf
;
1720 json_object
*json
= NULL
;
1721 json_object
*json_vrfs
= NULL
;
1722 bool uj
= use_json(argc
, argv
);
1725 json
= json_object_new_object();
1726 json_vrfs
= json_object_new_array();
1730 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1731 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1733 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1738 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1742 json_object_object_add(json
, "vrfs", json_vrfs
);
1743 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1744 json
, JSON_C_TO_STRING_PRETTY
));
1745 json_object_free(json
);
1751 DEFUN (show_evpn_global
,
1752 show_evpn_global_cmd
,
1758 bool uj
= use_json(argc
, argv
);
1760 zebra_vxlan_print_evpn(vty
, uj
);
1764 DEFUN (show_evpn_vni
,
1766 "show evpn vni [json]",
1769 "VxLAN Network Identifier\n"
1772 struct zebra_vrf
*zvrf
;
1773 bool uj
= use_json(argc
, argv
);
1775 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1776 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1780 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1781 "show evpn vni detail [json]",
1784 "VxLAN Network Identifier\n"
1785 "Detailed Information On Each VNI\n"
1788 struct zebra_vrf
*zvrf
;
1789 bool uj
= use_json(argc
, argv
);
1791 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1792 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1796 DEFUN (show_evpn_vni_vni
,
1797 show_evpn_vni_vni_cmd
,
1798 "show evpn vni " CMD_VNI_RANGE
"[json]",
1801 "VxLAN Network Identifier\n"
1805 struct zebra_vrf
*zvrf
;
1807 bool uj
= use_json(argc
, argv
);
1809 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1810 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1811 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1815 DEFUN (show_evpn_rmac_vni_mac
,
1816 show_evpn_rmac_vni_mac_cmd
,
1817 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1824 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1829 bool uj
= use_json(argc
, argv
);
1831 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1832 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1833 vty_out(vty
, "%% Malformed MAC address\n");
1836 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1840 DEFUN (show_evpn_rmac_vni
,
1841 show_evpn_rmac_vni_cmd
,
1842 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1851 bool uj
= use_json(argc
, argv
);
1853 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1854 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1859 DEFUN (show_evpn_rmac_vni_all
,
1860 show_evpn_rmac_vni_all_cmd
,
1861 "show evpn rmac vni all [json]",
1869 bool uj
= use_json(argc
, argv
);
1871 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1876 DEFUN (show_evpn_nh_vni_ip
,
1877 show_evpn_nh_vni_ip_cmd
,
1878 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1885 "Host address (ipv4 or ipv6)\n"
1890 bool uj
= use_json(argc
, argv
);
1892 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1893 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1895 vty_out(vty
, "%% Malformed Neighbor address\n");
1898 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1903 DEFUN (show_evpn_nh_vni
,
1904 show_evpn_nh_vni_cmd
,
1905 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1914 bool uj
= use_json(argc
, argv
);
1916 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1917 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1922 DEFUN (show_evpn_nh_vni_all
,
1923 show_evpn_nh_vni_all_cmd
,
1924 "show evpn next-hops vni all [json]",
1932 bool uj
= use_json(argc
, argv
);
1934 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1939 DEFUN (show_evpn_mac_vni
,
1940 show_evpn_mac_vni_cmd
,
1941 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1945 "VxLAN Network Identifier\n"
1949 struct zebra_vrf
*zvrf
;
1951 bool uj
= use_json(argc
, argv
);
1953 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1954 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1955 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1959 DEFUN (show_evpn_mac_vni_all
,
1960 show_evpn_mac_vni_all_cmd
,
1961 "show evpn mac vni all [json]",
1965 "VxLAN Network Identifier\n"
1969 struct zebra_vrf
*zvrf
;
1970 bool uj
= use_json(argc
, argv
);
1972 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1973 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
1977 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
1978 "show evpn mac vni all detail [json]",
1982 "VxLAN Network Identifier\n"
1984 "Detailed Information On Each VNI MAC\n"
1987 struct zebra_vrf
*zvrf
;
1988 bool uj
= use_json(argc
, argv
);
1990 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1991 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
1995 DEFUN (show_evpn_mac_vni_all_vtep
,
1996 show_evpn_mac_vni_all_vtep_cmd
,
1997 "show evpn mac vni all vtep A.B.C.D [json]",
2001 "VxLAN Network Identifier\n"
2004 "Remote VTEP IP address\n"
2007 struct zebra_vrf
*zvrf
;
2008 struct in_addr vtep_ip
;
2009 bool uj
= use_json(argc
, argv
);
2011 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2013 vty_out(vty
, "%% Malformed VTEP IP address\n");
2016 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2017 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2023 DEFUN (show_evpn_mac_vni_mac
,
2024 show_evpn_mac_vni_mac_cmd
,
2025 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2029 "VxLAN Network Identifier\n"
2032 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2036 struct zebra_vrf
*zvrf
;
2039 bool uj
= use_json(argc
, argv
);
2041 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2042 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2043 vty_out(vty
, "%% Malformed MAC address");
2046 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2047 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2051 DEFUN (show_evpn_mac_vni_vtep
,
2052 show_evpn_mac_vni_vtep_cmd
,
2053 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2057 "VxLAN Network Identifier\n"
2060 "Remote VTEP IP address\n"
2063 struct zebra_vrf
*zvrf
;
2065 struct in_addr vtep_ip
;
2066 bool uj
= use_json(argc
, argv
);
2068 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2069 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2071 vty_out(vty
, "%% Malformed VTEP IP address\n");
2075 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2076 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2080 DEFPY (show_evpn_mac_vni_all_dad
,
2081 show_evpn_mac_vni_all_dad_cmd
,
2082 "show evpn mac vni all duplicate [json]",
2086 "VxLAN Network Identifier\n"
2088 "Duplicate address list\n"
2091 struct zebra_vrf
*zvrf
;
2092 bool uj
= use_json(argc
, argv
);
2094 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2095 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2100 DEFPY (show_evpn_mac_vni_dad
,
2101 show_evpn_mac_vni_dad_cmd
,
2102 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2106 "VxLAN Network Identifier\n"
2108 "Duplicate address list\n"
2111 struct zebra_vrf
*zvrf
;
2113 bool uj
= use_json(argc
, argv
);
2115 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2116 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2118 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2123 DEFPY (show_evpn_neigh_vni_dad
,
2124 show_evpn_neigh_vni_dad_cmd
,
2125 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2128 "ARP and ND cache\n"
2129 "VxLAN Network Identifier\n"
2131 "Duplicate address list\n"
2134 struct zebra_vrf
*zvrf
;
2136 bool uj
= use_json(argc
, argv
);
2138 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2139 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2140 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2144 DEFPY (show_evpn_neigh_vni_all_dad
,
2145 show_evpn_neigh_vni_all_dad_cmd
,
2146 "show evpn arp-cache vni all duplicate [json]",
2149 "ARP and ND cache\n"
2150 "VxLAN Network Identifier\n"
2152 "Duplicate address list\n"
2155 struct zebra_vrf
*zvrf
;
2156 bool uj
= use_json(argc
, argv
);
2158 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2159 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2164 DEFUN (show_evpn_neigh_vni
,
2165 show_evpn_neigh_vni_cmd
,
2166 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2169 "ARP and ND cache\n"
2170 "VxLAN Network Identifier\n"
2174 struct zebra_vrf
*zvrf
;
2176 bool uj
= use_json(argc
, argv
);
2178 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2179 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2180 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2184 DEFUN (show_evpn_neigh_vni_all
,
2185 show_evpn_neigh_vni_all_cmd
,
2186 "show evpn arp-cache vni all [json]",
2189 "ARP and ND cache\n"
2190 "VxLAN Network Identifier\n"
2194 struct zebra_vrf
*zvrf
;
2195 bool uj
= use_json(argc
, argv
);
2197 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2198 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2202 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2203 "show evpn arp-cache vni all detail [json]",
2206 "ARP and ND cache\n"
2207 "VxLAN Network Identifier\n"
2209 "Neighbor details for all vnis in detail\n" JSON_STR
)
2211 struct zebra_vrf
*zvrf
;
2212 bool uj
= use_json(argc
, argv
);
2214 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2215 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2219 DEFUN (show_evpn_neigh_vni_neigh
,
2220 show_evpn_neigh_vni_neigh_cmd
,
2221 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2224 "ARP and ND cache\n"
2225 "VxLAN Network Identifier\n"
2228 "Neighbor address (IPv4 or IPv6 address)\n"
2231 struct zebra_vrf
*zvrf
;
2234 bool uj
= use_json(argc
, argv
);
2236 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2237 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2239 vty_out(vty
, "%% Malformed Neighbor address\n");
2242 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2243 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2247 DEFUN (show_evpn_neigh_vni_vtep
,
2248 show_evpn_neigh_vni_vtep_cmd
,
2249 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2252 "ARP and ND cache\n"
2253 "VxLAN Network Identifier\n"
2256 "Remote VTEP IP address\n"
2259 struct zebra_vrf
*zvrf
;
2261 struct in_addr vtep_ip
;
2262 bool uj
= use_json(argc
, argv
);
2264 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2265 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2267 vty_out(vty
, "%% Malformed VTEP IP address\n");
2271 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2272 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2276 /* policy routing contexts */
2277 DEFUN (show_pbr_ipset
,
2279 "show pbr ipset [WORD]",
2281 "Policy-Based Routing\n"
2282 "IPset Context information\n"
2283 "IPset Name information\n")
2287 found
= argv_find(argv
, argc
, "WORD", &idx
);
2289 zebra_pbr_show_ipset_list(vty
, NULL
);
2291 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2295 /* policy routing contexts */
2296 DEFUN (show_pbr_iptable
,
2297 show_pbr_iptable_cmd
,
2298 "show pbr iptable [WORD]",
2300 "Policy-Based Routing\n"
2301 "IPtable Context information\n"
2302 "IPtable Name information\n")
2307 found
= argv_find(argv
, argc
, "WORD", &idx
);
2309 zebra_pbr_show_iptable(vty
, NULL
);
2311 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2315 DEFPY (clear_evpn_dup_addr
,
2316 clear_evpn_dup_addr_cmd
,
2317 "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>]>",
2320 "Duplicate address \n"
2321 "VxLAN Network Identifier\n"
2325 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2330 struct zebra_vrf
*zvrf
;
2332 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2333 struct ethaddr mac_addr
;
2334 int ret
= CMD_SUCCESS
;
2336 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2338 vni
= strtoul(vni_val
, NULL
, 10);
2341 prefix_str2mac(mac_val
, &mac_addr
);
2342 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2346 if (sockunion_family(ip
) == AF_INET
) {
2347 host_ip
.ipa_type
= IPADDR_V4
;
2348 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2350 host_ip
.ipa_type
= IPADDR_V6
;
2351 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2352 sizeof(struct in6_addr
));
2354 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2358 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2361 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2367 /* Static ip route configuration write function. */
2368 static int zebra_ip_config(struct vty
*vty
)
2372 write
+= zebra_import_table_config(vty
);
2377 DEFUN (ip_zebra_import_table_distance
,
2378 ip_zebra_import_table_distance_cmd
,
2379 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2381 "import routes from non-main kernel table\n"
2382 "kernel routing table id\n"
2383 "Distance for imported routes\n"
2384 "Default distance value\n"
2385 "route-map for filtering\n"
2388 uint32_t table_id
= 0;
2390 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2391 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2393 strmatch(argv
[argc
- 2]->text
, "route-map")
2394 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2398 if (argc
== 7 || (argc
== 5 && !rmap
))
2399 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2401 if (!is_zebra_valid_kernel_table(table_id
)) {
2403 "Invalid routing table ID, %d. Must be in range 1-252\n",
2406 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2410 if (is_zebra_main_routing_table(table_id
)) {
2412 "Invalid routing table ID, %d. Must be non-default table\n",
2415 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2419 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2421 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2426 DEFUN_HIDDEN (zebra_packet_process
,
2427 zebra_packet_process_cmd
,
2428 "zebra zapi-packets (1-10000)",
2431 "Number of packets to process before relinquishing thread\n")
2433 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2435 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2436 memory_order_relaxed
);
2441 DEFUN_HIDDEN (no_zebra_packet_process
,
2442 no_zebra_packet_process_cmd
,
2443 "no zebra zapi-packets [(1-10000)]",
2447 "Number of packets to process before relinquishing thread\n")
2449 atomic_store_explicit(&zebrad
.packets_to_process
,
2450 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2451 memory_order_relaxed
);
2456 DEFUN_HIDDEN (zebra_workqueue_timer
,
2457 zebra_workqueue_timer_cmd
,
2458 "zebra work-queue (0-10000)",
2461 "Time in milliseconds\n")
2463 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2464 zebrad
.ribq
->spec
.hold
= timer
;
2469 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2470 no_zebra_workqueue_timer_cmd
,
2471 "no zebra work-queue [(0-10000)]",
2475 "Time in milliseconds\n")
2477 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2482 DEFUN (no_ip_zebra_import_table
,
2483 no_ip_zebra_import_table_cmd
,
2484 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2487 "import routes from non-main kernel table\n"
2488 "kernel routing table id\n"
2489 "Distance for imported routes\n"
2490 "Default distance value\n"
2491 "route-map for filtering\n"
2494 uint32_t table_id
= 0;
2495 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2497 if (!is_zebra_valid_kernel_table(table_id
)) {
2499 "Invalid routing table ID. Must be in range 1-252\n");
2503 if (is_zebra_main_routing_table(table_id
)) {
2505 "Invalid routing table ID, %d. Must be non-default table\n",
2510 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2513 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2516 static int config_write_protocol(struct vty
*vty
)
2519 vty_out(vty
, "allow-external-route-update\n");
2521 if (zebra_rnh_ip_default_route
)
2522 vty_out(vty
, "ip nht resolve-via-default\n");
2524 if (zebra_rnh_ipv6_default_route
)
2525 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2527 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2528 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2530 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2531 vty_out(vty
, "zebra zapi-packets %u\n",
2532 zebrad
.packets_to_process
);
2534 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2536 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2537 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2538 ipv4_multicast_mode
== MCAST_URIB_ONLY
2540 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2542 : ipv4_multicast_mode
2543 == MCAST_MIX_MRIB_FIRST
2545 : ipv4_multicast_mode
2546 == MCAST_MIX_DISTANCE
2553 /* Display default rtm_table for all clients. */
2558 "default routing table to use for all clients\n")
2560 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2564 DEFUN (config_table
,
2567 "Configure target kernel routing table\n"
2570 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2574 DEFUN (no_config_table
,
2575 no_config_table_cmd
,
2576 "no table [TABLENO]",
2578 "Configure target kernel routing table\n"
2581 zebrad
.rtm_table_default
= 0;
2595 " Route Route Neighbor LSP LSP\n");
2597 "VRF Installs Removals Updates Installs Removals\n");
2599 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2600 struct zebra_vrf
*zvrf
= vrf
->info
;
2602 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2603 " %10" PRIu64
" %10" PRIu64
"\n",
2604 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2605 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2606 zvrf
->lsp_removals
);
2612 DEFUN (ip_forwarding
,
2616 "Turn on IP forwarding\n")
2622 ret
= ipforward_on();
2625 vty_out(vty
, "Can't turn on IP forwarding\n");
2626 return CMD_WARNING_CONFIG_FAILED
;
2632 DEFUN (no_ip_forwarding
,
2633 no_ip_forwarding_cmd
,
2637 "Turn off IP forwarding\n")
2643 ret
= ipforward_off();
2646 vty_out(vty
, "Can't turn off IP forwarding\n");
2647 return CMD_WARNING_CONFIG_FAILED
;
2653 /* Only display ip forwarding is enabled or not. */
2654 DEFUN (show_ip_forwarding
,
2655 show_ip_forwarding_cmd
,
2656 "show ip forwarding",
2659 "IP forwarding status\n")
2666 vty_out(vty
, "IP forwarding is off\n");
2668 vty_out(vty
, "IP forwarding is on\n");
2672 /* Only display ipv6 forwarding is enabled or not. */
2673 DEFUN (show_ipv6_forwarding
,
2674 show_ipv6_forwarding_cmd
,
2675 "show ipv6 forwarding",
2677 "IPv6 information\n"
2678 "Forwarding status\n")
2682 ret
= ipforward_ipv6();
2686 vty_out(vty
, "ipv6 forwarding is unknown\n");
2689 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2692 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2695 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2701 DEFUN (ipv6_forwarding
,
2702 ipv6_forwarding_cmd
,
2705 "Turn on IPv6 forwarding\n")
2709 ret
= ipforward_ipv6();
2711 ret
= ipforward_ipv6_on();
2714 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2715 return CMD_WARNING_CONFIG_FAILED
;
2721 DEFUN (no_ipv6_forwarding
,
2722 no_ipv6_forwarding_cmd
,
2723 "no ipv6 forwarding",
2726 "Turn off IPv6 forwarding\n")
2730 ret
= ipforward_ipv6();
2732 ret
= ipforward_ipv6_off();
2735 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2736 return CMD_WARNING_CONFIG_FAILED
;
2742 /* Display dataplane info */
2743 DEFUN (show_dataplane
,
2745 "show zebra dplane [detailed]",
2748 "Zebra dataplane information\n"
2749 "Detailed output\n")
2752 bool detailed
= false;
2754 if (argv_find(argv
, argc
, "detailed", &idx
))
2757 return dplane_show_helper(vty
, detailed
);
2760 /* Display dataplane providers info */
2761 DEFUN (show_dataplane_providers
,
2762 show_dataplane_providers_cmd
,
2763 "show zebra dplane providers [detailed]",
2766 "Zebra dataplane information\n"
2767 "Zebra dataplane provider information\n"
2768 "Detailed output\n")
2771 bool detailed
= false;
2773 if (argv_find(argv
, argc
, "detailed", &idx
))
2776 return dplane_show_provs_helper(vty
, detailed
);
2779 /* Configure dataplane incoming queue limit */
2780 DEFUN (zebra_dplane_queue_limit
,
2781 zebra_dplane_queue_limit_cmd
,
2782 "zebra dplane limit (0-10000)",
2785 "Limit incoming queued updates\n"
2786 "Number of queued updates\n")
2790 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2792 dplane_set_in_queue_limit(limit
, true);
2797 /* Reset dataplane queue limit to default value */
2798 DEFUN (no_zebra_dplane_queue_limit
,
2799 no_zebra_dplane_queue_limit_cmd
,
2800 "no zebra dplane limit [(0-10000)]",
2804 "Limit incoming queued updates\n"
2805 "Number of queued updates\n")
2807 dplane_set_in_queue_limit(0, false);
2812 DEFUN (zebra_show_routing_tables_summary
,
2813 zebra_show_routing_tables_summary_cmd
,
2814 "show zebra router table summary",
2817 "The Zebra Router Information\n"
2818 "Table Information about this Zebra Router\n"
2819 "Summary Information\n")
2821 zebra_router_show_table_summary(vty
);
2826 /* Table configuration write function. */
2827 static int config_write_table(struct vty
*vty
)
2829 if (zebrad
.rtm_table_default
)
2830 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2834 /* IPForwarding configuration write function. */
2835 static int config_write_forwarding(struct vty
*vty
)
2837 /* FIXME: Find better place for that. */
2838 router_id_write(vty
);
2841 vty_out(vty
, "no ip forwarding\n");
2842 if (!ipforward_ipv6())
2843 vty_out(vty
, "no ipv6 forwarding\n");
2844 vty_out(vty
, "!\n");
2848 /* IP node for static routes. */
2849 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2850 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2851 /* table node for routing tables. */
2852 static struct cmd_node table_node
= {TABLE_NODE
,
2853 "", /* This node has no interface. */
2855 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2856 "", /* This node has no interface. */
2860 void zebra_vty_init(void)
2862 /* Install configuration write function. */
2863 install_node(&table_node
, config_write_table
);
2864 install_node(&forwarding_node
, config_write_forwarding
);
2866 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2867 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2868 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2869 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2872 install_element(VIEW_NODE
, &show_table_cmd
);
2873 install_element(CONFIG_NODE
, &config_table_cmd
);
2874 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2875 #endif /* HAVE_NETLINK */
2877 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2878 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2879 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2882 zebra_route_map_init();
2884 install_node(&ip_node
, zebra_ip_config
);
2885 install_node(&protocol_node
, config_write_protocol
);
2887 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2888 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2890 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2891 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2893 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2894 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2895 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2896 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2897 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2898 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2900 install_element(VIEW_NODE
, &show_vrf_cmd
);
2901 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2902 install_element(VIEW_NODE
, &show_route_cmd
);
2903 install_element(VIEW_NODE
, &show_route_table_cmd
);
2904 if (vrf_is_backend_netns())
2905 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2906 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2907 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2908 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2909 install_element(VIEW_NODE
, &show_ip_import_check_cmd
);
2911 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2912 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2914 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2915 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2916 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2917 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2918 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2919 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2920 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2921 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2922 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2924 /* Commands for VRF */
2925 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2927 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2928 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2929 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
2930 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2931 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2932 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2933 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2934 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2935 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2936 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2937 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2938 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2939 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
2940 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2941 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2942 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2943 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2944 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2945 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2946 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2947 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2948 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2949 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2950 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
2951 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
2952 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
2954 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2955 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2957 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2958 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2959 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2960 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2962 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2963 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2964 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2965 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
2967 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);