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
;
386 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
389 uptime
-= re
->uptime
;
390 tm
= gmtime(&uptime
);
393 json_route
= json_object_new_object();
394 json_nexthops
= json_object_new_array();
396 json_object_string_add(json_route
, "prefix",
397 srcdest_rnode2str(rn
, buf
, sizeof buf
));
398 json_object_string_add(json_route
, "protocol",
399 zebra_route_string(re
->type
));
402 json_object_int_add(json_route
, "instance",
406 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
408 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
409 json_object_boolean_true_add(json_route
, "selected");
411 if (dest
->selected_fib
== re
)
412 json_object_boolean_true_add(json_route
,
415 json_object_int_add(json_route
, "distance",
417 json_object_int_add(json_route
, "metric", re
->metric
);
419 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
420 json_object_boolean_true_add(json_route
, "installed");
422 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
423 json_object_boolean_true_add(json_route
, "failed");
425 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
426 json_object_boolean_true_add(json_route
, "queued");
429 json_object_int_add(json_route
, "tag", re
->tag
);
431 json_object_int_add(json_route
, "internalStatus",
433 json_object_int_add(json_route
, "internalFlags",
435 if (uptime
< ONE_DAY_SECOND
)
436 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
438 else if (uptime
< ONE_WEEK_SECOND
)
439 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
442 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
443 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
446 json_object_string_add(json_route
, "uptime", buf
);
448 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
449 json_nexthop
= json_object_new_object();
451 json_object_int_add(json_nexthop
, "flags",
454 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
455 json_object_boolean_true_add(json_nexthop
,
458 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
459 json_object_boolean_true_add(json_nexthop
,
462 switch (nexthop
->type
) {
463 case NEXTHOP_TYPE_IPV4
:
464 case NEXTHOP_TYPE_IPV4_IFINDEX
:
465 json_object_string_add(
467 inet_ntoa(nexthop
->gate
.ipv4
));
468 json_object_string_add(json_nexthop
, "afi",
471 if (nexthop
->ifindex
) {
472 json_object_int_add(json_nexthop
,
475 json_object_string_add(
476 json_nexthop
, "interfaceName",
482 case NEXTHOP_TYPE_IPV6
:
483 case NEXTHOP_TYPE_IPV6_IFINDEX
:
484 json_object_string_add(
486 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
488 json_object_string_add(json_nexthop
, "afi",
491 if (nexthop
->ifindex
) {
492 json_object_int_add(json_nexthop
,
495 json_object_string_add(
496 json_nexthop
, "interfaceName",
503 case NEXTHOP_TYPE_IFINDEX
:
504 json_object_boolean_true_add(
505 json_nexthop
, "directlyConnected");
506 json_object_int_add(json_nexthop
,
509 json_object_string_add(
510 json_nexthop
, "interfaceName",
511 ifindex2ifname(nexthop
->ifindex
,
514 case NEXTHOP_TYPE_BLACKHOLE
:
515 json_object_boolean_true_add(json_nexthop
,
517 switch (nexthop
->bh_type
) {
518 case BLACKHOLE_REJECT
:
519 json_object_boolean_true_add(
520 json_nexthop
, "reject");
522 case BLACKHOLE_ADMINPROHIB
:
523 json_object_boolean_true_add(
528 json_object_boolean_true_add(
529 json_nexthop
, "blackhole");
531 case BLACKHOLE_UNSPEC
:
539 if ((nexthop
->vrf_id
!= re
->vrf_id
)
540 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
542 vrf_lookup_by_id(nexthop
->vrf_id
);
544 json_object_string_add(json_nexthop
, "vrf",
547 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
548 json_object_boolean_true_add(json_nexthop
,
551 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
552 json_object_boolean_true_add(json_nexthop
,
555 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
556 json_object_boolean_true_add(json_nexthop
,
559 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
560 json_object_boolean_true_add(json_nexthop
,
563 switch (nexthop
->type
) {
564 case NEXTHOP_TYPE_IPV4
:
565 case NEXTHOP_TYPE_IPV4_IFINDEX
:
566 if (nexthop
->src
.ipv4
.s_addr
) {
567 if (inet_ntop(AF_INET
,
568 &nexthop
->src
.ipv4
, buf
,
570 json_object_string_add(
571 json_nexthop
, "source",
575 case NEXTHOP_TYPE_IPV6
:
576 case NEXTHOP_TYPE_IPV6_IFINDEX
:
577 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
579 if (inet_ntop(AF_INET6
,
580 &nexthop
->src
.ipv6
, buf
,
582 json_object_string_add(
583 json_nexthop
, "source",
591 if (nexthop
->nh_label
592 && nexthop
->nh_label
->num_labels
) {
593 json_labels
= json_object_new_array();
595 for (int label_index
= 0;
597 < nexthop
->nh_label
->num_labels
;
599 json_object_array_add(
602 nexthop
->nh_label
->label
605 json_object_object_add(json_nexthop
, "labels",
609 json_object_array_add(json_nexthops
, json_nexthop
);
612 json_object_object_add(json_route
, "nexthops", json_nexthops
);
613 json_object_array_add(json
, json_route
);
617 /* Nexthop information. */
618 for (ALL_NEXTHOPS(re
->ng
, nexthop
)) {
619 if (nexthop
== re
->ng
.nexthop
) {
620 /* Prefix information. */
621 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
623 len
+= vty_out(vty
, "[%d]", re
->instance
);
626 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
629 re_status_output_char(re
, nexthop
),
630 srcdest_rnode2str(rn
, buf
, sizeof buf
));
632 /* Distance and metric display. */
633 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
634 (re
->distance
|| re
->metric
)) ||
635 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
636 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
639 vty_out(vty
, " %c%*c",
640 re_status_output_char(re
, nexthop
),
641 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
644 switch (nexthop
->type
) {
645 case NEXTHOP_TYPE_IPV4
:
646 case NEXTHOP_TYPE_IPV4_IFINDEX
:
647 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
648 if (nexthop
->ifindex
)
650 ifindex2ifname(nexthop
->ifindex
,
653 case NEXTHOP_TYPE_IPV6
:
654 case NEXTHOP_TYPE_IPV6_IFINDEX
:
655 vty_out(vty
, " via %s",
656 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
658 if (nexthop
->ifindex
)
660 ifindex2ifname(nexthop
->ifindex
,
664 case NEXTHOP_TYPE_IFINDEX
:
665 vty_out(vty
, " is directly connected, %s",
666 ifindex2ifname(nexthop
->ifindex
,
669 case NEXTHOP_TYPE_BLACKHOLE
:
670 vty_out(vty
, " unreachable");
671 switch (nexthop
->bh_type
) {
672 case BLACKHOLE_REJECT
:
673 vty_out(vty
, " (ICMP unreachable)");
675 case BLACKHOLE_ADMINPROHIB
:
676 vty_out(vty
, " (ICMP admin-prohibited)");
679 vty_out(vty
, " (blackhole)");
681 case BLACKHOLE_UNSPEC
:
689 if ((nexthop
->vrf_id
!= re
->vrf_id
)
690 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
691 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
694 vty_out(vty
, "(vrf %s)", vrf
->name
);
696 vty_out(vty
, "(vrf UNKNOWN)");
699 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
700 vty_out(vty
, " inactive");
702 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
703 vty_out(vty
, " onlink");
705 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
706 vty_out(vty
, " (recursive)");
708 switch (nexthop
->type
) {
709 case NEXTHOP_TYPE_IPV4
:
710 case NEXTHOP_TYPE_IPV4_IFINDEX
:
711 if (nexthop
->src
.ipv4
.s_addr
) {
712 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
714 vty_out(vty
, ", src %s", buf
);
717 case NEXTHOP_TYPE_IPV6
:
718 case NEXTHOP_TYPE_IPV6_IFINDEX
:
719 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
720 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
722 vty_out(vty
, ", src %s", buf
);
729 /* Label information */
730 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
731 vty_out(vty
, ", label %s",
732 mpls_label2str(nexthop
->nh_label
->num_labels
,
733 nexthop
->nh_label
->label
, buf
,
737 if (uptime
< ONE_DAY_SECOND
)
738 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
739 tm
->tm_min
, tm
->tm_sec
);
740 else if (uptime
< ONE_WEEK_SECOND
)
741 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
742 tm
->tm_hour
, tm
->tm_min
);
744 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
745 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
751 static void vty_show_ip_route_detail_json(struct vty
*vty
,
752 struct route_node
*rn
)
754 json_object
*json
= NULL
;
755 json_object
*json_prefix
= NULL
;
756 struct route_entry
*re
;
759 json
= json_object_new_object();
760 json_prefix
= json_object_new_array();
762 RNODE_FOREACH_RE (rn
, re
) {
763 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
766 prefix2str(&rn
->p
, buf
, sizeof(buf
));
767 json_object_object_add(json
, buf
, json_prefix
);
768 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
769 json
, JSON_C_TO_STRING_PRETTY
));
770 json_object_free(json
);
773 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
774 struct route_table
*table
, afi_t afi
,
775 bool use_fib
, route_tag_t tag
,
776 const struct prefix
*longer_prefix_p
,
777 bool supernets_only
, int type
,
778 unsigned short ospf_instance_id
, bool use_json
)
780 struct route_node
*rn
;
781 struct route_entry
*re
;
784 json_object
*json
= NULL
;
785 json_object
*json_prefix
= NULL
;
790 json
= json_object_new_object();
792 /* Show all routes. */
793 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
794 dest
= rib_dest_from_rnode(rn
);
796 RNODE_FOREACH_RE (rn
, re
) {
797 if (use_fib
&& re
!= dest
->selected_fib
)
800 if (tag
&& re
->tag
!= tag
)
804 && !prefix_match(longer_prefix_p
, &rn
->p
))
807 /* This can only be true when the afi is IPv4 */
808 if (supernets_only
) {
809 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
811 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
814 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
817 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
821 if (type
&& re
->type
!= type
)
825 && (re
->type
!= ZEBRA_ROUTE_OSPF
826 || re
->instance
!= ospf_instance_id
))
831 json_prefix
= json_object_new_array();
836 SHOW_ROUTE_V4_HEADER
);
839 SHOW_ROUTE_V6_HEADER
);
841 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
842 vty_out(vty
, "\nVRF %s:\n",
849 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
853 prefix2str(&rn
->p
, buf
, sizeof(buf
));
854 json_object_object_add(json
, buf
, json_prefix
);
860 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
861 JSON_C_TO_STRING_PRETTY
));
862 json_object_free(json
);
866 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
867 safi_t safi
, bool use_fib
, bool use_json
,
869 const struct prefix
*longer_prefix_p
,
870 bool supernets_only
, int type
,
871 unsigned short ospf_instance_id
)
873 struct route_table
*table
;
874 struct zebra_vrf
*zvrf
= NULL
;
876 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
878 vty_out(vty
, "{}\n");
880 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
884 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
886 vty_out(vty
, "{}\n");
888 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
892 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
895 vty_out(vty
, "{}\n");
899 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
900 longer_prefix_p
, supernets_only
, type
,
901 ospf_instance_id
, use_json
);
906 DEFPY (show_route_table
,
907 show_route_table_cmd
,
908 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
914 "The table number to display, if available\n"
917 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
918 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
919 struct route_table
*t
;
921 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
923 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
929 DEFPY (show_route_table_vrf
,
930 show_route_table_vrf_cmd
,
931 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
937 "The table number to display, if available\n"
941 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
942 struct zebra_vrf
*zvrf
;
943 struct route_table
*t
;
944 vrf_id_t vrf_id
= VRF_DEFAULT
;
947 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
948 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
950 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
952 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
960 "show <ip$ipv4|ipv6$ipv6> <nht|import-check>$type [<A.B.C.D|X:X::X:X>$addr|vrf NAME$vrf_name <A.B.C.D|X:X::X:X>$addr|vrf all$vrf_all]",
964 "IP nexthop tracking table\n"
965 "IP import check tracking table\n"
971 VRF_ALL_CMD_HELP_STR
)
973 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
974 vrf_id_t vrf_id
= VRF_DEFAULT
;
975 struct prefix prefix
, *p
= NULL
;
978 if (strcmp(type
, "nht") == 0)
979 rtype
= RNH_NEXTHOP_TYPE
;
981 rtype
= RNH_IMPORT_CHECK_TYPE
;
985 struct zebra_vrf
*zvrf
;
987 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
988 if ((zvrf
= vrf
->info
) != NULL
) {
989 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
990 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
996 VRF_GET_ID(vrf_id
, vrf_name
, false);
998 memset(&prefix
, 0, sizeof(prefix
));
1000 p
= sockunion2hostprefix(addr
, &prefix
);
1002 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1006 DEFUN (ip_nht_default_route
,
1007 ip_nht_default_route_cmd
,
1008 "ip nht resolve-via-default",
1010 "Filter Next Hop tracking route resolution\n"
1011 "Resolve via default route\n")
1013 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1018 if (zebra_rnh_ip_default_route
)
1021 zebra_rnh_ip_default_route
= 1;
1023 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1027 DEFUN (no_ip_nht_default_route
,
1028 no_ip_nht_default_route_cmd
,
1029 "no ip nht resolve-via-default",
1032 "Filter Next Hop tracking route resolution\n"
1033 "Resolve via default route\n")
1035 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1040 if (!zebra_rnh_ip_default_route
)
1043 zebra_rnh_ip_default_route
= 0;
1044 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1048 DEFUN (ipv6_nht_default_route
,
1049 ipv6_nht_default_route_cmd
,
1050 "ipv6 nht resolve-via-default",
1052 "Filter Next Hop tracking route resolution\n"
1053 "Resolve via default route\n")
1055 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1060 if (zebra_rnh_ipv6_default_route
)
1063 zebra_rnh_ipv6_default_route
= 1;
1064 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1068 DEFUN (no_ipv6_nht_default_route
,
1069 no_ipv6_nht_default_route_cmd
,
1070 "no ipv6 nht resolve-via-default",
1073 "Filter Next Hop tracking route resolution\n"
1074 "Resolve via default route\n")
1077 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1082 if (!zebra_rnh_ipv6_default_route
)
1085 zebra_rnh_ipv6_default_route
= 0;
1086 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1094 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1097 |A.B.C.D/M$prefix longer-prefixes\
1098 |supernets-only$supernets_only\
1101 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1102 |ospf$type_str (1-65535)$ospf_instance_id\
1104 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1107 |X:X::X:X/M$prefix longer-prefixes\
1109 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1114 "IP forwarding table\n"
1115 "IP routing table\n"
1116 VRF_FULL_CMD_HELP_STR
1117 "Show only routes with tag\n"
1119 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1120 "Show route matching the specified Network/Mask pair only\n"
1121 "Show supernet entries only\n"
1122 FRR_IP_REDIST_HELP_STR_ZEBRA
1123 "Open Shortest Path First (OSPFv2)\n"
1126 "IP forwarding table\n"
1127 "IP routing table\n"
1128 VRF_FULL_CMD_HELP_STR
1129 "Show only routes with tag\n"
1132 "Show route matching the specified Network/Mask pair only\n"
1133 FRR_IP6_REDIST_HELP_STR_ZEBRA
1136 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1141 type
= proto_redistnum(afi
, type_str
);
1143 vty_out(vty
, "Unknown route type\n");
1149 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1150 struct zebra_vrf
*zvrf
;
1151 struct route_table
*table
;
1153 if ((zvrf
= vrf
->info
) == NULL
1154 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1158 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1159 !!json
, tag
, prefix_str
? prefix
: NULL
,
1160 !!supernets_only
, type
, ospf_instance_id
);
1163 vrf_id_t vrf_id
= VRF_DEFAULT
;
1166 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1167 vrf
= vrf_lookup_by_id(vrf_id
);
1168 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1169 !!json
, tag
, prefix_str
? prefix
: NULL
,
1170 !!supernets_only
, type
, ospf_instance_id
);
1176 DEFPY (show_route_detail
,
1177 show_route_detail_cmd
,
1180 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1185 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1194 "IP routing table\n"
1195 VRF_FULL_CMD_HELP_STR
1196 "Network in the IP routing table to display\n"
1197 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1199 "IP routing table\n"
1200 VRF_FULL_CMD_HELP_STR
1205 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1206 struct route_table
*table
;
1208 struct route_node
*rn
;
1211 prefix_str
= address_str
;
1212 if (str2prefix(prefix_str
, &p
) < 0) {
1213 vty_out(vty
, "%% Malformed address\n");
1219 struct zebra_vrf
*zvrf
;
1221 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1222 if ((zvrf
= vrf
->info
) == NULL
1223 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1226 rn
= route_node_match(table
, &p
);
1229 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1230 route_unlock_node(rn
);
1235 vty_show_ip_route_detail_json(vty
, rn
);
1237 vty_show_ip_route_detail(vty
, rn
, 0);
1239 route_unlock_node(rn
);
1242 vrf_id_t vrf_id
= VRF_DEFAULT
;
1245 VRF_GET_ID(vrf_id
, vrf_name
, false);
1247 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1251 rn
= route_node_match(table
, &p
);
1253 vty_out(vty
, "%% Network not in table\n");
1256 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1257 vty_out(vty
, "%% Network not in table\n");
1258 route_unlock_node(rn
);
1263 vty_show_ip_route_detail_json(vty
, rn
);
1265 vty_show_ip_route_detail(vty
, rn
, 0);
1267 route_unlock_node(rn
);
1273 DEFPY (show_route_summary
,
1274 show_route_summary_cmd
,
1277 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1278 summary [prefix$prefix]\
1279 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1280 summary [prefix$prefix]\
1284 "IP routing table\n"
1285 VRF_FULL_CMD_HELP_STR
1286 "Summary of all routes\n"
1289 "IP routing table\n"
1290 VRF_FULL_CMD_HELP_STR
1291 "Summary of all routes\n"
1294 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1295 struct route_table
*table
;
1299 struct zebra_vrf
*zvrf
;
1301 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1302 if ((zvrf
= vrf
->info
) == NULL
1303 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1307 vty_show_ip_route_summary_prefix(vty
, table
);
1309 vty_show_ip_route_summary(vty
, table
);
1312 vrf_id_t vrf_id
= VRF_DEFAULT
;
1315 VRF_GET_ID(vrf_id
, vrf_name
, false);
1317 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1322 vty_show_ip_route_summary_prefix(vty
, table
);
1324 vty_show_ip_route_summary(vty
, table
);
1330 static void vty_show_ip_route_summary(struct vty
*vty
,
1331 struct route_table
*table
)
1333 struct route_node
*rn
;
1334 struct route_entry
*re
;
1335 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1336 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1337 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1338 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1342 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1343 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1344 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1345 RNODE_FOREACH_RE (rn
, re
) {
1346 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1347 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1349 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1351 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1353 rib_cnt
[re
->type
]++;
1355 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1356 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1359 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1361 fib_cnt
[re
->type
]++;
1365 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1366 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1368 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1369 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1370 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1371 if (i
== ZEBRA_ROUTE_BGP
) {
1372 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1373 rib_cnt
[ZEBRA_ROUTE_BGP
],
1374 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1375 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1376 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1377 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1379 vty_out(vty
, "%-20s %-20d %-20d \n",
1380 zebra_route_string(i
), rib_cnt
[i
],
1385 vty_out(vty
, "------\n");
1386 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1387 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1392 * Implementation of the ip route summary prefix command.
1394 * This command prints the primary prefixes that have been installed by various
1395 * protocols on the box.
1398 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1399 struct route_table
*table
)
1401 struct route_node
*rn
;
1402 struct route_entry
*re
;
1403 struct nexthop
*nexthop
;
1404 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1405 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1406 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1407 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1411 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1412 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1413 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1414 RNODE_FOREACH_RE (rn
, re
) {
1417 * In case of ECMP, count only once.
1420 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1421 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1422 fib_cnt
[re
->type
]++;
1424 for (nexthop
= re
->ng
.nexthop
; (!cnt
&& nexthop
);
1425 nexthop
= nexthop
->next
) {
1427 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1428 rib_cnt
[re
->type
]++;
1429 if (re
->type
== ZEBRA_ROUTE_BGP
1430 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1431 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1432 if (CHECK_FLAG(re
->status
,
1433 ROUTE_ENTRY_INSTALLED
))
1434 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1439 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1440 "Prefix Routes", "FIB",
1441 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1443 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1444 if (rib_cnt
[i
] > 0) {
1445 if (i
== ZEBRA_ROUTE_BGP
) {
1446 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1447 rib_cnt
[ZEBRA_ROUTE_BGP
]
1448 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1449 fib_cnt
[ZEBRA_ROUTE_BGP
]
1450 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1451 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1452 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1453 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1455 vty_out(vty
, "%-20s %-20d %-20d \n",
1456 zebra_route_string(i
), rib_cnt
[i
],
1461 vty_out(vty
, "------\n");
1462 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1463 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1468 * Show IPv6 mroute command.Used to dump
1469 * the Multicast routing table.
1471 DEFUN (show_ipv6_mroute
,
1472 show_ipv6_mroute_cmd
,
1473 "show ipv6 mroute [vrf NAME]",
1476 "IPv6 Multicast routing table\n"
1479 struct route_table
*table
;
1480 struct route_node
*rn
;
1481 struct route_entry
*re
;
1483 vrf_id_t vrf_id
= VRF_DEFAULT
;
1486 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1488 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1492 /* Show all IPv6 route. */
1493 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1494 RNODE_FOREACH_RE (rn
, re
) {
1496 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1499 vty_show_ip_route(vty
, rn
, re
, NULL
);
1504 DEFUN (show_ipv6_mroute_vrf_all
,
1505 show_ipv6_mroute_vrf_all_cmd
,
1506 "show ipv6 mroute vrf all",
1509 "IPv6 Multicast routing table\n"
1510 VRF_ALL_CMD_HELP_STR
)
1512 struct route_table
*table
;
1513 struct route_node
*rn
;
1514 struct route_entry
*re
;
1516 struct zebra_vrf
*zvrf
;
1519 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1520 if ((zvrf
= vrf
->info
) == NULL
1521 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1524 /* Show all IPv6 route. */
1525 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1526 RNODE_FOREACH_RE (rn
, re
) {
1528 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1531 vty_show_ip_route(vty
, rn
, re
, NULL
);
1537 DEFUN (allow_external_route_update
,
1538 allow_external_route_update_cmd
,
1539 "allow-external-route-update",
1540 "Allow FRR routes to be overwritten by external processes\n")
1547 DEFUN (no_allow_external_route_update
,
1548 no_allow_external_route_update_cmd
,
1549 "no allow-external-route-update",
1551 "Allow FRR routes to be overwritten by external processes\n")
1566 struct zebra_vrf
*zvrf
;
1568 if (vrf_is_backend_netns())
1569 vty_out(vty
, "netns-based vrfs\n");
1571 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1572 if (!(zvrf
= vrf
->info
))
1574 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1577 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1578 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1579 vty_out(vty
, "inactive");
1580 else if (zvrf_ns_name(zvrf
))
1581 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
1582 zvrf_ns_name(zvrf
));
1584 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1586 if (vrf_is_user_cfged(vrf
))
1587 vty_out(vty
, " (configured)");
1594 DEFUN (default_vrf_vni_mapping
,
1595 default_vrf_vni_mapping_cmd
,
1596 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1597 "VNI corresponding to the DEFAULT VRF\n"
1599 "Prefix routes only \n")
1602 char err
[ERR_STR_SZ
];
1603 struct zebra_vrf
*zvrf
= NULL
;
1604 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1607 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1614 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1617 vty_out(vty
, "%s\n", err
);
1624 DEFUN (no_default_vrf_vni_mapping
,
1625 no_default_vrf_vni_mapping_cmd
,
1626 "no vni " CMD_VNI_RANGE
,
1628 "VNI corresponding to DEFAULT VRF\n"
1632 char err
[ERR_STR_SZ
];
1633 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1634 struct zebra_vrf
*zvrf
= NULL
;
1636 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
1640 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
1642 vty_out(vty
, "%s\n", err
);
1649 DEFUN (vrf_vni_mapping
,
1650 vrf_vni_mapping_cmd
,
1651 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1652 "VNI corresponding to tenant VRF\n"
1654 "prefix-routes-only\n")
1659 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1660 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1661 char err
[ERR_STR_SZ
];
1669 /* Mark as having FRR configuration */
1670 vrf_set_user_cfged(vrf
);
1671 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
1674 vty_out(vty
, "%s\n", err
);
1681 DEFUN (no_vrf_vni_mapping
,
1682 no_vrf_vni_mapping_cmd
,
1683 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
1685 "VNI corresponding to tenant VRF\n"
1687 "prefix-routes-only\n")
1691 char err
[ERR_STR_SZ
];
1692 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1694 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1702 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
1703 ERR_STR_SZ
, filter
, 0);
1705 vty_out(vty
, "%s\n", err
);
1709 /* If no other FRR config for this VRF, mark accordingly. */
1710 if (!zebra_vrf_has_config(zvrf
))
1711 vrf_reset_user_cfged(vrf
);
1717 DEFUN (show_vrf_vni
,
1719 "show vrf vni [json]",
1726 struct zebra_vrf
*zvrf
;
1727 json_object
*json
= NULL
;
1728 json_object
*json_vrfs
= NULL
;
1729 bool uj
= use_json(argc
, argv
);
1732 json
= json_object_new_object();
1733 json_vrfs
= json_object_new_array();
1737 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
1738 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
1740 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1745 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
1749 json_object_object_add(json
, "vrfs", json_vrfs
);
1750 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1751 json
, JSON_C_TO_STRING_PRETTY
));
1752 json_object_free(json
);
1758 DEFUN (show_evpn_global
,
1759 show_evpn_global_cmd
,
1765 bool uj
= use_json(argc
, argv
);
1767 zebra_vxlan_print_evpn(vty
, uj
);
1771 DEFUN (show_evpn_vni
,
1773 "show evpn vni [json]",
1776 "VxLAN Network Identifier\n"
1779 struct zebra_vrf
*zvrf
;
1780 bool uj
= use_json(argc
, argv
);
1782 zvrf
= zebra_vrf_get_evpn();
1783 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
1787 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
1788 "show evpn vni detail [json]",
1791 "VxLAN Network Identifier\n"
1792 "Detailed Information On Each VNI\n"
1795 struct zebra_vrf
*zvrf
;
1796 bool uj
= use_json(argc
, argv
);
1798 zvrf
= zebra_vrf_get_evpn();
1799 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
1803 DEFUN (show_evpn_vni_vni
,
1804 show_evpn_vni_vni_cmd
,
1805 "show evpn vni " CMD_VNI_RANGE
"[json]",
1808 "VxLAN Network Identifier\n"
1812 struct zebra_vrf
*zvrf
;
1814 bool uj
= use_json(argc
, argv
);
1816 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
1817 zvrf
= zebra_vrf_get_evpn();
1818 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
1822 DEFUN (show_evpn_rmac_vni_mac
,
1823 show_evpn_rmac_vni_mac_cmd
,
1824 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
1831 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
1836 bool uj
= use_json(argc
, argv
);
1838 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1839 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
1840 vty_out(vty
, "%% Malformed MAC address\n");
1843 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
1847 DEFUN (show_evpn_rmac_vni
,
1848 show_evpn_rmac_vni_cmd
,
1849 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
1858 bool uj
= use_json(argc
, argv
);
1860 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1861 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
1866 DEFUN (show_evpn_rmac_vni_all
,
1867 show_evpn_rmac_vni_all_cmd
,
1868 "show evpn rmac vni all [json]",
1876 bool uj
= use_json(argc
, argv
);
1878 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
1883 DEFUN (show_evpn_nh_vni_ip
,
1884 show_evpn_nh_vni_ip_cmd
,
1885 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
1892 "Host address (ipv4 or ipv6)\n"
1897 bool uj
= use_json(argc
, argv
);
1899 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1900 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
1902 vty_out(vty
, "%% Malformed Neighbor address\n");
1905 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
1910 DEFUN (show_evpn_nh_vni
,
1911 show_evpn_nh_vni_cmd
,
1912 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
1921 bool uj
= use_json(argc
, argv
);
1923 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1924 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
1929 DEFUN (show_evpn_nh_vni_all
,
1930 show_evpn_nh_vni_all_cmd
,
1931 "show evpn next-hops vni all [json]",
1939 bool uj
= use_json(argc
, argv
);
1941 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
1946 DEFUN (show_evpn_mac_vni
,
1947 show_evpn_mac_vni_cmd
,
1948 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
1952 "VxLAN Network Identifier\n"
1956 struct zebra_vrf
*zvrf
;
1958 bool uj
= use_json(argc
, argv
);
1960 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
1961 zvrf
= zebra_vrf_get_evpn();
1962 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
1966 DEFUN (show_evpn_mac_vni_all
,
1967 show_evpn_mac_vni_all_cmd
,
1968 "show evpn mac vni all [json]",
1972 "VxLAN Network Identifier\n"
1976 struct zebra_vrf
*zvrf
;
1977 bool uj
= use_json(argc
, argv
);
1979 zvrf
= zebra_vrf_get_evpn();
1980 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
1984 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
1985 "show evpn mac vni all detail [json]",
1989 "VxLAN Network Identifier\n"
1991 "Detailed Information On Each VNI MAC\n"
1994 struct zebra_vrf
*zvrf
;
1995 bool uj
= use_json(argc
, argv
);
1997 zvrf
= zebra_vrf_get_evpn();
1998 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2002 DEFUN (show_evpn_mac_vni_all_vtep
,
2003 show_evpn_mac_vni_all_vtep_cmd
,
2004 "show evpn mac vni all vtep A.B.C.D [json]",
2008 "VxLAN Network Identifier\n"
2011 "Remote VTEP IP address\n"
2014 struct zebra_vrf
*zvrf
;
2015 struct in_addr vtep_ip
;
2016 bool uj
= use_json(argc
, argv
);
2018 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2020 vty_out(vty
, "%% Malformed VTEP IP address\n");
2023 zvrf
= zebra_vrf_get_evpn();
2024 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2030 DEFUN (show_evpn_mac_vni_mac
,
2031 show_evpn_mac_vni_mac_cmd
,
2032 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2036 "VxLAN Network Identifier\n"
2039 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2043 struct zebra_vrf
*zvrf
;
2046 bool uj
= use_json(argc
, argv
);
2048 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2049 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2050 vty_out(vty
, "%% Malformed MAC address");
2053 zvrf
= zebra_vrf_get_evpn();
2054 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2058 DEFUN (show_evpn_mac_vni_vtep
,
2059 show_evpn_mac_vni_vtep_cmd
,
2060 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2064 "VxLAN Network Identifier\n"
2067 "Remote VTEP IP address\n"
2070 struct zebra_vrf
*zvrf
;
2072 struct in_addr vtep_ip
;
2073 bool uj
= use_json(argc
, argv
);
2075 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2076 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2078 vty_out(vty
, "%% Malformed VTEP IP address\n");
2082 zvrf
= zebra_vrf_get_evpn();
2083 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2087 DEFPY (show_evpn_mac_vni_all_dad
,
2088 show_evpn_mac_vni_all_dad_cmd
,
2089 "show evpn mac vni all duplicate [json]",
2093 "VxLAN Network Identifier\n"
2095 "Duplicate address list\n"
2098 struct zebra_vrf
*zvrf
;
2099 bool uj
= use_json(argc
, argv
);
2101 zvrf
= zebra_vrf_get_evpn();
2102 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2107 DEFPY (show_evpn_mac_vni_dad
,
2108 show_evpn_mac_vni_dad_cmd
,
2109 "show evpn mac vni " CMD_VNI_RANGE
" duplicate" "[json]",
2113 "VxLAN Network Identifier\n"
2115 "Duplicate address list\n"
2118 struct zebra_vrf
*zvrf
;
2120 bool uj
= use_json(argc
, argv
);
2122 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2123 zvrf
= zebra_vrf_get_evpn();
2125 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2130 DEFPY (show_evpn_neigh_vni_dad
,
2131 show_evpn_neigh_vni_dad_cmd
,
2132 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate" "[json]",
2135 "ARP and ND cache\n"
2136 "VxLAN Network Identifier\n"
2138 "Duplicate address list\n"
2141 struct zebra_vrf
*zvrf
;
2143 bool uj
= use_json(argc
, argv
);
2145 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2146 zvrf
= zebra_vrf_get_evpn();
2147 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2151 DEFPY (show_evpn_neigh_vni_all_dad
,
2152 show_evpn_neigh_vni_all_dad_cmd
,
2153 "show evpn arp-cache vni all duplicate [json]",
2156 "ARP and ND cache\n"
2157 "VxLAN Network Identifier\n"
2159 "Duplicate address list\n"
2162 struct zebra_vrf
*zvrf
;
2163 bool uj
= use_json(argc
, argv
);
2165 zvrf
= zebra_vrf_get_evpn();
2166 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2171 DEFUN (show_evpn_neigh_vni
,
2172 show_evpn_neigh_vni_cmd
,
2173 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2176 "ARP and ND cache\n"
2177 "VxLAN Network Identifier\n"
2181 struct zebra_vrf
*zvrf
;
2183 bool uj
= use_json(argc
, argv
);
2185 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2186 zvrf
= zebra_vrf_get_evpn();
2187 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2191 DEFUN (show_evpn_neigh_vni_all
,
2192 show_evpn_neigh_vni_all_cmd
,
2193 "show evpn arp-cache vni all [json]",
2196 "ARP and ND cache\n"
2197 "VxLAN Network Identifier\n"
2201 struct zebra_vrf
*zvrf
;
2202 bool uj
= use_json(argc
, argv
);
2204 zvrf
= zebra_vrf_get_evpn();
2205 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2209 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2210 "show evpn arp-cache vni all detail [json]",
2213 "ARP and ND cache\n"
2214 "VxLAN Network Identifier\n"
2216 "Neighbor details for all vnis in detail\n" JSON_STR
)
2218 struct zebra_vrf
*zvrf
;
2219 bool uj
= use_json(argc
, argv
);
2221 zvrf
= zebra_vrf_get_evpn();
2222 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2226 DEFUN (show_evpn_neigh_vni_neigh
,
2227 show_evpn_neigh_vni_neigh_cmd
,
2228 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2231 "ARP and ND cache\n"
2232 "VxLAN Network Identifier\n"
2235 "Neighbor address (IPv4 or IPv6 address)\n"
2238 struct zebra_vrf
*zvrf
;
2241 bool uj
= use_json(argc
, argv
);
2243 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2244 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2246 vty_out(vty
, "%% Malformed Neighbor address\n");
2249 zvrf
= zebra_vrf_get_evpn();
2250 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2254 DEFUN (show_evpn_neigh_vni_vtep
,
2255 show_evpn_neigh_vni_vtep_cmd
,
2256 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2259 "ARP and ND cache\n"
2260 "VxLAN Network Identifier\n"
2263 "Remote VTEP IP address\n"
2266 struct zebra_vrf
*zvrf
;
2268 struct in_addr vtep_ip
;
2269 bool uj
= use_json(argc
, argv
);
2271 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2272 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2274 vty_out(vty
, "%% Malformed VTEP IP address\n");
2278 zvrf
= zebra_vrf_get_evpn();
2279 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2283 /* policy routing contexts */
2284 DEFUN (show_pbr_ipset
,
2286 "show pbr ipset [WORD]",
2288 "Policy-Based Routing\n"
2289 "IPset Context information\n"
2290 "IPset Name information\n")
2294 found
= argv_find(argv
, argc
, "WORD", &idx
);
2296 zebra_pbr_show_ipset_list(vty
, NULL
);
2298 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2302 /* policy routing contexts */
2303 DEFUN (show_pbr_iptable
,
2304 show_pbr_iptable_cmd
,
2305 "show pbr iptable [WORD]",
2307 "Policy-Based Routing\n"
2308 "IPtable Context information\n"
2309 "IPtable Name information\n")
2314 found
= argv_find(argv
, argc
, "WORD", &idx
);
2316 zebra_pbr_show_iptable(vty
, NULL
);
2318 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2322 DEFPY (clear_evpn_dup_addr
,
2323 clear_evpn_dup_addr_cmd
,
2324 "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>]>",
2327 "Duplicate address \n"
2328 "VxLAN Network Identifier\n"
2332 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2337 struct zebra_vrf
*zvrf
;
2339 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2340 struct ethaddr mac_addr
;
2341 int ret
= CMD_SUCCESS
;
2343 zvrf
= zebra_vrf_get_evpn();
2345 vni
= strtoul(vni_val
, NULL
, 10);
2348 prefix_str2mac(mac_val
, &mac_addr
);
2349 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2353 if (sockunion_family(ip
) == AF_INET
) {
2354 host_ip
.ipa_type
= IPADDR_V4
;
2355 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2357 host_ip
.ipa_type
= IPADDR_V6
;
2358 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2359 sizeof(struct in6_addr
));
2361 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2365 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2368 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2374 /* Static ip route configuration write function. */
2375 static int zebra_ip_config(struct vty
*vty
)
2379 write
+= zebra_import_table_config(vty
);
2384 DEFUN (ip_zebra_import_table_distance
,
2385 ip_zebra_import_table_distance_cmd
,
2386 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2388 "import routes from non-main kernel table\n"
2389 "kernel routing table id\n"
2390 "Distance for imported routes\n"
2391 "Default distance value\n"
2392 "route-map for filtering\n"
2395 uint32_t table_id
= 0;
2397 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2398 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2400 strmatch(argv
[argc
- 2]->text
, "route-map")
2401 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2405 if (argc
== 7 || (argc
== 5 && !rmap
))
2406 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2408 if (!is_zebra_valid_kernel_table(table_id
)) {
2410 "Invalid routing table ID, %d. Must be in range 1-252\n",
2413 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2417 if (is_zebra_main_routing_table(table_id
)) {
2419 "Invalid routing table ID, %d. Must be non-default table\n",
2422 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2426 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2428 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2433 DEFUN_HIDDEN (zebra_packet_process
,
2434 zebra_packet_process_cmd
,
2435 "zebra zapi-packets (1-10000)",
2438 "Number of packets to process before relinquishing thread\n")
2440 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2442 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2443 memory_order_relaxed
);
2448 DEFUN_HIDDEN (no_zebra_packet_process
,
2449 no_zebra_packet_process_cmd
,
2450 "no zebra zapi-packets [(1-10000)]",
2454 "Number of packets to process before relinquishing thread\n")
2456 atomic_store_explicit(&zrouter
.packets_to_process
,
2457 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2458 memory_order_relaxed
);
2463 DEFUN_HIDDEN (zebra_workqueue_timer
,
2464 zebra_workqueue_timer_cmd
,
2465 "zebra work-queue (0-10000)",
2468 "Time in milliseconds\n")
2470 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2471 zrouter
.ribq
->spec
.hold
= timer
;
2476 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2477 no_zebra_workqueue_timer_cmd
,
2478 "no zebra work-queue [(0-10000)]",
2482 "Time in milliseconds\n")
2484 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2489 DEFUN (no_ip_zebra_import_table
,
2490 no_ip_zebra_import_table_cmd
,
2491 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2494 "import routes from non-main kernel table\n"
2495 "kernel routing table id\n"
2496 "Distance for imported routes\n"
2497 "Default distance value\n"
2498 "route-map for filtering\n"
2501 uint32_t table_id
= 0;
2502 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2504 if (!is_zebra_valid_kernel_table(table_id
)) {
2506 "Invalid routing table ID. Must be in range 1-252\n");
2510 if (is_zebra_main_routing_table(table_id
)) {
2512 "Invalid routing table ID, %d. Must be non-default table\n",
2517 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2520 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2523 static int config_write_protocol(struct vty
*vty
)
2526 vty_out(vty
, "allow-external-route-update\n");
2528 if (zebra_rnh_ip_default_route
)
2529 vty_out(vty
, "ip nht resolve-via-default\n");
2531 if (zebra_rnh_ipv6_default_route
)
2532 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2534 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2535 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2537 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2538 vty_out(vty
, "zebra zapi-packets %u\n",
2539 zrouter
.packets_to_process
);
2541 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2543 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2544 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2545 ipv4_multicast_mode
== MCAST_URIB_ONLY
2547 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2549 : ipv4_multicast_mode
2550 == MCAST_MIX_MRIB_FIRST
2552 : ipv4_multicast_mode
2553 == MCAST_MIX_DISTANCE
2568 " Route Route Neighbor LSP LSP\n");
2570 "VRF Installs Removals Updates Installs Removals\n");
2572 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2573 struct zebra_vrf
*zvrf
= vrf
->info
;
2575 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2576 " %10" PRIu64
" %10" PRIu64
"\n",
2577 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2578 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2579 zvrf
->lsp_removals
);
2585 DEFUN (ip_forwarding
,
2589 "Turn on IP forwarding\n")
2595 ret
= ipforward_on();
2598 vty_out(vty
, "Can't turn on IP forwarding\n");
2599 return CMD_WARNING_CONFIG_FAILED
;
2605 DEFUN (no_ip_forwarding
,
2606 no_ip_forwarding_cmd
,
2610 "Turn off IP forwarding\n")
2616 ret
= ipforward_off();
2619 vty_out(vty
, "Can't turn off IP forwarding\n");
2620 return CMD_WARNING_CONFIG_FAILED
;
2626 /* Only display ip forwarding is enabled or not. */
2627 DEFUN (show_ip_forwarding
,
2628 show_ip_forwarding_cmd
,
2629 "show ip forwarding",
2632 "IP forwarding status\n")
2639 vty_out(vty
, "IP forwarding is off\n");
2641 vty_out(vty
, "IP forwarding is on\n");
2645 /* Only display ipv6 forwarding is enabled or not. */
2646 DEFUN (show_ipv6_forwarding
,
2647 show_ipv6_forwarding_cmd
,
2648 "show ipv6 forwarding",
2650 "IPv6 information\n"
2651 "Forwarding status\n")
2655 ret
= ipforward_ipv6();
2659 vty_out(vty
, "ipv6 forwarding is unknown\n");
2662 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2665 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2668 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2674 DEFUN (ipv6_forwarding
,
2675 ipv6_forwarding_cmd
,
2678 "Turn on IPv6 forwarding\n")
2682 ret
= ipforward_ipv6();
2684 ret
= ipforward_ipv6_on();
2687 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2688 return CMD_WARNING_CONFIG_FAILED
;
2694 DEFUN (no_ipv6_forwarding
,
2695 no_ipv6_forwarding_cmd
,
2696 "no ipv6 forwarding",
2699 "Turn off IPv6 forwarding\n")
2703 ret
= ipforward_ipv6();
2705 ret
= ipforward_ipv6_off();
2708 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2709 return CMD_WARNING_CONFIG_FAILED
;
2715 /* Display dataplane info */
2716 DEFUN (show_dataplane
,
2718 "show zebra dplane [detailed]",
2721 "Zebra dataplane information\n"
2722 "Detailed output\n")
2725 bool detailed
= false;
2727 if (argv_find(argv
, argc
, "detailed", &idx
))
2730 return dplane_show_helper(vty
, detailed
);
2733 /* Display dataplane providers info */
2734 DEFUN (show_dataplane_providers
,
2735 show_dataplane_providers_cmd
,
2736 "show zebra dplane providers [detailed]",
2739 "Zebra dataplane information\n"
2740 "Zebra dataplane provider information\n"
2741 "Detailed output\n")
2744 bool detailed
= false;
2746 if (argv_find(argv
, argc
, "detailed", &idx
))
2749 return dplane_show_provs_helper(vty
, detailed
);
2752 /* Configure dataplane incoming queue limit */
2753 DEFUN (zebra_dplane_queue_limit
,
2754 zebra_dplane_queue_limit_cmd
,
2755 "zebra dplane limit (0-10000)",
2758 "Limit incoming queued updates\n"
2759 "Number of queued updates\n")
2763 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
2765 dplane_set_in_queue_limit(limit
, true);
2770 /* Reset dataplane queue limit to default value */
2771 DEFUN (no_zebra_dplane_queue_limit
,
2772 no_zebra_dplane_queue_limit_cmd
,
2773 "no zebra dplane limit [(0-10000)]",
2777 "Limit incoming queued updates\n"
2778 "Number of queued updates\n")
2780 dplane_set_in_queue_limit(0, false);
2785 DEFUN (zebra_show_routing_tables_summary
,
2786 zebra_show_routing_tables_summary_cmd
,
2787 "show zebra router table summary",
2790 "The Zebra Router Information\n"
2791 "Table Information about this Zebra Router\n"
2792 "Summary Information\n")
2794 zebra_router_show_table_summary(vty
);
2799 /* Table configuration write function. */
2800 static int config_write_table(struct vty
*vty
)
2805 /* IPForwarding configuration write function. */
2806 static int config_write_forwarding(struct vty
*vty
)
2808 /* FIXME: Find better place for that. */
2809 router_id_write(vty
);
2812 vty_out(vty
, "no ip forwarding\n");
2813 if (!ipforward_ipv6())
2814 vty_out(vty
, "no ipv6 forwarding\n");
2815 vty_out(vty
, "!\n");
2819 DEFUN_HIDDEN (show_frr
,
2825 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
2826 vty_out(vty
, ".............................7777:..............................................\n");
2827 vty_out(vty
, ".............................777777,............................................\n");
2828 vty_out(vty
, "... .........................77777777,..........................................\n");
2829 vty_out(vty
, "............................=7777777777:........................................\n");
2830 vty_out(vty
, "........................:7777777777777777,......................................\n");
2831 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
2832 vty_out(vty
, "...................I7777777777+.................................................\n");
2833 vty_out(vty
, "................,777777777?............ .......................................\n");
2834 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
2835 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
2836 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
2837 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
2838 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
2839 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
2840 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
2841 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
2842 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
2843 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
2844 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
2845 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
2846 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
2847 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
2848 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
2849 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
2850 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
2851 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
2852 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
2853 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
2854 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
2855 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
2856 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
2857 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
2858 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
2859 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
2860 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
2861 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
2862 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
2863 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
2864 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
2865 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
2866 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
2867 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
2868 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
2869 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
2870 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
2871 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
2872 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
2873 vty_out(vty
, "............................~777777777777..............+777777..................\n");
2874 vty_out(vty
, "................................~77777777...............=777777.................\n");
2875 vty_out(vty
, ".....................................:=?I................~777777................\n");
2876 vty_out(vty
, "..........................................................:777777,..............\n");
2877 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
2882 /* IP node for static routes. */
2883 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2884 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2885 /* table node for routing tables. */
2886 static struct cmd_node table_node
= {TABLE_NODE
,
2887 "", /* This node has no interface. */
2889 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2890 "", /* This node has no interface. */
2894 void zebra_vty_init(void)
2896 /* Install configuration write function. */
2897 install_node(&table_node
, config_write_table
);
2898 install_node(&forwarding_node
, config_write_forwarding
);
2900 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2901 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2902 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2903 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2905 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2906 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2907 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2910 zebra_route_map_init();
2912 install_node(&ip_node
, zebra_ip_config
);
2913 install_node(&protocol_node
, config_write_protocol
);
2915 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2916 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2918 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2919 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2921 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2922 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2923 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2924 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2925 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2926 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2928 install_element(VIEW_NODE
, &show_vrf_cmd
);
2929 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2930 install_element(VIEW_NODE
, &show_route_cmd
);
2931 install_element(VIEW_NODE
, &show_route_table_cmd
);
2932 if (vrf_is_backend_netns())
2933 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
2934 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2935 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2936 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2938 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2939 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2941 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2942 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2943 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2944 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2945 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
2946 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
2947 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
2948 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
2949 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2951 /* Commands for VRF */
2952 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2954 install_element(VIEW_NODE
, &show_frr_cmd
);
2955 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
2956 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2957 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
2958 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2959 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
2960 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
2961 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
2962 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
2963 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
2964 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
2965 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2966 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2967 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
2968 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2969 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2970 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2971 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
2972 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
2973 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2974 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2975 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
2976 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2977 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2978 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
2979 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
2980 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
2982 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
2983 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
2985 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
2986 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
2987 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2988 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
2990 install_element(VIEW_NODE
, &show_dataplane_cmd
);
2991 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
2992 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
2993 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
2995 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);