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();
736 RNODE_FOREACH_RE (rn
, re
) {
737 json_prefix
= json_object_new_array();
738 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
739 prefix2str(&rn
->p
, buf
, sizeof buf
);
740 json_object_object_add(json
, buf
, json_prefix
);
744 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
745 json
, JSON_C_TO_STRING_PRETTY
));
746 json_object_free(json
);
749 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
750 struct route_table
*table
, afi_t afi
,
751 bool use_fib
, route_tag_t tag
,
752 const struct prefix
*longer_prefix_p
,
753 bool supernets_only
, int type
,
754 unsigned short ospf_instance_id
, bool use_json
)
756 struct route_node
*rn
;
757 struct route_entry
*re
;
760 json_object
*json
= NULL
;
761 json_object
*json_prefix
= NULL
;
766 json
= json_object_new_object();
768 /* Show all routes. */
769 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
770 dest
= rib_dest_from_rnode(rn
);
772 RNODE_FOREACH_RE (rn
, re
) {
773 if (use_fib
&& re
!= dest
->selected_fib
)
776 if (tag
&& re
->tag
!= tag
)
780 && !prefix_match(longer_prefix_p
, &rn
->p
))
783 /* This can only be true when the afi is IPv4 */
784 if (supernets_only
) {
785 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
787 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
790 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
793 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
797 if (type
&& re
->type
!= type
)
801 && (re
->type
!= ZEBRA_ROUTE_OSPF
802 || re
->instance
!= ospf_instance_id
))
807 json_prefix
= json_object_new_array();
812 SHOW_ROUTE_V4_HEADER
);
815 SHOW_ROUTE_V6_HEADER
);
817 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
818 vty_out(vty
, "\nVRF %s:\n",
825 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
829 prefix2str(&rn
->p
, buf
, sizeof(buf
));
830 json_object_object_add(json
, buf
, json_prefix
);
836 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
837 JSON_C_TO_STRING_PRETTY
));
838 json_object_free(json
);
842 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
843 safi_t safi
, bool use_fib
, bool use_json
,
845 const struct prefix
*longer_prefix_p
,
846 bool supernets_only
, int type
,
847 unsigned short ospf_instance_id
)
849 struct route_table
*table
;
850 struct zebra_vrf
*zvrf
= NULL
;
852 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
854 vty_out(vty
, "{}\n");
856 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
860 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
862 vty_out(vty
, "{}\n");
864 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
868 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
871 vty_out(vty
, "{}\n");
875 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
876 longer_prefix_p
, supernets_only
, type
,
877 ospf_instance_id
, use_json
);
882 DEFPY (show_route_table
,
883 show_route_table_cmd
,
884 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
890 "The table number to display, if available\n"
893 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
894 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
895 struct route_table
*t
;
897 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
899 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
905 DEFPY (show_route_table_vrf
,
906 show_route_table_vrf_cmd
,
907 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
913 "The table number to display, if available\n"
917 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
918 struct zebra_vrf
*zvrf
;
919 struct route_table
*t
;
920 vrf_id_t vrf_id
= VRF_DEFAULT
;
923 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
924 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
926 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
928 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
936 "show ip nht [vrf NAME]",
939 "IP nexthop tracking table\n"
943 vrf_id_t vrf_id
= VRF_DEFAULT
;
946 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
948 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
953 DEFUN (show_ip_nht_vrf_all
,
954 show_ip_nht_vrf_all_cmd
,
955 "show ip nht vrf all",
958 "IP nexthop tracking table\n"
959 VRF_ALL_CMD_HELP_STR
)
962 struct zebra_vrf
*zvrf
;
964 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
965 if ((zvrf
= vrf
->info
) != NULL
) {
966 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
967 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
974 DEFUN (show_ipv6_nht
,
976 "show ipv6 nht [vrf NAME]",
979 "IPv6 nexthop tracking table\n"
983 vrf_id_t vrf_id
= VRF_DEFAULT
;
986 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
, false);
988 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
993 DEFUN (show_ipv6_nht_vrf_all
,
994 show_ipv6_nht_vrf_all_cmd
,
995 "show ipv6 nht vrf all",
998 "IPv6 nexthop tracking table\n"
999 VRF_ALL_CMD_HELP_STR
)
1002 struct zebra_vrf
*zvrf
;
1004 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1005 if ((zvrf
= vrf
->info
) != NULL
) {
1006 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1007 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1014 DEFUN (ip_nht_default_route
,
1015 ip_nht_default_route_cmd
,
1016 "ip nht resolve-via-default",
1018 "Filter Next Hop tracking route resolution\n"
1019 "Resolve via default route\n")
1021 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1026 if (zebra_rnh_ip_default_route
)
1029 zebra_rnh_ip_default_route
= 1;
1031 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1035 DEFUN (no_ip_nht_default_route
,
1036 no_ip_nht_default_route_cmd
,
1037 "no ip nht resolve-via-default",
1040 "Filter Next Hop tracking route resolution\n"
1041 "Resolve via default route\n")
1043 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1048 if (!zebra_rnh_ip_default_route
)
1051 zebra_rnh_ip_default_route
= 0;
1052 zebra_evaluate_rnh(zvrf
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1056 DEFUN (ipv6_nht_default_route
,
1057 ipv6_nht_default_route_cmd
,
1058 "ipv6 nht resolve-via-default",
1060 "Filter Next Hop tracking route resolution\n"
1061 "Resolve via default route\n")
1063 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1068 if (zebra_rnh_ipv6_default_route
)
1071 zebra_rnh_ipv6_default_route
= 1;
1072 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1076 DEFUN (no_ipv6_nht_default_route
,
1077 no_ipv6_nht_default_route_cmd
,
1078 "no ipv6 nht resolve-via-default",
1081 "Filter Next Hop tracking route resolution\n"
1082 "Resolve via default route\n")
1085 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1090 if (!zebra_rnh_ipv6_default_route
)
1093 zebra_rnh_ipv6_default_route
= 0;
1094 zebra_evaluate_rnh(zvrf
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1102 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1105 |A.B.C.D/M$prefix longer-prefixes\
1106 |supernets-only$supernets_only\
1109 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1110 |ospf$type_str (1-65535)$ospf_instance_id\
1112 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1115 |X:X::X:X/M$prefix longer-prefixes\
1117 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1122 "IP forwarding table\n"
1123 "IP routing table\n"
1124 VRF_FULL_CMD_HELP_STR
1125 "Show only routes with tag\n"
1127 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1128 "Show route matching the specified Network/Mask pair only\n"
1129 "Show supernet entries only\n"
1130 FRR_IP_REDIST_HELP_STR_ZEBRA
1131 "Open Shortest Path First (OSPFv2)\n"
1134 "IP forwarding table\n"
1135 "IP routing table\n"
1136 VRF_FULL_CMD_HELP_STR
1137 "Show only routes with tag\n"
1140 "Show route matching the specified Network/Mask pair only\n"
1141 FRR_IP6_REDIST_HELP_STR_ZEBRA
1144 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1149 type
= proto_redistnum(afi
, type_str
);
1151 vty_out(vty
, "Unknown route type\n");
1157 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1158 struct zebra_vrf
*zvrf
;
1159 struct route_table
*table
;
1161 if ((zvrf
= vrf
->info
) == NULL
1162 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1166 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1167 !!json
, tag
, prefix_str
? prefix
: NULL
,
1168 !!supernets_only
, type
, ospf_instance_id
);
1171 vrf_id_t vrf_id
= VRF_DEFAULT
;
1174 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1175 vrf
= vrf_lookup_by_id(vrf_id
);
1176 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1177 !!json
, tag
, prefix_str
? prefix
: NULL
,
1178 !!supernets_only
, type
, ospf_instance_id
);
1184 DEFPY (show_route_detail
,
1185 show_route_detail_cmd
,
1188 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1193 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1202 "IP routing table\n"
1203 VRF_FULL_CMD_HELP_STR
1204 "Network in the IP routing table to display\n"
1205 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1207 "IP routing table\n"
1208 VRF_FULL_CMD_HELP_STR
1213 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1214 struct route_table
*table
;
1216 struct route_node
*rn
;
1219 prefix_str
= address_str
;
1220 if (str2prefix(prefix_str
, &p
) < 0) {
1221 vty_out(vty
, "%% Malformed address\n");
1227 struct zebra_vrf
*zvrf
;
1229 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1230 if ((zvrf
= vrf
->info
) == NULL
1231 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1234 rn
= route_node_match(table
, &p
);
1237 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1238 route_unlock_node(rn
);
1243 vty_show_ip_route_detail_json(vty
, rn
);
1245 vty_show_ip_route_detail(vty
, rn
, 0);
1247 route_unlock_node(rn
);
1250 vrf_id_t vrf_id
= VRF_DEFAULT
;
1253 VRF_GET_ID(vrf_id
, vrf_name
, false);
1255 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1259 rn
= route_node_match(table
, &p
);
1261 vty_out(vty
, "%% Network not in table\n");
1264 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1265 vty_out(vty
, "%% Network not in table\n");
1266 route_unlock_node(rn
);
1271 vty_show_ip_route_detail_json(vty
, rn
);
1273 vty_show_ip_route_detail(vty
, rn
, 0);
1275 route_unlock_node(rn
);
1281 DEFPY (show_route_summary
,
1282 show_route_summary_cmd
,
1285 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1286 summary [prefix$prefix]\
1287 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1288 summary [prefix$prefix]\
1292 "IP routing table\n"
1293 VRF_FULL_CMD_HELP_STR
1294 "Summary of all routes\n"
1297 "IP routing table\n"
1298 VRF_FULL_CMD_HELP_STR
1299 "Summary of all routes\n"
1302 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1303 struct route_table
*table
;
1307 struct zebra_vrf
*zvrf
;
1309 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1310 if ((zvrf
= vrf
->info
) == NULL
1311 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1315 vty_show_ip_route_summary_prefix(vty
, table
);
1317 vty_show_ip_route_summary(vty
, table
);
1320 vrf_id_t vrf_id
= VRF_DEFAULT
;
1323 VRF_GET_ID(vrf_id
, vrf_name
, false);
1325 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1330 vty_show_ip_route_summary_prefix(vty
, table
);
1332 vty_show_ip_route_summary(vty
, table
);
1338 static void vty_show_ip_route_summary(struct vty
*vty
,
1339 struct route_table
*table
)
1341 struct route_node
*rn
;
1342 struct route_entry
*re
;
1343 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1344 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1345 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1346 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1350 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1351 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1352 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1353 RNODE_FOREACH_RE (rn
, re
) {
1354 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1355 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1357 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1359 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1361 rib_cnt
[re
->type
]++;
1363 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1364 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1367 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1369 fib_cnt
[re
->type
]++;
1373 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1374 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1376 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1377 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1378 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1379 if (i
== ZEBRA_ROUTE_BGP
) {
1380 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1381 rib_cnt
[ZEBRA_ROUTE_BGP
],
1382 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1383 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1384 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1385 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1387 vty_out(vty
, "%-20s %-20d %-20d \n",
1388 zebra_route_string(i
), rib_cnt
[i
],
1393 vty_out(vty
, "------\n");
1394 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1395 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1400 * Implementation of the ip route summary prefix command.
1402 * This command prints the primary prefixes that have been installed by various
1403 * protocols on the box.
1406 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1407 struct route_table
*table
)
1409 struct route_node
*rn
;
1410 struct route_entry
*re
;
1411 struct nexthop
*nexthop
;
1412 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1413 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1414 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1415 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1419 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1420 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1421 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1422 RNODE_FOREACH_RE (rn
, re
) {
1425 * In case of ECMP, count only once.
1428 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1429 nexthop
= nexthop
->next
) {
1431 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1432 rib_cnt
[re
->type
]++;
1433 if (CHECK_FLAG(nexthop
->flags
,
1434 NEXTHOP_FLAG_FIB
)) {
1435 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1436 fib_cnt
[re
->type
]++;
1438 if (re
->type
== ZEBRA_ROUTE_BGP
1439 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1440 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1441 if (CHECK_FLAG(nexthop
->flags
,
1443 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1448 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1449 "Prefix Routes", "FIB",
1450 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1452 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1453 if (rib_cnt
[i
] > 0) {
1454 if (i
== ZEBRA_ROUTE_BGP
) {
1455 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1456 rib_cnt
[ZEBRA_ROUTE_BGP
]
1457 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1458 fib_cnt
[ZEBRA_ROUTE_BGP
]
1459 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1460 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1461 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1462 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1464 vty_out(vty
, "%-20s %-20d %-20d \n",
1465 zebra_route_string(i
), rib_cnt
[i
],
1470 vty_out(vty
, "------\n");
1471 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1472 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1477 * Show IPv6 mroute command.Used to dump
1478 * the Multicast routing table.
1480 DEFUN (show_ipv6_mroute
,
1481 show_ipv6_mroute_cmd
,
1482 "show ipv6 mroute [vrf NAME]",
1485 "IPv6 Multicast routing table\n"
1488 struct route_table
*table
;
1489 struct route_node
*rn
;
1490 struct route_entry
*re
;
1492 vrf_id_t vrf_id
= VRF_DEFAULT
;
1495 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1497 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1501 /* Show all IPv6 route. */
1502 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1503 RNODE_FOREACH_RE (rn
, re
) {
1505 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1508 vty_show_ip_route(vty
, rn
, re
, NULL
);
1513 DEFUN (show_ipv6_mroute_vrf_all
,
1514 show_ipv6_mroute_vrf_all_cmd
,
1515 "show ipv6 mroute vrf all",
1518 "IPv6 Multicast routing table\n"
1519 VRF_ALL_CMD_HELP_STR
)
1521 struct route_table
*table
;
1522 struct route_node
*rn
;
1523 struct route_entry
*re
;
1525 struct zebra_vrf
*zvrf
;
1528 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1529 if ((zvrf
= vrf
->info
) == NULL
1530 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1533 /* Show all IPv6 route. */
1534 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1535 RNODE_FOREACH_RE (rn
, re
) {
1537 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1540 vty_show_ip_route(vty
, rn
, re
, NULL
);
1546 DEFUN (allow_external_route_update
,
1547 allow_external_route_update_cmd
,
1548 "allow-external-route-update",
1549 "Allow FRR routes to be overwritten by external processes\n")
1556 DEFUN (no_allow_external_route_update
,
1557 no_allow_external_route_update_cmd
,
1558 "no allow-external-route-update",
1560 "Allow FRR routes to be overwritten by external processes\n")
1575 struct zebra_vrf
*zvrf
;
1577 if (vrf_is_backend_netns())
1578 vty_out(vty
, "netns-based vrfs\n");
1580 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1581 if (!(zvrf
= vrf
->info
))
1583 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1586 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1587 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1588 vty_out(vty
, "inactive");
1589 else if (zvrf_ns_name(zvrf
))
1590 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1591 zvrf_ns_name(zvrf
));
1593 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1595 if (vrf_is_user_cfged(vrf
))
1596 vty_out(vty
, " (configured)");
1603 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1604 default_vrf_vni_mapping_cmd
,
1605 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1606 "VNI corresponding to the DEFAULT VRF\n"
1608 "Prefix routes only \n")
1611 char err
[ERR_STR_SZ
];
1612 struct zebra_vrf
*zvrf
= NULL
;
1613 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1616 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1623 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1626 vty_out(vty
, "%s\n", err
);
1633 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1634 no_default_vrf_vni_mapping_cmd
,
1635 "no vni " CMD_VNI_RANGE
,
1637 "VNI corresponding to DEFAULT VRF\n"
1641 char err
[ERR_STR_SZ
];
1642 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1643 struct zebra_vrf
*zvrf
= NULL
;
1645 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1649 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1651 vty_out(vty
, "%s\n", err
);
1658 DEFUN (vrf_vni_mapping
,
1659 vrf_vni_mapping_cmd
,
1660 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1661 "VNI corresponding to tenant VRF\n"
1663 "prefix-routes-only\n")
1668 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1669 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1670 char err
[ERR_STR_SZ
];
1678 /* Mark as having FRR configuration */
1679 vrf_set_user_cfged(vrf
);
1680 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1683 vty_out(vty
, "%s\n", err
);
1690 DEFUN (no_vrf_vni_mapping
,
1691 no_vrf_vni_mapping_cmd
,
1692 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1694 "VNI corresponding to tenant VRF\n"
1696 "prefix-routes-only\n")
1700 char err
[ERR_STR_SZ
];
1701 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1703 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1711 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1712 ERR_STR_SZ
, filter
, 0);
1714 vty_out(vty
, "%s\n", err
);
1718 /* If no other FRR config for this VRF, mark accordingly. */
1719 if (!zebra_vrf_has_config(zvrf
))
1720 vrf_reset_user_cfged(vrf
);
1726 DEFUN (show_vrf_vni
,
1728 "show vrf vni [json]",
1735 struct zebra_vrf
*zvrf
;
1736 json_object
*json
= NULL
;
1737 json_object
*json_vrfs
= NULL
;
1738 bool uj
= use_json(argc
, argv
);
1741 json
= json_object_new_object();
1742 json_vrfs
= json_object_new_array();
1746 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1747 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1749 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1754 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1758 json_object_object_add(json
, "vrfs", json_vrfs
);
1759 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1760 json
, JSON_C_TO_STRING_PRETTY
));
1761 json_object_free(json
);
1767 DEFUN (show_evpn_global
,
1768 show_evpn_global_cmd
,
1774 bool uj
= use_json(argc
, argv
);
1776 zebra_vxlan_print_evpn(vty
, uj
);
1780 DEFUN (show_evpn_vni
,
1782 "show evpn vni [json]",
1785 "VxLAN information\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(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_vtep
,
1978 show_evpn_mac_vni_all_vtep_cmd
,
1979 "show evpn mac vni all vtep A.B.C.D [json]",
1983 "VxLAN Network Identifier\n"
1986 "Remote VTEP IP address\n"
1989 struct zebra_vrf
*zvrf
;
1990 struct in_addr vtep_ip
;
1991 bool uj
= use_json(argc
, argv
);
1993 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
1995 vty_out(vty
, "%% Malformed VTEP IP address\n");
1998 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1999 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2005 DEFUN (show_evpn_mac_vni_mac
,
2006 show_evpn_mac_vni_mac_cmd
,
2007 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2011 "VxLAN Network Identifier\n"
2014 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2018 struct zebra_vrf
*zvrf
;
2021 bool uj
= use_json(argc
, argv
);
2023 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2024 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2025 vty_out(vty
, "%% Malformed MAC address");
2028 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2029 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2033 DEFUN (show_evpn_mac_vni_vtep
,
2034 show_evpn_mac_vni_vtep_cmd
,
2035 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2039 "VxLAN Network Identifier\n"
2042 "Remote VTEP IP address\n"
2045 struct zebra_vrf
*zvrf
;
2047 struct in_addr vtep_ip
;
2048 bool uj
= use_json(argc
, argv
);
2050 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2051 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2053 vty_out(vty
, "%% Malformed VTEP IP address\n");
2057 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2058 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2062 DEFPY (show_evpn_mac_vni_all_dad
,
2063 show_evpn_mac_vni_all_dad_cmd
,
2064 "show evpn mac vni all duplicate [json]",
2068 "VxLAN Network Identifier\n"
2070 "Duplicate address list\n"
2073 struct zebra_vrf
*zvrf
;
2074 bool uj
= use_json(argc
, argv
);
2076 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2077 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2082 DEFPY (show_evpn_mac_vni_dad
,
2083 show_evpn_mac_vni_dad_cmd
,
2084 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2088 "VxLAN Network Identifier\n"
2090 "Duplicate address list\n"
2093 struct zebra_vrf
*zvrf
;
2095 bool uj
= use_json(argc
, argv
);
2097 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2098 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2100 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2105 DEFPY (show_evpn_neigh_vni_dad
,
2106 show_evpn_neigh_vni_dad_cmd
,
2107 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2110 "ARP and ND cache\n"
2111 "VxLAN Network Identifier\n"
2113 "Duplicate address list\n"
2116 struct zebra_vrf
*zvrf
;
2118 bool uj
= use_json(argc
, argv
);
2120 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2121 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2122 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2126 DEFPY (show_evpn_neigh_vni_all_dad
,
2127 show_evpn_neigh_vni_all_dad_cmd
,
2128 "show evpn arp-cache vni all duplicate [json]",
2131 "ARP and ND cache\n"
2132 "VxLAN Network Identifier\n"
2134 "Duplicate address list\n"
2137 struct zebra_vrf
*zvrf
;
2138 bool uj
= use_json(argc
, argv
);
2140 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2141 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2146 DEFUN (show_evpn_neigh_vni
,
2147 show_evpn_neigh_vni_cmd
,
2148 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2151 "ARP and ND cache\n"
2152 "VxLAN Network Identifier\n"
2156 struct zebra_vrf
*zvrf
;
2158 bool uj
= use_json(argc
, argv
);
2160 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2161 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2162 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2166 DEFUN (show_evpn_neigh_vni_all
,
2167 show_evpn_neigh_vni_all_cmd
,
2168 "show evpn arp-cache vni all [json]",
2171 "ARP and ND cache\n"
2172 "VxLAN Network Identifier\n"
2176 struct zebra_vrf
*zvrf
;
2177 bool uj
= use_json(argc
, argv
);
2179 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2180 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2184 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2185 "show evpn arp-cache vni all detail [json]",
2188 "ARP and ND cache\n"
2189 "VxLAN Network Identifier\n"
2191 "Neighbor details for all vnis in detail\n" JSON_STR
)
2193 struct zebra_vrf
*zvrf
;
2194 bool uj
= use_json(argc
, argv
);
2196 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2197 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2201 DEFUN (show_evpn_neigh_vni_neigh
,
2202 show_evpn_neigh_vni_neigh_cmd
,
2203 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2206 "ARP and ND cache\n"
2207 "VxLAN Network Identifier\n"
2210 "Neighbor address (IPv4 or IPv6 address)\n"
2213 struct zebra_vrf
*zvrf
;
2216 bool uj
= use_json(argc
, argv
);
2218 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2219 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2221 vty_out(vty
, "%% Malformed Neighbor address\n");
2224 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2225 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2229 DEFUN (show_evpn_neigh_vni_vtep
,
2230 show_evpn_neigh_vni_vtep_cmd
,
2231 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2234 "ARP and ND cache\n"
2235 "VxLAN Network Identifier\n"
2238 "Remote VTEP IP address\n"
2241 struct zebra_vrf
*zvrf
;
2243 struct in_addr vtep_ip
;
2244 bool uj
= use_json(argc
, argv
);
2246 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2247 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2249 vty_out(vty
, "%% Malformed VTEP IP address\n");
2253 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2254 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2258 /* policy routing contexts */
2259 DEFUN (show_pbr_ipset
,
2261 "show pbr ipset [WORD]",
2263 "Policy-Based Routing\n"
2264 "IPset Context information\n"
2265 "IPset Name information\n")
2269 found
= argv_find(argv
, argc
, "WORD", &idx
);
2271 zebra_pbr_show_ipset_list(vty
, NULL
);
2273 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2277 /* policy routing contexts */
2278 DEFUN (show_pbr_iptable
,
2279 show_pbr_iptable_cmd
,
2280 "show pbr iptable [WORD]",
2282 "Policy-Based Routing\n"
2283 "IPtable Context information\n"
2284 "IPtable Name information\n")
2289 found
= argv_find(argv
, argc
, "WORD", &idx
);
2291 zebra_pbr_show_iptable(vty
, NULL
);
2293 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2297 DEFPY (clear_evpn_dup_addr
,
2298 clear_evpn_dup_addr_cmd
,
2299 "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>]>",
2302 "Duplicate address \n"
2303 "VxLAN Network Identifier\n"
2307 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2312 struct zebra_vrf
*zvrf
;
2314 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2315 struct ethaddr mac_addr
;
2317 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2319 vni
= strtoul(vni_val
, NULL
, 10);
2322 prefix_str2mac(mac_val
, &mac_addr
);
2323 zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
, vni
,
2326 if (sockunion_family(ip
) == AF_INET
) {
2327 host_ip
.ipa_type
= IPADDR_V4
;
2328 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2330 host_ip
.ipa_type
= IPADDR_V6
;
2331 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2332 sizeof(struct in6_addr
));
2334 zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
, vni
,
2337 zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2340 zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2346 /* Static ip route configuration write function. */
2347 static int zebra_ip_config(struct vty
*vty
)
2351 write
+= zebra_import_table_config(vty
);
2356 DEFUN (ip_zebra_import_table_distance
,
2357 ip_zebra_import_table_distance_cmd
,
2358 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2360 "import routes from non-main kernel table\n"
2361 "kernel routing table id\n"
2362 "Distance for imported routes\n"
2363 "Default distance value\n"
2364 "route-map for filtering\n"
2367 uint32_t table_id
= 0;
2369 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2370 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2372 strmatch(argv
[argc
- 2]->text
, "route-map")
2373 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2377 if (argc
== 7 || (argc
== 5 && !rmap
))
2378 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2380 if (!is_zebra_valid_kernel_table(table_id
)) {
2382 "Invalid routing table ID, %d. Must be in range 1-252\n",
2385 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2389 if (is_zebra_main_routing_table(table_id
)) {
2391 "Invalid routing table ID, %d. Must be non-default table\n",
2394 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2398 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2400 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2405 DEFUN_HIDDEN (zebra_packet_process
,
2406 zebra_packet_process_cmd
,
2407 "zebra zapi-packets (1-10000)",
2410 "Number of packets to process before relinquishing thread\n")
2412 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2414 atomic_store_explicit(&zebrad
.packets_to_process
, packets
,
2415 memory_order_relaxed
);
2420 DEFUN_HIDDEN (no_zebra_packet_process
,
2421 no_zebra_packet_process_cmd
,
2422 "no zebra zapi-packets [(1-10000)]",
2426 "Number of packets to process before relinquishing thread\n")
2428 atomic_store_explicit(&zebrad
.packets_to_process
,
2429 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2430 memory_order_relaxed
);
2435 DEFUN_HIDDEN (zebra_workqueue_timer
,
2436 zebra_workqueue_timer_cmd
,
2437 "zebra work-queue (0-10000)",
2440 "Time in milliseconds\n")
2442 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2443 zebrad
.ribq
->spec
.hold
= timer
;
2448 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2449 no_zebra_workqueue_timer_cmd
,
2450 "no zebra work-queue [(0-10000)]",
2454 "Time in milliseconds\n")
2456 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2461 DEFUN (no_ip_zebra_import_table
,
2462 no_ip_zebra_import_table_cmd
,
2463 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2466 "import routes from non-main kernel table\n"
2467 "kernel routing table id\n"
2468 "Distance for imported routes\n"
2469 "Default distance value\n"
2470 "route-map for filtering\n"
2473 uint32_t table_id
= 0;
2474 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2476 if (!is_zebra_valid_kernel_table(table_id
)) {
2478 "Invalid routing table ID. Must be in range 1-252\n");
2482 if (is_zebra_main_routing_table(table_id
)) {
2484 "Invalid routing table ID, %d. Must be non-default table\n",
2489 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2492 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2495 static int config_write_protocol(struct vty
*vty
)
2498 vty_out(vty
, "allow-external-route-update\n");
2500 if (zebra_rnh_ip_default_route
)
2501 vty_out(vty
, "ip nht resolve-via-default\n");
2503 if (zebra_rnh_ipv6_default_route
)
2504 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2506 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2507 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2509 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2510 vty_out(vty
, "zebra zapi-packets %u\n",
2511 zebrad
.packets_to_process
);
2513 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2515 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2516 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2517 ipv4_multicast_mode
== MCAST_URIB_ONLY
2519 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2521 : ipv4_multicast_mode
2522 == MCAST_MIX_MRIB_FIRST
2524 : ipv4_multicast_mode
2525 == MCAST_MIX_DISTANCE
2532 /* Display default rtm_table for all clients. */
2537 "default routing table to use for all clients\n")
2539 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2543 DEFUN (config_table
,
2546 "Configure target kernel routing table\n"
2549 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2553 DEFUN (no_config_table
,
2554 no_config_table_cmd
,
2555 "no table [TABLENO]",
2557 "Configure target kernel routing table\n"
2560 zebrad
.rtm_table_default
= 0;
2574 " Route Route Neighbor LSP LSP\n");
2576 "VRF Installs Removals Updates Installs Removals\n");
2578 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2579 struct zebra_vrf
*zvrf
= vrf
->info
;
2581 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2582 " %10" PRIu64
" %10" PRIu64
"\n",
2583 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2584 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2585 zvrf
->lsp_removals
);
2591 DEFUN (ip_forwarding
,
2595 "Turn on IP forwarding\n")
2601 ret
= ipforward_on();
2604 vty_out(vty
, "Can't turn on IP forwarding\n");
2605 return CMD_WARNING_CONFIG_FAILED
;
2611 DEFUN (no_ip_forwarding
,
2612 no_ip_forwarding_cmd
,
2616 "Turn off IP forwarding\n")
2622 ret
= ipforward_off();
2625 vty_out(vty
, "Can't turn off IP forwarding\n");
2626 return CMD_WARNING_CONFIG_FAILED
;
2632 /* Only display ip forwarding is enabled or not. */
2633 DEFUN (show_ip_forwarding
,
2634 show_ip_forwarding_cmd
,
2635 "show ip forwarding",
2638 "IP forwarding status\n")
2645 vty_out(vty
, "IP forwarding is off\n");
2647 vty_out(vty
, "IP forwarding is on\n");
2651 /* Only display ipv6 forwarding is enabled or not. */
2652 DEFUN (show_ipv6_forwarding
,
2653 show_ipv6_forwarding_cmd
,
2654 "show ipv6 forwarding",
2656 "IPv6 information\n"
2657 "Forwarding status\n")
2661 ret
= ipforward_ipv6();
2665 vty_out(vty
, "ipv6 forwarding is unknown\n");
2668 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2671 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2674 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2680 DEFUN (ipv6_forwarding
,
2681 ipv6_forwarding_cmd
,
2684 "Turn on IPv6 forwarding\n")
2688 ret
= ipforward_ipv6();
2690 ret
= ipforward_ipv6_on();
2693 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2694 return CMD_WARNING_CONFIG_FAILED
;
2700 DEFUN (no_ipv6_forwarding
,
2701 no_ipv6_forwarding_cmd
,
2702 "no ipv6 forwarding",
2705 "Turn off IPv6 forwarding\n")
2709 ret
= ipforward_ipv6();
2711 ret
= ipforward_ipv6_off();
2714 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2715 return CMD_WARNING_CONFIG_FAILED
;
2721 /* Display dataplane info */
2722 DEFUN (show_dataplane
,
2724 "show zebra dplane [detailed]",
2727 "Zebra dataplane information\n"
2728 "Detailed output\n")
2731 bool detailed
= false;
2733 if (argv_find(argv
, argc
, "detailed", &idx
))
2736 return dplane_show_helper(vty
, detailed
);
2739 /* Display dataplane providers info */
2740 DEFUN (show_dataplane_providers
,
2741 show_dataplane_providers_cmd
,
2742 "show zebra dplane providers [detailed]",
2745 "Zebra dataplane information\n"
2746 "Zebra dataplane provider information\n"
2747 "Detailed output\n")
2750 bool detailed
= false;
2752 if (argv_find(argv
, argc
, "detailed", &idx
))
2755 return dplane_show_provs_helper(vty
, detailed
);
2758 /* Configure dataplane incoming queue limit */
2759 DEFUN (zebra_dplane_queue_limit
,
2760 zebra_dplane_queue_limit_cmd
,
2761 "zebra dplane limit (0-10000)",
2764 "Limit incoming queued updates\n"
2765 "Number of queued updates\n")
2769 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2771 dplane_set_in_queue_limit(limit
, true);
2776 /* Reset dataplane queue limit to default value */
2777 DEFUN (no_zebra_dplane_queue_limit
,
2778 no_zebra_dplane_queue_limit_cmd
,
2779 "no zebra dplane limit [(0-10000)]",
2783 "Limit incoming queued updates\n"
2784 "Number of queued updates\n")
2786 dplane_set_in_queue_limit(0, false);
2791 /* Table configuration write function. */
2792 static int config_write_table(struct vty
*vty
)
2794 if (zebrad
.rtm_table_default
)
2795 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2799 /* IPForwarding configuration write function. */
2800 static int config_write_forwarding(struct vty
*vty
)
2802 /* FIXME: Find better place for that. */
2803 router_id_write(vty
);
2806 vty_out(vty
, "no ip forwarding\n");
2807 if (!ipforward_ipv6())
2808 vty_out(vty
, "no ipv6 forwarding\n");
2809 vty_out(vty
, "!\n");
2813 /* IP node for static routes. */
2814 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2815 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2816 /* table node for routing tables. */
2817 static struct cmd_node table_node
= {TABLE_NODE
,
2818 "", /* This node has no interface. */
2820 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2821 "", /* This node has no interface. */
2825 void zebra_vty_init(void)
2827 /* Install configuration write function. */
2828 install_node(&table_node
, config_write_table
);
2829 install_node(&forwarding_node
, config_write_forwarding
);
2831 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2832 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2833 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2834 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2837 install_element(VIEW_NODE
, &show_table_cmd
);
2838 install_element(CONFIG_NODE
, &config_table_cmd
);
2839 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2840 #endif /* HAVE_NETLINK */
2842 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2843 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2844 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2847 zebra_route_map_init();
2849 install_node(&ip_node
, zebra_ip_config
);
2850 install_node(&protocol_node
, config_write_protocol
);
2852 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2853 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2855 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2856 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2858 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2859 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2860 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2861 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2862 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2863 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2865 install_element(VIEW_NODE
, &show_vrf_cmd
);
2866 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2867 install_element(VIEW_NODE
, &show_route_cmd
);
2868 install_element(VIEW_NODE
, &show_route_table_cmd
);
2869 if (vrf_is_backend_netns())
2870 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2871 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2872 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2873 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2874 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2875 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2876 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2878 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2879 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2881 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2882 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2883 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2884 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2885 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2886 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2887 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2888 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2889 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2891 /* Commands for VRF */
2892 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2894 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2895 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2896 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2897 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2898 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2899 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2900 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2901 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2902 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2903 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2904 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2905 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2906 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2907 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2908 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2909 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2910 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2911 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2912 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2913 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2914 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2915 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
2916 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
2917 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
2919 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2920 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2922 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2923 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2924 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2925 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2927 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2928 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2929 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2930 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);