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 static char re_status_output_char(struct route_entry
*re
, struct nexthop
*nhop
)
166 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
167 if (!CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
168 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
174 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
175 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
181 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
187 /* New RIB. Detailed information for IPv4 route. */
188 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
191 struct route_entry
*re
;
192 struct nexthop
*nexthop
;
193 char buf
[SRCDEST2STR_BUFFER
];
194 struct zebra_vrf
*zvrf
;
196 RNODE_FOREACH_RE (rn
, re
) {
197 const char *mcast_info
= "";
199 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
200 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
201 ? " using Multicast RIB"
202 : " using Unicast RIB";
205 vty_out(vty
, "Routing entry for %s%s\n",
206 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
207 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
209 vty_out(vty
, "[%d]", re
->instance
);
211 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
214 vty_out(vty
, ", tag %u", re
->tag
);
215 #if defined(SUPPORT_REALMS)
216 if (re
->tag
> 0 && re
->tag
<= 255)
217 vty_out(vty
, "(realm)");
221 vty_out(vty
, ", mtu %u", re
->mtu
);
222 if (re
->vrf_id
!= VRF_DEFAULT
) {
223 zvrf
= vrf_info_lookup(re
->vrf_id
);
224 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
226 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
227 vty_out(vty
, ", best");
234 uptime
-= re
->uptime
;
235 tm
= gmtime(&uptime
);
237 vty_out(vty
, " Last update ");
239 if (uptime
< ONE_DAY_SECOND
)
240 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
242 else if (uptime
< ONE_WEEK_SECOND
)
243 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
246 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
247 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
249 vty_out(vty
, " ago\n");
251 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
254 vty_out(vty
, " %c%s",
255 re_status_output_char(re
, nexthop
),
256 nexthop
->rparent
? " " : "");
258 switch (nexthop
->type
) {
259 case NEXTHOP_TYPE_IPV4
:
260 case NEXTHOP_TYPE_IPV4_IFINDEX
:
262 inet_ntoa(nexthop
->gate
.ipv4
));
263 if (nexthop
->ifindex
)
264 vty_out(vty
, ", via %s",
269 case NEXTHOP_TYPE_IPV6
:
270 case NEXTHOP_TYPE_IPV6_IFINDEX
:
272 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
274 if (nexthop
->ifindex
)
275 vty_out(vty
, ", via %s",
280 case NEXTHOP_TYPE_IFINDEX
:
281 vty_out(vty
, " directly connected, %s",
282 ifindex2ifname(nexthop
->ifindex
,
285 case NEXTHOP_TYPE_BLACKHOLE
:
286 vty_out(vty
, " unreachable");
287 switch (nexthop
->bh_type
) {
288 case BLACKHOLE_REJECT
:
289 vty_out(vty
, " (ICMP unreachable)");
291 case BLACKHOLE_ADMINPROHIB
:
293 " (ICMP admin-prohibited)");
296 vty_out(vty
, " (blackhole)");
298 case BLACKHOLE_UNSPEC
:
306 if ((re
->vrf_id
!= nexthop
->vrf_id
)
307 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
309 vrf_lookup_by_id(nexthop
->vrf_id
);
312 vty_out(vty
, "(vrf %s)", vrf
->name
);
314 vty_out(vty
, "(vrf UNKNOWN)");
317 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
318 vty_out(vty
, " (duplicate nexthop removed)");
320 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
321 vty_out(vty
, " inactive");
323 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
324 vty_out(vty
, " onlink");
326 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
327 vty_out(vty
, " (recursive)");
329 switch (nexthop
->type
) {
330 case NEXTHOP_TYPE_IPV4
:
331 case NEXTHOP_TYPE_IPV4_IFINDEX
:
332 if (nexthop
->src
.ipv4
.s_addr
) {
333 if (inet_ntop(AF_INET
,
335 addrstr
, sizeof addrstr
))
336 vty_out(vty
, ", src %s",
340 case NEXTHOP_TYPE_IPV6
:
341 case NEXTHOP_TYPE_IPV6_IFINDEX
:
342 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
344 if (inet_ntop(AF_INET6
,
346 addrstr
, sizeof addrstr
))
347 vty_out(vty
, ", src %s",
356 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
358 /* Label information */
359 if (nexthop
->nh_label
360 && nexthop
->nh_label
->num_labels
) {
361 vty_out(vty
, ", label %s",
363 nexthop
->nh_label
->num_labels
,
364 nexthop
->nh_label
->label
, buf
,
374 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
375 struct route_entry
*re
, json_object
*json
)
377 struct nexthop
*nexthop
;
379 char buf
[SRCDEST2STR_BUFFER
];
380 json_object
*json_nexthops
= NULL
;
381 json_object
*json_nexthop
= NULL
;
382 json_object
*json_route
= NULL
;
383 json_object
*json_labels
= NULL
;
388 uptime
-= re
->uptime
;
389 tm
= gmtime(&uptime
);
392 json_route
= json_object_new_object();
393 json_nexthops
= json_object_new_array();
395 json_object_string_add(json_route
, "prefix",
396 srcdest_rnode2str(rn
, buf
, sizeof buf
));
397 json_object_string_add(json_route
, "protocol",
398 zebra_route_string(re
->type
));
401 json_object_int_add(json_route
, "instance",
405 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
407 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
408 json_object_boolean_true_add(json_route
, "selected");
410 json_object_int_add(json_route
, "distance",
412 json_object_int_add(json_route
, "metric", re
->metric
);
414 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
415 json_object_boolean_true_add(json_route
, "installed");
417 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
418 json_object_boolean_true_add(json_route
, "failed");
420 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
421 json_object_boolean_true_add(json_route
, "queued");
423 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
424 json_object_int_add(json_route
, "distance",
426 json_object_int_add(json_route
, "metric", re
->metric
);
430 json_object_int_add(json_route
, "tag", re
->tag
);
432 json_object_int_add(json_route
, "internalStatus",
434 json_object_int_add(json_route
, "internalFlags",
436 if (uptime
< ONE_DAY_SECOND
)
437 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
439 else if (uptime
< ONE_WEEK_SECOND
)
440 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
443 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
444 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
447 json_object_string_add(json_route
, "uptime", buf
);
449 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
450 json_nexthop
= json_object_new_object();
452 json_object_int_add(json_nexthop
, "flags",
455 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
456 json_object_boolean_true_add(json_nexthop
,
459 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
460 json_object_boolean_true_add(json_nexthop
,
463 switch (nexthop
->type
) {
464 case NEXTHOP_TYPE_IPV4
:
465 case NEXTHOP_TYPE_IPV4_IFINDEX
:
466 json_object_string_add(
468 inet_ntoa(nexthop
->gate
.ipv4
));
469 json_object_string_add(json_nexthop
, "afi",
472 if (nexthop
->ifindex
) {
473 json_object_int_add(json_nexthop
,
476 json_object_string_add(
477 json_nexthop
, "interfaceName",
483 case NEXTHOP_TYPE_IPV6
:
484 case NEXTHOP_TYPE_IPV6_IFINDEX
:
485 json_object_string_add(
487 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
489 json_object_string_add(json_nexthop
, "afi",
492 if (nexthop
->ifindex
) {
493 json_object_int_add(json_nexthop
,
496 json_object_string_add(
497 json_nexthop
, "interfaceName",
504 case NEXTHOP_TYPE_IFINDEX
:
505 json_object_boolean_true_add(
506 json_nexthop
, "directlyConnected");
507 json_object_int_add(json_nexthop
,
510 json_object_string_add(
511 json_nexthop
, "interfaceName",
512 ifindex2ifname(nexthop
->ifindex
,
515 case NEXTHOP_TYPE_BLACKHOLE
:
516 json_object_boolean_true_add(json_nexthop
,
518 switch (nexthop
->bh_type
) {
519 case BLACKHOLE_REJECT
:
520 json_object_boolean_true_add(
521 json_nexthop
, "reject");
523 case BLACKHOLE_ADMINPROHIB
:
524 json_object_boolean_true_add(
529 json_object_boolean_true_add(
530 json_nexthop
, "blackhole");
532 case BLACKHOLE_UNSPEC
:
540 if ((nexthop
->vrf_id
!= re
->vrf_id
)
541 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
543 vrf_lookup_by_id(nexthop
->vrf_id
);
545 json_object_string_add(json_nexthop
, "vrf",
548 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
549 json_object_boolean_true_add(json_nexthop
,
552 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
553 json_object_boolean_true_add(json_nexthop
,
556 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
557 json_object_boolean_true_add(json_nexthop
,
560 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
561 json_object_boolean_true_add(json_nexthop
,
564 switch (nexthop
->type
) {
565 case NEXTHOP_TYPE_IPV4
:
566 case NEXTHOP_TYPE_IPV4_IFINDEX
:
567 if (nexthop
->src
.ipv4
.s_addr
) {
568 if (inet_ntop(AF_INET
,
569 &nexthop
->src
.ipv4
, buf
,
571 json_object_string_add(
572 json_nexthop
, "source",
576 case NEXTHOP_TYPE_IPV6
:
577 case NEXTHOP_TYPE_IPV6_IFINDEX
:
578 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
580 if (inet_ntop(AF_INET6
,
581 &nexthop
->src
.ipv6
, buf
,
583 json_object_string_add(
584 json_nexthop
, "source",
592 if (nexthop
->nh_label
593 && nexthop
->nh_label
->num_labels
) {
594 json_labels
= json_object_new_array();
596 for (int label_index
= 0;
598 < nexthop
->nh_label
->num_labels
;
600 json_object_array_add(
603 nexthop
->nh_label
->label
606 json_object_object_add(json_nexthop
, "labels",
610 json_object_array_add(json_nexthops
, json_nexthop
);
613 json_object_object_add(json_route
, "nexthops", json_nexthops
);
614 json_object_array_add(json
, json_route
);
618 /* Nexthop information. */
619 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
620 if (nexthop
== re
->ng
.nexthop
) {
621 /* Prefix information. */
622 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
624 len
+= vty_out(vty
, "[%d]", re
->instance
);
627 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
630 re_status_output_char(re
, nexthop
),
631 srcdest_rnode2str(rn
, buf
, sizeof buf
));
633 /* Distance and metric display. */
634 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
635 (re
->distance
|| re
->metric
)) ||
636 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
637 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
640 vty_out(vty
, " %c%*c",
641 re_status_output_char(re
, nexthop
),
642 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
645 switch (nexthop
->type
) {
646 case NEXTHOP_TYPE_IPV4
:
647 case NEXTHOP_TYPE_IPV4_IFINDEX
:
648 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
649 if (nexthop
->ifindex
)
651 ifindex2ifname(nexthop
->ifindex
,
654 case NEXTHOP_TYPE_IPV6
:
655 case NEXTHOP_TYPE_IPV6_IFINDEX
:
656 vty_out(vty
, " via %s",
657 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
659 if (nexthop
->ifindex
)
661 ifindex2ifname(nexthop
->ifindex
,
665 case NEXTHOP_TYPE_IFINDEX
:
666 vty_out(vty
, " is directly connected, %s",
667 ifindex2ifname(nexthop
->ifindex
,
670 case NEXTHOP_TYPE_BLACKHOLE
:
671 vty_out(vty
, " unreachable");
672 switch (nexthop
->bh_type
) {
673 case BLACKHOLE_REJECT
:
674 vty_out(vty
, " (ICMP unreachable)");
676 case BLACKHOLE_ADMINPROHIB
:
677 vty_out(vty
, " (ICMP admin-prohibited)");
680 vty_out(vty
, " (blackhole)");
682 case BLACKHOLE_UNSPEC
:
690 if ((nexthop
->vrf_id
!= re
->vrf_id
)
691 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
692 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
695 vty_out(vty
, "(vrf %s)", vrf
->name
);
697 vty_out(vty
, "(vrf UNKNOWN)");
700 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
701 vty_out(vty
, " inactive");
703 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
704 vty_out(vty
, " onlink");
706 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
707 vty_out(vty
, " (recursive)");
709 switch (nexthop
->type
) {
710 case NEXTHOP_TYPE_IPV4
:
711 case NEXTHOP_TYPE_IPV4_IFINDEX
:
712 if (nexthop
->src
.ipv4
.s_addr
) {
713 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
715 vty_out(vty
, ", src %s", buf
);
718 case NEXTHOP_TYPE_IPV6
:
719 case NEXTHOP_TYPE_IPV6_IFINDEX
:
720 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
721 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
723 vty_out(vty
, ", src %s", buf
);
730 /* Label information */
731 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
732 vty_out(vty
, ", label %s",
733 mpls_label2str(nexthop
->nh_label
->num_labels
,
734 nexthop
->nh_label
->label
, buf
,
738 if (uptime
< ONE_DAY_SECOND
)
739 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
740 tm
->tm_min
, tm
->tm_sec
);
741 else if (uptime
< ONE_WEEK_SECOND
)
742 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
743 tm
->tm_hour
, tm
->tm_min
);
745 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
746 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
752 static void vty_show_ip_route_detail_json(struct vty
*vty
,
753 struct route_node
*rn
)
755 json_object
*json
= NULL
;
756 json_object
*json_prefix
= NULL
;
757 struct route_entry
*re
;
760 json
= json_object_new_object();
761 json_prefix
= json_object_new_array();
763 RNODE_FOREACH_RE (rn
, re
) {
764 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
767 prefix2str(&rn
->p
, buf
, sizeof(buf
));
768 json_object_object_add(json
, buf
, json_prefix
);
769 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
770 json
, JSON_C_TO_STRING_PRETTY
));
771 json_object_free(json
);
774 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
775 struct route_table
*table
, afi_t afi
,
776 bool use_fib
, route_tag_t tag
,
777 const struct prefix
*longer_prefix_p
,
778 bool supernets_only
, int type
,
779 unsigned short ospf_instance_id
, bool use_json
)
781 struct route_node
*rn
;
782 struct route_entry
*re
;
785 json_object
*json
= NULL
;
786 json_object
*json_prefix
= NULL
;
791 json
= json_object_new_object();
793 /* Show all routes. */
794 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
795 dest
= rib_dest_from_rnode(rn
);
797 RNODE_FOREACH_RE (rn
, re
) {
798 if (use_fib
&& re
!= dest
->selected_fib
)
801 if (tag
&& re
->tag
!= tag
)
805 && !prefix_match(longer_prefix_p
, &rn
->p
))
808 /* This can only be true when the afi is IPv4 */
809 if (supernets_only
) {
810 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
812 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
815 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
818 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
822 if (type
&& re
->type
!= type
)
826 && (re
->type
!= ZEBRA_ROUTE_OSPF
827 || re
->instance
!= ospf_instance_id
))
832 json_prefix
= json_object_new_array();
837 SHOW_ROUTE_V4_HEADER
);
840 SHOW_ROUTE_V6_HEADER
);
842 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
843 vty_out(vty
, "\nVRF %s:\n",
850 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
854 prefix2str(&rn
->p
, buf
, sizeof(buf
));
855 json_object_object_add(json
, buf
, json_prefix
);
861 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
862 JSON_C_TO_STRING_PRETTY
));
863 json_object_free(json
);
867 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
868 safi_t safi
, bool use_fib
, bool use_json
,
870 const struct prefix
*longer_prefix_p
,
871 bool supernets_only
, int type
,
872 unsigned short ospf_instance_id
)
874 struct route_table
*table
;
875 struct zebra_vrf
*zvrf
= NULL
;
877 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
879 vty_out(vty
, "{}\n");
881 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
885 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
887 vty_out(vty
, "{}\n");
889 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
893 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
896 vty_out(vty
, "{}\n");
900 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
901 longer_prefix_p
, supernets_only
, type
,
902 ospf_instance_id
, use_json
);
907 DEFPY (show_route_table
,
908 show_route_table_cmd
,
909 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
915 "The table number to display, if available\n"
918 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
919 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
920 struct route_table
*t
;
922 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
924 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
930 DEFPY (show_route_table_vrf
,
931 show_route_table_vrf_cmd
,
932 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
938 "The table number to display, if available\n"
942 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
943 struct zebra_vrf
*zvrf
;
944 struct route_table
*t
;
945 vrf_id_t vrf_id
= VRF_DEFAULT
;
948 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
949 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
951 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
953 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
961 "show <ip$ipv4|ipv6$ipv6> nht [vrf NAME$vrf_name|vrf all$vrf_all]",
965 "IP nexthop tracking table\n"
967 VRF_ALL_CMD_HELP_STR
)
969 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
970 vrf_id_t vrf_id
= VRF_DEFAULT
;
974 struct zebra_vrf
*zvrf
;
976 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
977 if ((zvrf
= vrf
->info
) != NULL
) {
978 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
979 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
985 VRF_GET_ID(vrf_id
, vrf_name
, false);
987 zebra_print_rnh_table(vrf_id
, afi
, vty
, RNH_NEXTHOP_TYPE
);
991 DEFPY (show_ip_import_check
,
992 show_ip_import_check_cmd
,
993 "show <ip$ipv4|ipv6$ipv6> import-check [vrf NAME$vrf_name|vrf all$vrf_all]",
997 "IP import check tracking table\n"
999 VRF_ALL_CMD_HELP_STR
)
1001 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1002 vrf_id_t vrf_id
= VRF_DEFAULT
;
1006 struct zebra_vrf
*zvrf
;
1008 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1009 if ((zvrf
= vrf
->info
) != NULL
) {
1010 vty_out(vty
, "\nVRF %s:\n",
1012 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1013 RNH_IMPORT_CHECK_TYPE
);
1018 VRF_GET_ID(vrf_id
, vrf_name
, false);
1020 zebra_print_rnh_table(vrf_id
, afi
, vty
, RNH_IMPORT_CHECK_TYPE
);
1024 DEFUN (ip_nht_default_route
,
1025 ip_nht_default_route_cmd
,
1026 "ip nht resolve-via-default",
1028 "Filter Next Hop tracking route resolution\n"
1029 "Resolve via default route\n")
1031 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1036 if (zebra_rnh_ip_default_route
)
1039 zebra_rnh_ip_default_route
= 1;
1041 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1045 DEFUN (no_ip_nht_default_route
,
1046 no_ip_nht_default_route_cmd
,
1047 "no ip nht resolve-via-default",
1050 "Filter Next Hop tracking route resolution\n"
1051 "Resolve via default route\n")
1053 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1058 if (!zebra_rnh_ip_default_route
)
1061 zebra_rnh_ip_default_route
= 0;
1062 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1066 DEFUN (ipv6_nht_default_route
,
1067 ipv6_nht_default_route_cmd
,
1068 "ipv6 nht resolve-via-default",
1070 "Filter Next Hop tracking route resolution\n"
1071 "Resolve via default route\n")
1073 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1078 if (zebra_rnh_ipv6_default_route
)
1081 zebra_rnh_ipv6_default_route
= 1;
1082 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1086 DEFUN (no_ipv6_nht_default_route
,
1087 no_ipv6_nht_default_route_cmd
,
1088 "no ipv6 nht resolve-via-default",
1091 "Filter Next Hop tracking route resolution\n"
1092 "Resolve via default route\n")
1095 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1100 if (!zebra_rnh_ipv6_default_route
)
1103 zebra_rnh_ipv6_default_route
= 0;
1104 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1112 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1115 |A.B.C.D/M$prefix longer-prefixes\
1116 |supernets-only$supernets_only\
1119 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1120 |ospf$type_str (1-65535)$ospf_instance_id\
1122 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1125 |X:X::X:X/M$prefix longer-prefixes\
1127 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1132 "IP forwarding table\n"
1133 "IP routing table\n"
1134 VRF_FULL_CMD_HELP_STR
1135 "Show only routes with tag\n"
1137 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1138 "Show route matching the specified Network/Mask pair only\n"
1139 "Show supernet entries only\n"
1140 FRR_IP_REDIST_HELP_STR_ZEBRA
1141 "Open Shortest Path First (OSPFv2)\n"
1144 "IP forwarding table\n"
1145 "IP routing table\n"
1146 VRF_FULL_CMD_HELP_STR
1147 "Show only routes with tag\n"
1150 "Show route matching the specified Network/Mask pair only\n"
1151 FRR_IP6_REDIST_HELP_STR_ZEBRA
1154 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1159 type
= proto_redistnum(afi
, type_str
);
1161 vty_out(vty
, "Unknown route type\n");
1167 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1168 struct zebra_vrf
*zvrf
;
1169 struct route_table
*table
;
1171 if ((zvrf
= vrf
->info
) == NULL
1172 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1176 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1177 !!json
, tag
, prefix_str
? prefix
: NULL
,
1178 !!supernets_only
, type
, ospf_instance_id
);
1181 vrf_id_t vrf_id
= VRF_DEFAULT
;
1184 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1185 vrf
= vrf_lookup_by_id(vrf_id
);
1186 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1187 !!json
, tag
, prefix_str
? prefix
: NULL
,
1188 !!supernets_only
, type
, ospf_instance_id
);
1194 DEFPY (show_route_detail
,
1195 show_route_detail_cmd
,
1198 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1203 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1212 "IP routing table\n"
1213 VRF_FULL_CMD_HELP_STR
1214 "Network in the IP routing table to display\n"
1215 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1217 "IP routing table\n"
1218 VRF_FULL_CMD_HELP_STR
1223 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1224 struct route_table
*table
;
1226 struct route_node
*rn
;
1229 prefix_str
= address_str
;
1230 if (str2prefix(prefix_str
, &p
) < 0) {
1231 vty_out(vty
, "%% Malformed address\n");
1237 struct zebra_vrf
*zvrf
;
1239 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1240 if ((zvrf
= vrf
->info
) == NULL
1241 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1244 rn
= route_node_match(table
, &p
);
1247 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1248 route_unlock_node(rn
);
1253 vty_show_ip_route_detail_json(vty
, rn
);
1255 vty_show_ip_route_detail(vty
, rn
, 0);
1257 route_unlock_node(rn
);
1260 vrf_id_t vrf_id
= VRF_DEFAULT
;
1263 VRF_GET_ID(vrf_id
, vrf_name
, false);
1265 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1269 rn
= route_node_match(table
, &p
);
1271 vty_out(vty
, "%% Network not in table\n");
1274 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1275 vty_out(vty
, "%% Network not in table\n");
1276 route_unlock_node(rn
);
1281 vty_show_ip_route_detail_json(vty
, rn
);
1283 vty_show_ip_route_detail(vty
, rn
, 0);
1285 route_unlock_node(rn
);
1291 DEFPY (show_route_summary
,
1292 show_route_summary_cmd
,
1295 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1296 summary [prefix$prefix]\
1297 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1298 summary [prefix$prefix]\
1302 "IP routing table\n"
1303 VRF_FULL_CMD_HELP_STR
1304 "Summary of all routes\n"
1307 "IP routing table\n"
1308 VRF_FULL_CMD_HELP_STR
1309 "Summary of all routes\n"
1312 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1313 struct route_table
*table
;
1317 struct zebra_vrf
*zvrf
;
1319 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1320 if ((zvrf
= vrf
->info
) == NULL
1321 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1325 vty_show_ip_route_summary_prefix(vty
, table
);
1327 vty_show_ip_route_summary(vty
, table
);
1330 vrf_id_t vrf_id
= VRF_DEFAULT
;
1333 VRF_GET_ID(vrf_id
, vrf_name
, false);
1335 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1340 vty_show_ip_route_summary_prefix(vty
, table
);
1342 vty_show_ip_route_summary(vty
, table
);
1348 static void vty_show_ip_route_summary(struct vty
*vty
,
1349 struct route_table
*table
)
1351 struct route_node
*rn
;
1352 struct route_entry
*re
;
1353 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1354 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1355 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1356 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1360 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1361 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1362 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1363 RNODE_FOREACH_RE (rn
, re
) {
1364 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1365 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1367 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1369 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1371 rib_cnt
[re
->type
]++;
1373 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1374 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1377 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1379 fib_cnt
[re
->type
]++;
1383 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1384 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1386 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1387 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1388 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1389 if (i
== ZEBRA_ROUTE_BGP
) {
1390 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1391 rib_cnt
[ZEBRA_ROUTE_BGP
],
1392 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1393 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1394 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1395 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1397 vty_out(vty
, "%-20s %-20d %-20d \n",
1398 zebra_route_string(i
), rib_cnt
[i
],
1403 vty_out(vty
, "------\n");
1404 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1405 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1410 * Implementation of the ip route summary prefix command.
1412 * This command prints the primary prefixes that have been installed by various
1413 * protocols on the box.
1416 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1417 struct route_table
*table
)
1419 struct route_node
*rn
;
1420 struct route_entry
*re
;
1421 struct nexthop
*nexthop
;
1422 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1423 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1424 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1425 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1429 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1430 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1431 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1432 RNODE_FOREACH_RE (rn
, re
) {
1435 * In case of ECMP, count only once.
1438 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1439 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1440 fib_cnt
[re
->type
]++;
1442 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1443 nexthop
= nexthop
->next
) {
1445 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1446 rib_cnt
[re
->type
]++;
1447 if (re
->type
== ZEBRA_ROUTE_BGP
1448 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1449 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1450 if (CHECK_FLAG(re
->status
,
1451 ROUTE_ENTRY_INSTALLED
))
1452 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1457 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1458 "Prefix Routes", "FIB",
1459 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1461 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1462 if (rib_cnt
[i
] > 0) {
1463 if (i
== ZEBRA_ROUTE_BGP
) {
1464 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1465 rib_cnt
[ZEBRA_ROUTE_BGP
]
1466 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1467 fib_cnt
[ZEBRA_ROUTE_BGP
]
1468 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1469 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1470 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1471 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1473 vty_out(vty
, "%-20s %-20d %-20d \n",
1474 zebra_route_string(i
), rib_cnt
[i
],
1479 vty_out(vty
, "------\n");
1480 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1481 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1486 * Show IPv6 mroute command.Used to dump
1487 * the Multicast routing table.
1489 DEFUN (show_ipv6_mroute
,
1490 show_ipv6_mroute_cmd
,
1491 "show ipv6 mroute [vrf NAME]",
1494 "IPv6 Multicast routing table\n"
1497 struct route_table
*table
;
1498 struct route_node
*rn
;
1499 struct route_entry
*re
;
1501 vrf_id_t vrf_id
= VRF_DEFAULT
;
1504 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1506 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1510 /* Show all IPv6 route. */
1511 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1512 RNODE_FOREACH_RE (rn
, re
) {
1514 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1517 vty_show_ip_route(vty
, rn
, re
, NULL
);
1522 DEFUN (show_ipv6_mroute_vrf_all
,
1523 show_ipv6_mroute_vrf_all_cmd
,
1524 "show ipv6 mroute vrf all",
1527 "IPv6 Multicast routing table\n"
1528 VRF_ALL_CMD_HELP_STR
)
1530 struct route_table
*table
;
1531 struct route_node
*rn
;
1532 struct route_entry
*re
;
1534 struct zebra_vrf
*zvrf
;
1537 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1538 if ((zvrf
= vrf
->info
) == NULL
1539 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1542 /* Show all IPv6 route. */
1543 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1544 RNODE_FOREACH_RE (rn
, re
) {
1546 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1549 vty_show_ip_route(vty
, rn
, re
, NULL
);
1555 DEFUN (allow_external_route_update
,
1556 allow_external_route_update_cmd
,
1557 "allow-external-route-update",
1558 "Allow FRR routes to be overwritten by external processes\n")
1565 DEFUN (no_allow_external_route_update
,
1566 no_allow_external_route_update_cmd
,
1567 "no allow-external-route-update",
1569 "Allow FRR routes to be overwritten by external processes\n")
1584 struct zebra_vrf
*zvrf
;
1586 if (vrf_is_backend_netns())
1587 vty_out(vty
, "netns-based vrfs\n");
1589 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1590 if (!(zvrf
= vrf
->info
))
1592 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1595 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1596 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1597 vty_out(vty
, "inactive");
1598 else if (zvrf_ns_name(zvrf
))
1599 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1600 zvrf_ns_name(zvrf
));
1602 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1604 if (vrf_is_user_cfged(vrf
))
1605 vty_out(vty
, " (configured)");
1612 DEFUN_HIDDEN (default_vrf_vni_mapping
,
1613 default_vrf_vni_mapping_cmd
,
1614 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1615 "VNI corresponding to the DEFAULT VRF\n"
1617 "Prefix routes only \n")
1620 char err
[ERR_STR_SZ
];
1621 struct zebra_vrf
*zvrf
= NULL
;
1622 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1625 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1632 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1635 vty_out(vty
, "%s\n", err
);
1642 DEFUN_HIDDEN (no_default_vrf_vni_mapping
,
1643 no_default_vrf_vni_mapping_cmd
,
1644 "no vni " CMD_VNI_RANGE
,
1646 "VNI corresponding to DEFAULT VRF\n"
1650 char err
[ERR_STR_SZ
];
1651 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1652 struct zebra_vrf
*zvrf
= NULL
;
1654 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1658 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1660 vty_out(vty
, "%s\n", err
);
1667 DEFUN (vrf_vni_mapping
,
1668 vrf_vni_mapping_cmd
,
1669 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1670 "VNI corresponding to tenant VRF\n"
1672 "prefix-routes-only\n")
1677 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1678 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1679 char err
[ERR_STR_SZ
];
1687 /* Mark as having FRR configuration */
1688 vrf_set_user_cfged(vrf
);
1689 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1692 vty_out(vty
, "%s\n", err
);
1699 DEFUN (no_vrf_vni_mapping
,
1700 no_vrf_vni_mapping_cmd
,
1701 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1703 "VNI corresponding to tenant VRF\n"
1705 "prefix-routes-only\n")
1709 char err
[ERR_STR_SZ
];
1710 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1712 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1720 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1721 ERR_STR_SZ
, filter
, 0);
1723 vty_out(vty
, "%s\n", err
);
1727 /* If no other FRR config for this VRF, mark accordingly. */
1728 if (!zebra_vrf_has_config(zvrf
))
1729 vrf_reset_user_cfged(vrf
);
1735 DEFUN (show_vrf_vni
,
1737 "show vrf vni [json]",
1744 struct zebra_vrf
*zvrf
;
1745 json_object
*json
= NULL
;
1746 json_object
*json_vrfs
= NULL
;
1747 bool uj
= use_json(argc
, argv
);
1750 json
= json_object_new_object();
1751 json_vrfs
= json_object_new_array();
1755 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1756 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1758 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1763 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1767 json_object_object_add(json
, "vrfs", json_vrfs
);
1768 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1769 json
, JSON_C_TO_STRING_PRETTY
));
1770 json_object_free(json
);
1776 DEFUN (show_evpn_global
,
1777 show_evpn_global_cmd
,
1783 bool uj
= use_json(argc
, argv
);
1785 zebra_vxlan_print_evpn(vty
, uj
);
1789 DEFUN (show_evpn_vni
,
1791 "show evpn vni [json]",
1794 "VxLAN Network Identifier\n"
1797 struct zebra_vrf
*zvrf
;
1798 bool uj
= use_json(argc
, argv
);
1800 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1801 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1805 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1806 "show evpn vni detail [json]",
1809 "VxLAN Network Identifier\n"
1810 "Detailed Information On Each VNI\n"
1813 struct zebra_vrf
*zvrf
;
1814 bool uj
= use_json(argc
, argv
);
1816 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1817 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1821 DEFUN (show_evpn_vni_vni
,
1822 show_evpn_vni_vni_cmd
,
1823 "show evpn vni " CMD_VNI_RANGE
"[json]",
1826 "VxLAN Network Identifier\n"
1830 struct zebra_vrf
*zvrf
;
1832 bool uj
= use_json(argc
, argv
);
1834 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1835 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1836 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1840 DEFUN (show_evpn_rmac_vni_mac
,
1841 show_evpn_rmac_vni_mac_cmd
,
1842 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1849 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1854 bool uj
= use_json(argc
, argv
);
1856 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1857 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1858 vty_out(vty
, "%% Malformed MAC address\n");
1861 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1865 DEFUN (show_evpn_rmac_vni
,
1866 show_evpn_rmac_vni_cmd
,
1867 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1876 bool uj
= use_json(argc
, argv
);
1878 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1879 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1884 DEFUN (show_evpn_rmac_vni_all
,
1885 show_evpn_rmac_vni_all_cmd
,
1886 "show evpn rmac vni all [json]",
1894 bool uj
= use_json(argc
, argv
);
1896 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1901 DEFUN (show_evpn_nh_vni_ip
,
1902 show_evpn_nh_vni_ip_cmd
,
1903 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1910 "Host address (ipv4 or ipv6)\n"
1915 bool uj
= use_json(argc
, argv
);
1917 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1918 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1920 vty_out(vty
, "%% Malformed Neighbor address\n");
1923 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1928 DEFUN (show_evpn_nh_vni
,
1929 show_evpn_nh_vni_cmd
,
1930 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1939 bool uj
= use_json(argc
, argv
);
1941 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1942 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1947 DEFUN (show_evpn_nh_vni_all
,
1948 show_evpn_nh_vni_all_cmd
,
1949 "show evpn next-hops vni all [json]",
1957 bool uj
= use_json(argc
, argv
);
1959 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1964 DEFUN (show_evpn_mac_vni
,
1965 show_evpn_mac_vni_cmd
,
1966 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1970 "VxLAN Network Identifier\n"
1974 struct zebra_vrf
*zvrf
;
1976 bool uj
= use_json(argc
, argv
);
1978 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1979 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1980 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1984 DEFUN (show_evpn_mac_vni_all
,
1985 show_evpn_mac_vni_all_cmd
,
1986 "show evpn mac vni all [json]",
1990 "VxLAN Network Identifier\n"
1994 struct zebra_vrf
*zvrf
;
1995 bool uj
= use_json(argc
, argv
);
1997 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1998 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2002 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2003 "show evpn mac vni all detail [json]",
2007 "VxLAN Network Identifier\n"
2009 "Detailed Information On Each VNI MAC\n"
2012 struct zebra_vrf
*zvrf
;
2013 bool uj
= use_json(argc
, argv
);
2015 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2016 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2020 DEFUN (show_evpn_mac_vni_all_vtep
,
2021 show_evpn_mac_vni_all_vtep_cmd
,
2022 "show evpn mac vni all vtep A.B.C.D [json]",
2026 "VxLAN Network Identifier\n"
2029 "Remote VTEP IP address\n"
2032 struct zebra_vrf
*zvrf
;
2033 struct in_addr vtep_ip
;
2034 bool uj
= use_json(argc
, argv
);
2036 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2038 vty_out(vty
, "%% Malformed VTEP IP address\n");
2041 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2042 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2048 DEFUN (show_evpn_mac_vni_mac
,
2049 show_evpn_mac_vni_mac_cmd
,
2050 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2054 "VxLAN Network Identifier\n"
2057 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2061 struct zebra_vrf
*zvrf
;
2064 bool uj
= use_json(argc
, argv
);
2066 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2067 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2068 vty_out(vty
, "%% Malformed MAC address");
2071 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2072 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2076 DEFUN (show_evpn_mac_vni_vtep
,
2077 show_evpn_mac_vni_vtep_cmd
,
2078 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2082 "VxLAN Network Identifier\n"
2085 "Remote VTEP IP address\n"
2088 struct zebra_vrf
*zvrf
;
2090 struct in_addr vtep_ip
;
2091 bool uj
= use_json(argc
, argv
);
2093 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2094 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2096 vty_out(vty
, "%% Malformed VTEP IP address\n");
2100 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2101 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2105 DEFPY (show_evpn_mac_vni_all_dad
,
2106 show_evpn_mac_vni_all_dad_cmd
,
2107 "show evpn mac vni all duplicate [json]",
2111 "VxLAN Network Identifier\n"
2113 "Duplicate address list\n"
2116 struct zebra_vrf
*zvrf
;
2117 bool uj
= use_json(argc
, argv
);
2119 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2120 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2125 DEFPY (show_evpn_mac_vni_dad
,
2126 show_evpn_mac_vni_dad_cmd
,
2127 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2131 "VxLAN Network Identifier\n"
2133 "Duplicate address list\n"
2136 struct zebra_vrf
*zvrf
;
2138 bool uj
= use_json(argc
, argv
);
2140 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2141 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2143 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2148 DEFPY (show_evpn_neigh_vni_dad
,
2149 show_evpn_neigh_vni_dad_cmd
,
2150 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2153 "ARP and ND cache\n"
2154 "VxLAN Network Identifier\n"
2156 "Duplicate address list\n"
2159 struct zebra_vrf
*zvrf
;
2161 bool uj
= use_json(argc
, argv
);
2163 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2164 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2165 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2169 DEFPY (show_evpn_neigh_vni_all_dad
,
2170 show_evpn_neigh_vni_all_dad_cmd
,
2171 "show evpn arp-cache vni all duplicate [json]",
2174 "ARP and ND cache\n"
2175 "VxLAN Network Identifier\n"
2177 "Duplicate address list\n"
2180 struct zebra_vrf
*zvrf
;
2181 bool uj
= use_json(argc
, argv
);
2183 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2184 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2189 DEFUN (show_evpn_neigh_vni
,
2190 show_evpn_neigh_vni_cmd
,
2191 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2194 "ARP and ND cache\n"
2195 "VxLAN Network Identifier\n"
2199 struct zebra_vrf
*zvrf
;
2201 bool uj
= use_json(argc
, argv
);
2203 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2204 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2205 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2209 DEFUN (show_evpn_neigh_vni_all
,
2210 show_evpn_neigh_vni_all_cmd
,
2211 "show evpn arp-cache vni all [json]",
2214 "ARP and ND cache\n"
2215 "VxLAN Network Identifier\n"
2219 struct zebra_vrf
*zvrf
;
2220 bool uj
= use_json(argc
, argv
);
2222 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2223 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2227 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2228 "show evpn arp-cache vni all detail [json]",
2231 "ARP and ND cache\n"
2232 "VxLAN Network Identifier\n"
2234 "Neighbor details for all vnis in detail\n" JSON_STR
)
2236 struct zebra_vrf
*zvrf
;
2237 bool uj
= use_json(argc
, argv
);
2239 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2240 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2244 DEFUN (show_evpn_neigh_vni_neigh
,
2245 show_evpn_neigh_vni_neigh_cmd
,
2246 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2249 "ARP and ND cache\n"
2250 "VxLAN Network Identifier\n"
2253 "Neighbor address (IPv4 or IPv6 address)\n"
2256 struct zebra_vrf
*zvrf
;
2259 bool uj
= use_json(argc
, argv
);
2261 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2262 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2264 vty_out(vty
, "%% Malformed Neighbor address\n");
2267 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2268 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2272 DEFUN (show_evpn_neigh_vni_vtep
,
2273 show_evpn_neigh_vni_vtep_cmd
,
2274 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2277 "ARP and ND cache\n"
2278 "VxLAN Network Identifier\n"
2281 "Remote VTEP IP address\n"
2284 struct zebra_vrf
*zvrf
;
2286 struct in_addr vtep_ip
;
2287 bool uj
= use_json(argc
, argv
);
2289 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2290 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2292 vty_out(vty
, "%% Malformed VTEP IP address\n");
2296 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2297 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2301 /* policy routing contexts */
2302 DEFUN (show_pbr_ipset
,
2304 "show pbr ipset [WORD]",
2306 "Policy-Based Routing\n"
2307 "IPset Context information\n"
2308 "IPset Name information\n")
2312 found
= argv_find(argv
, argc
, "WORD", &idx
);
2314 zebra_pbr_show_ipset_list(vty
, NULL
);
2316 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2320 /* policy routing contexts */
2321 DEFUN (show_pbr_iptable
,
2322 show_pbr_iptable_cmd
,
2323 "show pbr iptable [WORD]",
2325 "Policy-Based Routing\n"
2326 "IPtable Context information\n"
2327 "IPtable Name information\n")
2332 found
= argv_find(argv
, argc
, "WORD", &idx
);
2334 zebra_pbr_show_iptable(vty
, NULL
);
2336 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2340 DEFPY (clear_evpn_dup_addr
,
2341 clear_evpn_dup_addr_cmd
,
2342 "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>]>",
2345 "Duplicate address \n"
2346 "VxLAN Network Identifier\n"
2350 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2355 struct zebra_vrf
*zvrf
;
2357 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2358 struct ethaddr mac_addr
;
2359 int ret
= CMD_SUCCESS
;
2361 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2363 vni
= strtoul(vni_val
, NULL
, 10);
2366 prefix_str2mac(mac_val
, &mac_addr
);
2367 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2371 if (sockunion_family(ip
) == AF_INET
) {
2372 host_ip
.ipa_type
= IPADDR_V4
;
2373 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2375 host_ip
.ipa_type
= IPADDR_V6
;
2376 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2377 sizeof(struct in6_addr
));
2379 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2383 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2386 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2392 /* Static ip route configuration write function. */
2393 static int zebra_ip_config(struct vty
*vty
)
2397 write
+= zebra_import_table_config(vty
);
2402 DEFUN (ip_zebra_import_table_distance
,
2403 ip_zebra_import_table_distance_cmd
,
2404 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2406 "import routes from non-main kernel table\n"
2407 "kernel routing table id\n"
2408 "Distance for imported routes\n"
2409 "Default distance value\n"
2410 "route-map for filtering\n"
2413 uint32_t table_id
= 0;
2415 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2416 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2418 strmatch(argv
[argc
- 2]->text
, "route-map")
2419 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2423 if (argc
== 7 || (argc
== 5 && !rmap
))
2424 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2426 if (!is_zebra_valid_kernel_table(table_id
)) {
2428 "Invalid routing table ID, %d. Must be in range 1-252\n",
2431 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2435 if (is_zebra_main_routing_table(table_id
)) {
2437 "Invalid routing table ID, %d. Must be non-default table\n",
2440 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2444 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2446 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2451 DEFUN_HIDDEN (zebra_packet_process
,
2452 zebra_packet_process_cmd
,
2453 "zebra zapi-packets (1-10000)",
2456 "Number of packets to process before relinquishing thread\n")
2458 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2460 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2461 memory_order_relaxed
);
2466 DEFUN_HIDDEN (no_zebra_packet_process
,
2467 no_zebra_packet_process_cmd
,
2468 "no zebra zapi-packets [(1-10000)]",
2472 "Number of packets to process before relinquishing thread\n")
2474 atomic_store_explicit(&zrouter
.packets_to_process
,
2475 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2476 memory_order_relaxed
);
2481 DEFUN_HIDDEN (zebra_workqueue_timer
,
2482 zebra_workqueue_timer_cmd
,
2483 "zebra work-queue (0-10000)",
2486 "Time in milliseconds\n")
2488 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2489 zrouter
.ribq
->spec
.hold
= timer
;
2494 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2495 no_zebra_workqueue_timer_cmd
,
2496 "no zebra work-queue [(0-10000)]",
2500 "Time in milliseconds\n")
2502 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2507 DEFUN (no_ip_zebra_import_table
,
2508 no_ip_zebra_import_table_cmd
,
2509 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2512 "import routes from non-main kernel table\n"
2513 "kernel routing table id\n"
2514 "Distance for imported routes\n"
2515 "Default distance value\n"
2516 "route-map for filtering\n"
2519 uint32_t table_id
= 0;
2520 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2522 if (!is_zebra_valid_kernel_table(table_id
)) {
2524 "Invalid routing table ID. Must be in range 1-252\n");
2528 if (is_zebra_main_routing_table(table_id
)) {
2530 "Invalid routing table ID, %d. Must be non-default table\n",
2535 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2538 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2541 static int config_write_protocol(struct vty
*vty
)
2544 vty_out(vty
, "allow-external-route-update\n");
2546 if (zebra_rnh_ip_default_route
)
2547 vty_out(vty
, "ip nht resolve-via-default\n");
2549 if (zebra_rnh_ipv6_default_route
)
2550 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2552 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2553 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2555 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2556 vty_out(vty
, "zebra zapi-packets %u\n",
2557 zrouter
.packets_to_process
);
2559 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2561 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2562 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2563 ipv4_multicast_mode
== MCAST_URIB_ONLY
2565 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2567 : ipv4_multicast_mode
2568 == MCAST_MIX_MRIB_FIRST
2570 : ipv4_multicast_mode
2571 == MCAST_MIX_DISTANCE
2578 /* Display default rtm_table for all clients. */
2583 "default routing table to use for all clients\n")
2585 vty_out(vty
, "table %d\n", zrouter
.rtm_table_default
);
2589 DEFUN (config_table
,
2592 "Configure target kernel routing table\n"
2595 zrouter
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2599 DEFUN (no_config_table
,
2600 no_config_table_cmd
,
2601 "no table [TABLENO]",
2603 "Configure target kernel routing table\n"
2606 zrouter
.rtm_table_default
= 0;
2620 " Route Route Neighbor LSP LSP\n");
2622 "VRF Installs Removals Updates Installs Removals\n");
2624 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2625 struct zebra_vrf
*zvrf
= vrf
->info
;
2627 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2628 " %10" PRIu64
" %10" PRIu64
"\n",
2629 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2630 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2631 zvrf
->lsp_removals
);
2637 DEFUN (ip_forwarding
,
2641 "Turn on IP forwarding\n")
2647 ret
= ipforward_on();
2650 vty_out(vty
, "Can't turn on IP forwarding\n");
2651 return CMD_WARNING_CONFIG_FAILED
;
2657 DEFUN (no_ip_forwarding
,
2658 no_ip_forwarding_cmd
,
2662 "Turn off IP forwarding\n")
2668 ret
= ipforward_off();
2671 vty_out(vty
, "Can't turn off IP forwarding\n");
2672 return CMD_WARNING_CONFIG_FAILED
;
2678 /* Only display ip forwarding is enabled or not. */
2679 DEFUN (show_ip_forwarding
,
2680 show_ip_forwarding_cmd
,
2681 "show ip forwarding",
2684 "IP forwarding status\n")
2691 vty_out(vty
, "IP forwarding is off\n");
2693 vty_out(vty
, "IP forwarding is on\n");
2697 /* Only display ipv6 forwarding is enabled or not. */
2698 DEFUN (show_ipv6_forwarding
,
2699 show_ipv6_forwarding_cmd
,
2700 "show ipv6 forwarding",
2702 "IPv6 information\n"
2703 "Forwarding status\n")
2707 ret
= ipforward_ipv6();
2711 vty_out(vty
, "ipv6 forwarding is unknown\n");
2714 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2717 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2720 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2726 DEFUN (ipv6_forwarding
,
2727 ipv6_forwarding_cmd
,
2730 "Turn on IPv6 forwarding\n")
2734 ret
= ipforward_ipv6();
2736 ret
= ipforward_ipv6_on();
2739 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2740 return CMD_WARNING_CONFIG_FAILED
;
2746 DEFUN (no_ipv6_forwarding
,
2747 no_ipv6_forwarding_cmd
,
2748 "no ipv6 forwarding",
2751 "Turn off IPv6 forwarding\n")
2755 ret
= ipforward_ipv6();
2757 ret
= ipforward_ipv6_off();
2760 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2761 return CMD_WARNING_CONFIG_FAILED
;
2767 /* Display dataplane info */
2768 DEFUN (show_dataplane
,
2770 "show zebra dplane [detailed]",
2773 "Zebra dataplane information\n"
2774 "Detailed output\n")
2777 bool detailed
= false;
2779 if (argv_find(argv
, argc
, "detailed", &idx
))
2782 return dplane_show_helper(vty
, detailed
);
2785 /* Display dataplane providers info */
2786 DEFUN (show_dataplane_providers
,
2787 show_dataplane_providers_cmd
,
2788 "show zebra dplane providers [detailed]",
2791 "Zebra dataplane information\n"
2792 "Zebra dataplane provider information\n"
2793 "Detailed output\n")
2796 bool detailed
= false;
2798 if (argv_find(argv
, argc
, "detailed", &idx
))
2801 return dplane_show_provs_helper(vty
, detailed
);
2804 /* Configure dataplane incoming queue limit */
2805 DEFUN (zebra_dplane_queue_limit
,
2806 zebra_dplane_queue_limit_cmd
,
2807 "zebra dplane limit (0-10000)",
2810 "Limit incoming queued updates\n"
2811 "Number of queued updates\n")
2815 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2817 dplane_set_in_queue_limit(limit
, true);
2822 /* Reset dataplane queue limit to default value */
2823 DEFUN (no_zebra_dplane_queue_limit
,
2824 no_zebra_dplane_queue_limit_cmd
,
2825 "no zebra dplane limit [(0-10000)]",
2829 "Limit incoming queued updates\n"
2830 "Number of queued updates\n")
2832 dplane_set_in_queue_limit(0, false);
2837 DEFUN (zebra_show_routing_tables_summary
,
2838 zebra_show_routing_tables_summary_cmd
,
2839 "show zebra router table summary",
2842 "The Zebra Router Information\n"
2843 "Table Information about this Zebra Router\n"
2844 "Summary Information\n")
2846 zebra_router_show_table_summary(vty
);
2851 /* Table configuration write function. */
2852 static int config_write_table(struct vty
*vty
)
2854 if (zrouter
.rtm_table_default
)
2855 vty_out(vty
, "table %d\n", zrouter
.rtm_table_default
);
2859 /* IPForwarding configuration write function. */
2860 static int config_write_forwarding(struct vty
*vty
)
2862 /* FIXME: Find better place for that. */
2863 router_id_write(vty
);
2866 vty_out(vty
, "no ip forwarding\n");
2867 if (!ipforward_ipv6())
2868 vty_out(vty
, "no ipv6 forwarding\n");
2869 vty_out(vty
, "!\n");
2873 /* IP node for static routes. */
2874 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2875 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2876 /* table node for routing tables. */
2877 static struct cmd_node table_node
= {TABLE_NODE
,
2878 "", /* This node has no interface. */
2880 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2881 "", /* This node has no interface. */
2885 void zebra_vty_init(void)
2887 /* Install configuration write function. */
2888 install_node(&table_node
, config_write_table
);
2889 install_node(&forwarding_node
, config_write_forwarding
);
2891 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2892 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2893 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2894 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2897 install_element(VIEW_NODE
, &show_table_cmd
);
2898 install_element(CONFIG_NODE
, &config_table_cmd
);
2899 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2900 #endif /* HAVE_NETLINK */
2902 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2903 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2904 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2907 zebra_route_map_init();
2909 install_node(&ip_node
, zebra_ip_config
);
2910 install_node(&protocol_node
, config_write_protocol
);
2912 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2913 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2915 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2916 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2918 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2919 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2920 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2921 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2922 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2923 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2925 install_element(VIEW_NODE
, &show_vrf_cmd
);
2926 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2927 install_element(VIEW_NODE
, &show_route_cmd
);
2928 install_element(VIEW_NODE
, &show_route_table_cmd
);
2929 if (vrf_is_backend_netns())
2930 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2931 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2932 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2933 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2934 install_element(VIEW_NODE
, &show_ip_import_check_cmd
);
2936 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2937 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2939 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2940 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2941 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2942 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2943 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2944 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2945 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2946 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2947 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2949 /* Commands for VRF */
2950 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2952 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2953 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2954 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
2955 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2956 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2957 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2958 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2959 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2960 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2961 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2962 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2963 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2964 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
2965 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2966 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2967 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2968 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2969 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2970 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2971 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2972 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2973 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2974 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2975 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
2976 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
2977 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
2979 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2980 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2982 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2983 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2984 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2985 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2987 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2988 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2989 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2990 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
2992 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);