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"
55 #include "zebra/zebra_nhg.h"
56 #include "zebra/interface.h"
58 extern int allow_delete
;
60 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
61 safi_t safi
, bool use_fib
, bool use_json
,
63 const struct prefix
*longer_prefix_p
,
64 bool supernets_only
, int type
,
65 unsigned short ospf_instance_id
);
66 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
67 int mcast
, bool use_fib
, bool show_ng
);
68 static void vty_show_ip_route_summary(struct vty
*vty
,
69 struct route_table
*table
);
70 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
71 struct route_table
*table
);
73 DEFUN (ip_multicast_mode
,
74 ip_multicast_mode_cmd
,
75 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
78 "RPF lookup behavior\n"
79 "Lookup in unicast RIB only\n"
80 "Lookup in multicast RIB only\n"
81 "Try multicast RIB first, fall back to unicast RIB\n"
82 "Lookup both, use entry with lower distance\n"
83 "Lookup both, use entry with longer prefix\n")
85 char *mode
= argv
[3]->text
;
87 if (strmatch(mode
, "urib-only"))
88 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
89 else if (strmatch(mode
, "mrib-only"))
90 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
91 else if (strmatch(mode
, "mrib-then-urib"))
92 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
93 else if (strmatch(mode
, "lower-distance"))
94 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
95 else if (strmatch(mode
, "longer-prefix"))
96 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
98 vty_out(vty
, "Invalid mode specified\n");
99 return CMD_WARNING_CONFIG_FAILED
;
105 DEFUN (no_ip_multicast_mode
,
106 no_ip_multicast_mode_cmd
,
107 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
110 "Multicast options\n"
111 "RPF lookup behavior\n"
112 "Lookup in unicast RIB only\n"
113 "Lookup in multicast RIB only\n"
114 "Try multicast RIB first, fall back to unicast RIB\n"
115 "Lookup both, use entry with lower distance\n"
116 "Lookup both, use entry with longer prefix\n")
118 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
125 "show ip rpf [json]",
128 "Display RPF information for multicast source\n"
131 bool uj
= use_json(argc
, argv
);
132 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
133 false, uj
, 0, NULL
, false, 0, 0);
136 DEFUN (show_ip_rpf_addr
,
137 show_ip_rpf_addr_cmd
,
138 "show ip rpf A.B.C.D",
141 "Display RPF information for multicast source\n"
142 "IP multicast source address (e.g. 10.0.0.0)\n")
146 struct route_node
*rn
;
147 struct route_entry
*re
;
150 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
152 vty_out(vty
, "%% Malformed address\n");
156 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
159 vty_show_ip_route_detail(vty
, rn
, 1, false, false);
161 vty_out(vty
, "%% No match for RPF lookup\n");
166 static char re_status_output_char(struct route_entry
*re
, struct nexthop
*nhop
)
168 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
169 if (!CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
170 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
176 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
177 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
183 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
189 /* New RIB. Detailed information for IPv4 route. */
190 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
191 int mcast
, bool use_fib
, bool show_ng
)
193 struct route_entry
*re
;
194 struct nexthop
*nexthop
;
195 char buf
[SRCDEST2STR_BUFFER
];
196 struct zebra_vrf
*zvrf
;
199 dest
= rib_dest_from_rnode(rn
);
201 RNODE_FOREACH_RE (rn
, re
) {
203 * If re not selected for forwarding, skip re
204 * for "show ip/ipv6 fib <prefix>"
206 if (use_fib
&& re
!= dest
->selected_fib
)
209 const char *mcast_info
= "";
211 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
212 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
213 ? " using Multicast RIB"
214 : " using Unicast RIB";
217 vty_out(vty
, "Routing entry for %s%s\n",
218 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
219 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
221 vty_out(vty
, "[%d]", re
->instance
);
223 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
226 vty_out(vty
, ", tag %u", re
->tag
);
227 #if defined(SUPPORT_REALMS)
228 if (re
->tag
> 0 && re
->tag
<= 255)
229 vty_out(vty
, "(realm)");
233 vty_out(vty
, ", mtu %u", re
->mtu
);
234 if (re
->vrf_id
!= VRF_DEFAULT
) {
235 zvrf
= vrf_info_lookup(re
->vrf_id
);
236 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
238 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
239 vty_out(vty
, ", best");
245 uptime
= monotime(NULL
);
246 uptime
-= re
->uptime
;
247 tm
= gmtime(&uptime
);
249 vty_out(vty
, " Last update ");
251 if (uptime
< ONE_DAY_SECOND
)
252 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
254 else if (uptime
< ONE_WEEK_SECOND
)
255 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
258 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
259 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
261 vty_out(vty
, " ago\n");
264 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
266 for (ALL_NEXTHOPS_PTR(re
->nhe
->nhg
, nexthop
)) {
269 vty_out(vty
, " %c%s",
270 re_status_output_char(re
, nexthop
),
271 nexthop
->rparent
? " " : "");
273 switch (nexthop
->type
) {
274 case NEXTHOP_TYPE_IPV4
:
275 case NEXTHOP_TYPE_IPV4_IFINDEX
:
277 inet_ntoa(nexthop
->gate
.ipv4
));
278 if (nexthop
->ifindex
)
279 vty_out(vty
, ", via %s",
284 case NEXTHOP_TYPE_IPV6
:
285 case NEXTHOP_TYPE_IPV6_IFINDEX
:
287 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
289 if (nexthop
->ifindex
)
290 vty_out(vty
, ", via %s",
295 case NEXTHOP_TYPE_IFINDEX
:
296 vty_out(vty
, " directly connected, %s",
297 ifindex2ifname(nexthop
->ifindex
,
300 case NEXTHOP_TYPE_BLACKHOLE
:
301 vty_out(vty
, " unreachable");
302 switch (nexthop
->bh_type
) {
303 case BLACKHOLE_REJECT
:
304 vty_out(vty
, " (ICMP unreachable)");
306 case BLACKHOLE_ADMINPROHIB
:
308 " (ICMP admin-prohibited)");
311 vty_out(vty
, " (blackhole)");
313 case BLACKHOLE_UNSPEC
:
321 if ((re
->vrf_id
!= nexthop
->vrf_id
)
322 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
324 vrf_lookup_by_id(nexthop
->vrf_id
);
327 vty_out(vty
, "(vrf %s)", vrf
->name
);
329 vty_out(vty
, "(vrf UNKNOWN)");
332 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
333 vty_out(vty
, " (duplicate nexthop removed)");
335 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
336 vty_out(vty
, " inactive");
338 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
339 vty_out(vty
, " onlink");
341 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
342 vty_out(vty
, " (recursive)");
344 switch (nexthop
->type
) {
345 case NEXTHOP_TYPE_IPV4
:
346 case NEXTHOP_TYPE_IPV4_IFINDEX
:
347 if (nexthop
->src
.ipv4
.s_addr
) {
348 if (inet_ntop(AF_INET
,
350 addrstr
, sizeof addrstr
))
351 vty_out(vty
, ", src %s",
355 case NEXTHOP_TYPE_IPV6
:
356 case NEXTHOP_TYPE_IPV6_IFINDEX
:
357 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
359 if (inet_ntop(AF_INET6
,
361 addrstr
, sizeof addrstr
))
362 vty_out(vty
, ", src %s",
371 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
373 /* Label information */
374 if (nexthop
->nh_label
375 && nexthop
->nh_label
->num_labels
) {
376 vty_out(vty
, ", label %s",
378 nexthop
->nh_label
->num_labels
,
379 nexthop
->nh_label
->label
, buf
,
384 vty_out(vty
, ", weight %u", nexthop
->weight
);
392 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
393 struct route_entry
*re
, json_object
*json
,
396 struct nexthop
*nexthop
;
398 char buf
[SRCDEST2STR_BUFFER
];
399 json_object
*json_nexthops
= NULL
;
400 json_object
*json_nexthop
= NULL
;
401 json_object
*json_route
= NULL
;
402 json_object
*json_labels
= NULL
;
405 struct vrf
*vrf
= NULL
;
406 rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
407 struct nexthop_group
*nhg
;
409 uptime
= monotime(NULL
);
410 uptime
-= re
->uptime
;
411 tm
= gmtime(&uptime
);
413 /* If showing fib information, use the fib view of the
417 nhg
= rib_active_nhg(re
);
422 json_route
= json_object_new_object();
423 json_nexthops
= json_object_new_array();
425 json_object_string_add(json_route
, "prefix",
426 srcdest_rnode2str(rn
, buf
, sizeof buf
));
427 json_object_string_add(json_route
, "protocol",
428 zebra_route_string(re
->type
));
431 json_object_int_add(json_route
, "instance",
435 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
436 vrf
= vrf_lookup_by_id(re
->vrf_id
);
437 json_object_string_add(json_route
, "vrfName",
441 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
442 json_object_boolean_true_add(json_route
, "selected");
444 if (dest
->selected_fib
== re
)
445 json_object_boolean_true_add(json_route
,
448 json_object_int_add(json_route
, "distance",
450 json_object_int_add(json_route
, "metric", re
->metric
);
452 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
453 json_object_boolean_true_add(json_route
, "installed");
455 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
456 json_object_boolean_true_add(json_route
, "failed");
458 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
459 json_object_boolean_true_add(json_route
, "queued");
462 json_object_int_add(json_route
, "tag", re
->tag
);
465 json_object_int_add(json_route
, "table", re
->table
);
467 json_object_int_add(json_route
, "internalStatus",
469 json_object_int_add(json_route
, "internalFlags",
471 json_object_int_add(json_route
, "internalNextHopNum",
472 nexthop_group_nexthop_num(re
->nhe
->nhg
));
473 json_object_int_add(json_route
, "internalNextHopActiveNum",
474 nexthop_group_active_nexthop_num(
476 if (uptime
< ONE_DAY_SECOND
)
477 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
479 else if (uptime
< ONE_WEEK_SECOND
)
480 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
483 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
484 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
487 json_object_string_add(json_route
, "uptime", buf
);
489 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
490 json_nexthop
= json_object_new_object();
492 json_object_int_add(json_nexthop
, "flags",
495 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
496 json_object_boolean_true_add(json_nexthop
,
499 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
500 json_object_boolean_true_add(json_nexthop
,
503 switch (nexthop
->type
) {
504 case NEXTHOP_TYPE_IPV4
:
505 case NEXTHOP_TYPE_IPV4_IFINDEX
:
506 json_object_string_add(
508 inet_ntoa(nexthop
->gate
.ipv4
));
509 json_object_string_add(json_nexthop
, "afi",
512 if (nexthop
->ifindex
) {
513 json_object_int_add(json_nexthop
,
516 json_object_string_add(
517 json_nexthop
, "interfaceName",
523 case NEXTHOP_TYPE_IPV6
:
524 case NEXTHOP_TYPE_IPV6_IFINDEX
:
525 json_object_string_add(
527 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
529 json_object_string_add(json_nexthop
, "afi",
532 if (nexthop
->ifindex
) {
533 json_object_int_add(json_nexthop
,
536 json_object_string_add(
537 json_nexthop
, "interfaceName",
544 case NEXTHOP_TYPE_IFINDEX
:
545 json_object_boolean_true_add(
546 json_nexthop
, "directlyConnected");
547 json_object_int_add(json_nexthop
,
550 json_object_string_add(
551 json_nexthop
, "interfaceName",
552 ifindex2ifname(nexthop
->ifindex
,
555 case NEXTHOP_TYPE_BLACKHOLE
:
556 json_object_boolean_true_add(json_nexthop
,
558 switch (nexthop
->bh_type
) {
559 case BLACKHOLE_REJECT
:
560 json_object_boolean_true_add(
561 json_nexthop
, "reject");
563 case BLACKHOLE_ADMINPROHIB
:
564 json_object_boolean_true_add(
569 json_object_boolean_true_add(
570 json_nexthop
, "blackhole");
572 case BLACKHOLE_UNSPEC
:
580 if ((nexthop
->vrf_id
!= re
->vrf_id
)
581 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
582 vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
583 json_object_string_add(json_nexthop
, "vrf",
586 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
587 json_object_boolean_true_add(json_nexthop
,
590 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
591 json_object_boolean_true_add(json_nexthop
,
594 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
595 json_object_boolean_true_add(json_nexthop
,
598 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
599 json_object_boolean_true_add(json_nexthop
,
602 switch (nexthop
->type
) {
603 case NEXTHOP_TYPE_IPV4
:
604 case NEXTHOP_TYPE_IPV4_IFINDEX
:
605 if (nexthop
->src
.ipv4
.s_addr
) {
606 if (inet_ntop(AF_INET
,
607 &nexthop
->src
.ipv4
, buf
,
609 json_object_string_add(
610 json_nexthop
, "source",
614 case NEXTHOP_TYPE_IPV6
:
615 case NEXTHOP_TYPE_IPV6_IFINDEX
:
616 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
618 if (inet_ntop(AF_INET6
,
619 &nexthop
->src
.ipv6
, buf
,
621 json_object_string_add(
622 json_nexthop
, "source",
630 if (nexthop
->nh_label
631 && nexthop
->nh_label
->num_labels
) {
632 json_labels
= json_object_new_array();
634 for (int label_index
= 0;
636 < nexthop
->nh_label
->num_labels
;
638 json_object_array_add(
641 nexthop
->nh_label
->label
644 json_object_object_add(json_nexthop
, "labels",
648 json_object_array_add(json_nexthops
, json_nexthop
);
651 json_object_object_add(json_route
, "nexthops", json_nexthops
);
652 json_object_array_add(json
, json_route
);
656 /* Nexthop information. */
657 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
658 if (nexthop
== nhg
->nexthop
) {
659 /* Prefix information. */
660 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
662 len
+= vty_out(vty
, "[%d]", re
->instance
);
665 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
668 re_status_output_char(re
, nexthop
),
669 srcdest_rnode2str(rn
, buf
, sizeof buf
));
671 /* Distance and metric display. */
672 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
673 (re
->distance
|| re
->metric
)) ||
674 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
675 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
678 vty_out(vty
, " %c%*c",
679 re_status_output_char(re
, nexthop
),
680 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
683 switch (nexthop
->type
) {
684 case NEXTHOP_TYPE_IPV4
:
685 case NEXTHOP_TYPE_IPV4_IFINDEX
:
686 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
687 if (nexthop
->ifindex
)
689 ifindex2ifname(nexthop
->ifindex
,
692 case NEXTHOP_TYPE_IPV6
:
693 case NEXTHOP_TYPE_IPV6_IFINDEX
:
694 vty_out(vty
, " via %s",
695 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
697 if (nexthop
->ifindex
)
699 ifindex2ifname(nexthop
->ifindex
,
703 case NEXTHOP_TYPE_IFINDEX
:
704 vty_out(vty
, " is directly connected, %s",
705 ifindex2ifname(nexthop
->ifindex
,
708 case NEXTHOP_TYPE_BLACKHOLE
:
709 vty_out(vty
, " unreachable");
710 switch (nexthop
->bh_type
) {
711 case BLACKHOLE_REJECT
:
712 vty_out(vty
, " (ICMP unreachable)");
714 case BLACKHOLE_ADMINPROHIB
:
715 vty_out(vty
, " (ICMP admin-prohibited)");
718 vty_out(vty
, " (blackhole)");
720 case BLACKHOLE_UNSPEC
:
728 if ((nexthop
->vrf_id
!= re
->vrf_id
)
729 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
)) {
730 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
733 vty_out(vty
, "(vrf %s)", vrf
->name
);
735 vty_out(vty
, "(vrf UNKNOWN)");
738 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
739 vty_out(vty
, " inactive");
741 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
742 vty_out(vty
, " onlink");
744 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
745 vty_out(vty
, " (recursive)");
747 switch (nexthop
->type
) {
748 case NEXTHOP_TYPE_IPV4
:
749 case NEXTHOP_TYPE_IPV4_IFINDEX
:
750 if (nexthop
->src
.ipv4
.s_addr
) {
751 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
753 vty_out(vty
, ", src %s", buf
);
756 case NEXTHOP_TYPE_IPV6
:
757 case NEXTHOP_TYPE_IPV6_IFINDEX
:
758 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
759 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
761 vty_out(vty
, ", src %s", buf
);
768 /* Label information */
769 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
770 vty_out(vty
, ", label %s",
771 mpls_label2str(nexthop
->nh_label
->num_labels
,
772 nexthop
->nh_label
->label
, buf
,
776 if (uptime
< ONE_DAY_SECOND
)
777 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
778 tm
->tm_min
, tm
->tm_sec
);
779 else if (uptime
< ONE_WEEK_SECOND
)
780 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
781 tm
->tm_hour
, tm
->tm_min
);
783 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
784 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
790 static void vty_show_ip_route_detail_json(struct vty
*vty
,
791 struct route_node
*rn
, bool use_fib
)
793 json_object
*json
= NULL
;
794 json_object
*json_prefix
= NULL
;
795 struct route_entry
*re
;
799 dest
= rib_dest_from_rnode(rn
);
801 json
= json_object_new_object();
802 json_prefix
= json_object_new_array();
804 RNODE_FOREACH_RE (rn
, re
) {
806 * If re not selected for forwarding, skip re
807 * for "show ip/ipv6 fib <prefix> json"
809 if (use_fib
&& re
!= dest
->selected_fib
)
811 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
814 prefix2str(&rn
->p
, buf
, sizeof(buf
));
815 json_object_object_add(json
, buf
, json_prefix
);
816 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
817 json
, JSON_C_TO_STRING_PRETTY
));
818 json_object_free(json
);
821 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
822 struct route_table
*table
, afi_t afi
,
823 bool use_fib
, route_tag_t tag
,
824 const struct prefix
*longer_prefix_p
,
825 bool supernets_only
, int type
,
826 unsigned short ospf_instance_id
, bool use_json
,
829 struct route_node
*rn
;
830 struct route_entry
*re
;
833 json_object
*json
= NULL
;
834 json_object
*json_prefix
= NULL
;
839 json
= json_object_new_object();
841 /* Show all routes. */
842 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
843 dest
= rib_dest_from_rnode(rn
);
845 RNODE_FOREACH_RE (rn
, re
) {
846 if (use_fib
&& re
!= dest
->selected_fib
)
849 if (tag
&& re
->tag
!= tag
)
853 && !prefix_match(longer_prefix_p
, &rn
->p
))
856 /* This can only be true when the afi is IPv4 */
857 if (supernets_only
) {
858 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
860 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
863 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
866 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
870 if (type
&& re
->type
!= type
)
874 && (re
->type
!= ZEBRA_ROUTE_OSPF
875 || re
->instance
!= ospf_instance_id
))
880 json_prefix
= json_object_new_array();
885 SHOW_ROUTE_V4_HEADER
);
888 SHOW_ROUTE_V6_HEADER
);
890 if (tableid
&& tableid
!= RT_TABLE_MAIN
)
891 vty_out(vty
, "\nVRF %s table %u:\n",
892 zvrf_name(zvrf
), tableid
);
893 else if (zvrf_id(zvrf
) != VRF_DEFAULT
)
894 vty_out(vty
, "\nVRF %s:\n",
900 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
904 prefix2str(&rn
->p
, buf
, sizeof(buf
));
905 json_object_object_add(json
, buf
, json_prefix
);
911 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
912 JSON_C_TO_STRING_PRETTY
));
913 json_object_free(json
);
917 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
918 safi_t safi
, bool use_fib
, bool use_json
,
920 const struct prefix
*longer_prefix_p
,
921 bool supernets_only
, int type
,
922 unsigned short ospf_instance_id
)
924 struct route_table
*table
;
925 struct zebra_vrf
*zvrf
= NULL
;
927 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
929 vty_out(vty
, "{}\n");
931 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
935 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
937 vty_out(vty
, "{}\n");
939 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
943 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
946 vty_out(vty
, "{}\n");
950 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
951 longer_prefix_p
, supernets_only
, type
,
952 ospf_instance_id
, use_json
, 0);
957 DEFPY (show_route_table
,
958 show_route_table_cmd
,
959 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
965 "The table number to display, if available\n"
968 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
969 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
970 struct route_table
*t
;
972 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
974 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
975 0, 0, !!json
, table
);
980 DEFPY (show_route_table_vrf
,
981 show_route_table_vrf_cmd
,
982 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
988 "The table number to display, if available\n"
992 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
993 struct zebra_vrf
*zvrf
;
994 struct route_table
*t
;
995 vrf_id_t vrf_id
= VRF_DEFAULT
;
998 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
999 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1001 t
= zebra_router_find_table(zvrf
, table
, afi
, SAFI_UNICAST
);
1003 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
1004 0, 0, !!json
, table
);
1009 DEFPY (show_route_all_table_vrf
,
1010 show_route_all_table_vrf_cmd
,
1011 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] tables [json$json]",
1015 "IP routing table\n"
1016 "Display all tables\n"
1017 VRF_FULL_CMD_HELP_STR
1020 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1021 struct zebra_vrf
*zvrf
= NULL
;
1022 vrf_id_t vrf_id
= VRF_UNKNOWN
;
1023 struct zebra_router_table
*zrt
;
1026 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1027 zvrf
= zebra_vrf_lookup_by_id(vrf_id
);
1030 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
1031 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
1033 if (zvrf
&& zvrf
!= info
->zvrf
)
1035 if (zrt
->afi
!= afi
|| zrt
->safi
!= SAFI_UNICAST
)
1038 do_show_route_helper(vty
, info
->zvrf
, zrt
->table
, afi
, false, 0,
1039 false, false, 0, 0, !!json
, zrt
->tableid
);
1046 "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]",
1050 "IP nexthop tracking table\n"
1051 "IP import check tracking table\n"
1057 VRF_ALL_CMD_HELP_STR
)
1059 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1060 vrf_id_t vrf_id
= VRF_DEFAULT
;
1061 struct prefix prefix
, *p
= NULL
;
1064 if (strcmp(type
, "nht") == 0)
1065 rtype
= RNH_NEXTHOP_TYPE
;
1067 rtype
= RNH_IMPORT_CHECK_TYPE
;
1071 struct zebra_vrf
*zvrf
;
1073 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1074 if ((zvrf
= vrf
->info
) != NULL
) {
1075 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1076 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1082 VRF_GET_ID(vrf_id
, vrf_name
, false);
1084 memset(&prefix
, 0, sizeof(prefix
));
1086 p
= sockunion2hostprefix(addr
, &prefix
);
1088 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1092 DEFUN (ip_nht_default_route
,
1093 ip_nht_default_route_cmd
,
1094 "ip nht resolve-via-default",
1096 "Filter Next Hop tracking route resolution\n"
1097 "Resolve via default route\n")
1099 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1104 if (zvrf
->zebra_rnh_ip_default_route
)
1107 zvrf
->zebra_rnh_ip_default_route
= 1;
1109 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1113 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1115 struct nexthop
*nexthop
= NULL
;
1116 struct nhg_connected
*rb_node_dep
= NULL
;
1117 char buf
[SRCDEST2STR_BUFFER
];
1119 struct vrf
*nhe_vrf
= vrf_lookup_by_id(nhe
->vrf_id
);
1121 vty_out(vty
, "ID: %u\n", nhe
->id
);
1122 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1125 vty_out(vty
, " VRF: %s\n", nhe_vrf
->name
);
1127 vty_out(vty
, " VRF: UNKNOWN\n");
1129 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_UNHASHABLE
))
1130 vty_out(vty
, " Duplicate - from kernel not hashable\n");
1132 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1133 vty_out(vty
, " Valid");
1134 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1135 vty_out(vty
, ", Installed");
1139 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1141 if (!zebra_nhg_depends_is_empty(nhe
)) {
1142 vty_out(vty
, " Depends:");
1143 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1144 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1149 for (ALL_NEXTHOPS_PTR(nhe
->nhg
, nexthop
)) {
1150 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1153 /* Make recursive nexthops a bit more clear */
1156 switch (nexthop
->type
) {
1157 case NEXTHOP_TYPE_IPV4
:
1158 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1159 vty_out(vty
, " %s", inet_ntoa(nexthop
->gate
.ipv4
));
1160 if (nexthop
->ifindex
)
1161 vty_out(vty
, ", %s",
1162 ifindex2ifname(nexthop
->ifindex
,
1165 case NEXTHOP_TYPE_IPV6
:
1166 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1168 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1170 if (nexthop
->ifindex
)
1171 vty_out(vty
, ", %s",
1172 ifindex2ifname(nexthop
->ifindex
,
1176 case NEXTHOP_TYPE_IFINDEX
:
1177 vty_out(vty
, " directly connected %s",
1178 ifindex2ifname(nexthop
->ifindex
,
1181 case NEXTHOP_TYPE_BLACKHOLE
:
1182 vty_out(vty
, " unreachable");
1183 switch (nexthop
->bh_type
) {
1184 case BLACKHOLE_REJECT
:
1185 vty_out(vty
, " (ICMP unreachable)");
1187 case BLACKHOLE_ADMINPROHIB
:
1188 vty_out(vty
, " (ICMP admin-prohibited)");
1190 case BLACKHOLE_NULL
:
1191 vty_out(vty
, " (blackhole)");
1193 case BLACKHOLE_UNSPEC
:
1201 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1204 vty_out(vty
, " (vrf %s)", vrf
->name
);
1206 vty_out(vty
, " (vrf UNKNOWN)");
1208 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1209 vty_out(vty
, " inactive");
1211 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1212 vty_out(vty
, " onlink");
1214 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1215 vty_out(vty
, " (recursive)");
1217 switch (nexthop
->type
) {
1218 case NEXTHOP_TYPE_IPV4
:
1219 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1220 if (nexthop
->src
.ipv4
.s_addr
) {
1221 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1223 vty_out(vty
, ", src %s", buf
);
1226 case NEXTHOP_TYPE_IPV6
:
1227 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1228 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1229 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1231 vty_out(vty
, ", src %s", buf
);
1238 /* Label information */
1239 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1240 vty_out(vty
, ", label %s",
1241 mpls_label2str(nexthop
->nh_label
->num_labels
,
1242 nexthop
->nh_label
->label
, buf
,
1246 if (nexthop
->weight
)
1247 vty_out(vty
, ", weight %u", nexthop
->weight
);
1252 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1253 vty_out(vty
, " Dependents:");
1254 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1256 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1263 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1265 struct nhg_hash_entry
*nhe
= NULL
;
1267 nhe
= zebra_nhg_lookup_id(id
);
1270 show_nexthop_group_out(vty
, nhe
);
1272 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1278 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1279 struct zebra_vrf
*zvrf
, afi_t afi
)
1281 struct list
*list
= hash_to_list(zrouter
.nhgs
);
1282 struct nhg_hash_entry
*nhe
= NULL
;
1283 struct listnode
*node
= NULL
;
1285 for (ALL_LIST_ELEMENTS_RO(list
, node
, nhe
)) {
1287 if (afi
&& nhe
->afi
!= afi
)
1290 if (nhe
->vrf_id
!= zvrf
->vrf
->vrf_id
)
1293 show_nexthop_group_out(vty
, nhe
);
1299 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1301 struct zebra_if
*zebra_if
= NULL
;
1302 struct nhg_connected
*rb_node_dep
= NULL
;
1304 zebra_if
= ifp
->info
;
1306 if (!if_nhg_dependents_is_empty(ifp
)) {
1307 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1309 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1312 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1317 DEFPY (show_interface_nexthop_group
,
1318 show_interface_nexthop_group_cmd
,
1319 "show interface [IFNAME$if_name] nexthop-group",
1321 "Interface status and configuration\n"
1323 "Show Nexthop Groups\n")
1325 struct vrf
*vrf
= NULL
;
1326 struct interface
*ifp
= NULL
;
1329 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1331 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1333 if_nexthop_group_dump_vty(vty
, ifp
);
1337 FOR_ALL_INTERFACES (vrf
, ifp
)
1338 if_nexthop_group_dump_vty(vty
, ifp
);
1344 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1351 DEFPY (show_nexthop_group
,
1352 show_nexthop_group_cmd
,
1353 "show nexthop-group <(0-4294967295)$id|[<ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
1355 "Show Nexthop Groups\n"
1356 "Nexthop Group ID\n"
1359 VRF_FULL_CMD_HELP_STR
)
1362 struct zebra_vrf
*zvrf
= NULL
;
1366 return show_nexthop_group_id_cmd_helper(vty
, id
);
1376 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1377 struct zebra_vrf
*zvrf
;
1383 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1384 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1391 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1393 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1396 vty_out(vty
, "VRF %s specified does not exist", vrf_name
);
1400 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
);
1405 DEFUN (no_ip_nht_default_route
,
1406 no_ip_nht_default_route_cmd
,
1407 "no ip nht resolve-via-default",
1410 "Filter Next Hop tracking route resolution\n"
1411 "Resolve via default route\n")
1413 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1418 if (!zvrf
->zebra_rnh_ip_default_route
)
1421 zvrf
->zebra_rnh_ip_default_route
= 0;
1422 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1426 DEFUN (ipv6_nht_default_route
,
1427 ipv6_nht_default_route_cmd
,
1428 "ipv6 nht resolve-via-default",
1430 "Filter Next Hop tracking route resolution\n"
1431 "Resolve via default route\n")
1433 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1438 if (zvrf
->zebra_rnh_ipv6_default_route
)
1441 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1442 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1446 DEFUN (no_ipv6_nht_default_route
,
1447 no_ipv6_nht_default_route_cmd
,
1448 "no ipv6 nht resolve-via-default",
1451 "Filter Next Hop tracking route resolution\n"
1452 "Resolve via default route\n")
1455 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1460 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1463 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1464 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1472 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1475 |A.B.C.D/M$prefix longer-prefixes\
1476 |supernets-only$supernets_only\
1479 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1480 |ospf$type_str (1-65535)$ospf_instance_id\
1482 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1485 |X:X::X:X/M$prefix longer-prefixes\
1487 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1492 "IP forwarding table\n"
1493 "IP routing table\n"
1494 VRF_FULL_CMD_HELP_STR
1495 "Show only routes with tag\n"
1497 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1498 "Show route matching the specified Network/Mask pair only\n"
1499 "Show supernet entries only\n"
1500 FRR_IP_REDIST_HELP_STR_ZEBRA
1501 "Open Shortest Path First (OSPFv2)\n"
1504 "IP forwarding table\n"
1505 "IP routing table\n"
1506 VRF_FULL_CMD_HELP_STR
1507 "Show only routes with tag\n"
1510 "Show route matching the specified Network/Mask pair only\n"
1511 FRR_IP6_REDIST_HELP_STR_ZEBRA
1514 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1519 type
= proto_redistnum(afi
, type_str
);
1521 vty_out(vty
, "Unknown route type\n");
1527 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1528 struct zebra_vrf
*zvrf
;
1529 struct route_table
*table
;
1531 if ((zvrf
= vrf
->info
) == NULL
1532 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1536 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1537 !!json
, tag
, prefix_str
? prefix
: NULL
,
1538 !!supernets_only
, type
, ospf_instance_id
);
1541 vrf_id_t vrf_id
= VRF_DEFAULT
;
1544 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1545 vrf
= vrf_lookup_by_id(vrf_id
);
1546 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1547 !!json
, tag
, prefix_str
? prefix
: NULL
,
1548 !!supernets_only
, type
, ospf_instance_id
);
1554 DEFPY (show_route_detail
,
1555 show_route_detail_cmd
,
1558 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1563 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1569 [json$json] [nexthop-group$ng]",
1572 "IPv6 forwarding table\n"
1573 "IP routing table\n"
1574 VRF_FULL_CMD_HELP_STR
1575 "Network in the IP routing table to display\n"
1576 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1578 "IPv6 forwarding table\n"
1579 "IPv6 routing table\n"
1580 VRF_FULL_CMD_HELP_STR
1584 "Nexthop Group Information\n")
1586 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1587 struct route_table
*table
;
1589 struct route_node
*rn
;
1590 bool use_fib
= !!fib
;
1592 bool network_found
= false;
1593 bool show_ng
= !!ng
;
1596 prefix_str
= address_str
;
1597 if (str2prefix(prefix_str
, &p
) < 0) {
1598 vty_out(vty
, "%% Malformed address\n");
1604 struct zebra_vrf
*zvrf
;
1606 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1607 if ((zvrf
= vrf
->info
) == NULL
1608 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1611 rn
= route_node_match(table
, &p
);
1614 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1615 route_unlock_node(rn
);
1619 dest
= rib_dest_from_rnode(rn
);
1620 if (use_fib
&& !dest
->selected_fib
) {
1621 route_unlock_node(rn
);
1625 network_found
= true;
1627 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1629 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1632 route_unlock_node(rn
);
1635 if (!network_found
) {
1637 vty_out(vty
, "{}\n");
1641 "%% Network not in FIB\n");
1644 "%% Network not in RIB\n");
1649 vrf_id_t vrf_id
= VRF_DEFAULT
;
1652 VRF_GET_ID(vrf_id
, vrf_name
, false);
1654 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1658 rn
= route_node_match(table
, &p
);
1660 dest
= rib_dest_from_rnode(rn
);
1662 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1663 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1665 vty_out(vty
, "{}\n");
1669 "%% Network not in FIB\n");
1672 "%% Network not in table\n");
1675 route_unlock_node(rn
);
1680 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1682 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1684 route_unlock_node(rn
);
1690 DEFPY (show_route_summary
,
1691 show_route_summary_cmd
,
1692 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1693 summary [table (1-4294967295)$table_id] [prefix$prefix]",
1697 "IP routing table\n"
1698 VRF_FULL_CMD_HELP_STR
1699 "Summary of all routes\n"
1700 "Table to display summary for\n"
1701 "The table number\n"
1704 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1705 struct route_table
*table
;
1708 table_id
= RT_TABLE_MAIN
;
1712 struct zebra_vrf
*zvrf
;
1714 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1715 if ((zvrf
= vrf
->info
) == NULL
)
1718 table
= zebra_vrf_lookup_table_with_table_id(
1719 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, table_id
);
1725 vty_show_ip_route_summary_prefix(vty
, table
);
1727 vty_show_ip_route_summary(vty
, table
);
1730 vrf_id_t vrf_id
= VRF_DEFAULT
;
1733 VRF_GET_ID(vrf_id
, vrf_name
, false);
1735 table
= zebra_vrf_lookup_table_with_table_id(afi
, SAFI_UNICAST
,
1741 vty_show_ip_route_summary_prefix(vty
, table
);
1743 vty_show_ip_route_summary(vty
, table
);
1749 static void vty_show_ip_route_summary(struct vty
*vty
,
1750 struct route_table
*table
)
1752 struct route_node
*rn
;
1753 struct route_entry
*re
;
1754 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1755 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1756 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1757 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1761 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1762 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1763 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1764 RNODE_FOREACH_RE (rn
, re
) {
1765 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1766 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1768 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1770 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1772 rib_cnt
[re
->type
]++;
1774 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1775 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1778 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1780 fib_cnt
[re
->type
]++;
1784 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1785 "FIB", zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1787 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1788 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1789 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1790 if (i
== ZEBRA_ROUTE_BGP
) {
1791 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1792 rib_cnt
[ZEBRA_ROUTE_BGP
],
1793 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1794 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1795 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1796 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1798 vty_out(vty
, "%-20s %-20d %-20d \n",
1799 zebra_route_string(i
), rib_cnt
[i
],
1804 vty_out(vty
, "------\n");
1805 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1806 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1811 * Implementation of the ip route summary prefix command.
1813 * This command prints the primary prefixes that have been installed by various
1814 * protocols on the box.
1817 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1818 struct route_table
*table
)
1820 struct route_node
*rn
;
1821 struct route_entry
*re
;
1822 struct nexthop
*nexthop
;
1823 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1824 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1825 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1826 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1830 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1831 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1832 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1833 RNODE_FOREACH_RE (rn
, re
) {
1836 * In case of ECMP, count only once.
1839 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
1840 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1841 fib_cnt
[re
->type
]++;
1843 for (nexthop
= re
->nhe
->nhg
->nexthop
; (!cnt
&& nexthop
);
1844 nexthop
= nexthop
->next
) {
1846 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1847 rib_cnt
[re
->type
]++;
1848 if (re
->type
== ZEBRA_ROUTE_BGP
1849 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1850 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1851 if (CHECK_FLAG(re
->status
,
1852 ROUTE_ENTRY_INSTALLED
))
1853 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1858 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1859 "Prefix Routes", "FIB",
1860 zvrf_name(((rib_table_info_t
*)route_table_get_info(table
))->zvrf
));
1862 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1863 if (rib_cnt
[i
] > 0) {
1864 if (i
== ZEBRA_ROUTE_BGP
) {
1865 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1866 rib_cnt
[ZEBRA_ROUTE_BGP
]
1867 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1868 fib_cnt
[ZEBRA_ROUTE_BGP
]
1869 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1870 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1871 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1872 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1874 vty_out(vty
, "%-20s %-20d %-20d \n",
1875 zebra_route_string(i
), rib_cnt
[i
],
1880 vty_out(vty
, "------\n");
1881 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1882 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1887 * Show IPv6 mroute command.Used to dump
1888 * the Multicast routing table.
1890 DEFUN (show_ipv6_mroute
,
1891 show_ipv6_mroute_cmd
,
1892 "show ipv6 mroute [vrf NAME]",
1895 "IPv6 Multicast routing table\n"
1898 struct route_table
*table
;
1899 struct route_node
*rn
;
1900 struct route_entry
*re
;
1902 vrf_id_t vrf_id
= VRF_DEFAULT
;
1905 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
1907 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1911 /* Show all IPv6 route. */
1912 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1913 RNODE_FOREACH_RE (rn
, re
) {
1915 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1918 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1923 DEFUN (show_ipv6_mroute_vrf_all
,
1924 show_ipv6_mroute_vrf_all_cmd
,
1925 "show ipv6 mroute vrf all",
1928 "IPv6 Multicast routing table\n"
1929 VRF_ALL_CMD_HELP_STR
)
1931 struct route_table
*table
;
1932 struct route_node
*rn
;
1933 struct route_entry
*re
;
1935 struct zebra_vrf
*zvrf
;
1938 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1939 if ((zvrf
= vrf
->info
) == NULL
1940 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1943 /* Show all IPv6 route. */
1944 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1945 RNODE_FOREACH_RE (rn
, re
) {
1947 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1950 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
1956 DEFUN (allow_external_route_update
,
1957 allow_external_route_update_cmd
,
1958 "allow-external-route-update",
1959 "Allow FRR routes to be overwritten by external processes\n")
1966 DEFUN (no_allow_external_route_update
,
1967 no_allow_external_route_update_cmd
,
1968 "no allow-external-route-update",
1970 "Allow FRR routes to be overwritten by external processes\n")
1985 struct zebra_vrf
*zvrf
;
1987 if (vrf_is_backend_netns())
1988 vty_out(vty
, "netns-based vrfs\n");
1990 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1991 if (!(zvrf
= vrf
->info
))
1993 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
1996 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1997 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
1998 vty_out(vty
, "inactive");
1999 else if (zvrf_ns_name(zvrf
))
2000 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2001 zvrf_ns_name(zvrf
));
2003 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2005 if (vrf_is_user_cfged(vrf
))
2006 vty_out(vty
, " (configured)");
2013 DEFUN (default_vrf_vni_mapping
,
2014 default_vrf_vni_mapping_cmd
,
2015 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2016 "VNI corresponding to the DEFAULT VRF\n"
2018 "Prefix routes only \n")
2021 char err
[ERR_STR_SZ
];
2022 struct zebra_vrf
*zvrf
= NULL
;
2023 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2026 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2033 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2036 vty_out(vty
, "%s\n", err
);
2043 DEFUN (no_default_vrf_vni_mapping
,
2044 no_default_vrf_vni_mapping_cmd
,
2045 "no vni " CMD_VNI_RANGE
,
2047 "VNI corresponding to DEFAULT VRF\n"
2051 char err
[ERR_STR_SZ
];
2052 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2053 struct zebra_vrf
*zvrf
= NULL
;
2055 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2059 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2061 vty_out(vty
, "%s\n", err
);
2068 DEFUN (vrf_vni_mapping
,
2069 vrf_vni_mapping_cmd
,
2070 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2071 "VNI corresponding to tenant VRF\n"
2073 "prefix-routes-only\n")
2078 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2079 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2080 char err
[ERR_STR_SZ
];
2088 /* Mark as having FRR configuration */
2089 vrf_set_user_cfged(vrf
);
2090 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2093 vty_out(vty
, "%s\n", err
);
2100 DEFUN (no_vrf_vni_mapping
,
2101 no_vrf_vni_mapping_cmd
,
2102 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2104 "VNI corresponding to tenant VRF\n"
2106 "prefix-routes-only\n")
2110 char err
[ERR_STR_SZ
];
2111 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2113 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2121 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
,
2122 ERR_STR_SZ
, filter
, 0);
2124 vty_out(vty
, "%s\n", err
);
2128 /* If no other FRR config for this VRF, mark accordingly. */
2129 if (!zebra_vrf_has_config(zvrf
))
2130 vrf_reset_user_cfged(vrf
);
2136 DEFUN (show_vrf_vni
,
2138 "show vrf vni [json]",
2145 struct zebra_vrf
*zvrf
;
2146 json_object
*json
= NULL
;
2147 json_object
*json_vrfs
= NULL
;
2148 bool uj
= use_json(argc
, argv
);
2151 json
= json_object_new_object();
2152 json_vrfs
= json_object_new_array();
2156 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2157 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2159 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2164 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2168 json_object_object_add(json
, "vrfs", json_vrfs
);
2169 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2170 json
, JSON_C_TO_STRING_PRETTY
));
2171 json_object_free(json
);
2177 DEFUN (show_evpn_global
,
2178 show_evpn_global_cmd
,
2184 bool uj
= use_json(argc
, argv
);
2186 zebra_vxlan_print_evpn(vty
, uj
);
2190 DEFUN (show_evpn_vni
,
2192 "show evpn vni [json]",
2195 "VxLAN Network Identifier\n"
2198 struct zebra_vrf
*zvrf
;
2199 bool uj
= use_json(argc
, argv
);
2201 zvrf
= zebra_vrf_get_evpn();
2202 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2206 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2207 "show evpn vni detail [json]",
2210 "VxLAN Network Identifier\n"
2211 "Detailed Information On Each VNI\n"
2214 struct zebra_vrf
*zvrf
;
2215 bool uj
= use_json(argc
, argv
);
2217 zvrf
= zebra_vrf_get_evpn();
2218 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2222 DEFUN (show_evpn_vni_vni
,
2223 show_evpn_vni_vni_cmd
,
2224 "show evpn vni " CMD_VNI_RANGE
"[json]",
2227 "VxLAN Network Identifier\n"
2231 struct zebra_vrf
*zvrf
;
2233 bool uj
= use_json(argc
, argv
);
2235 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2236 zvrf
= zebra_vrf_get_evpn();
2237 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2241 DEFUN (show_evpn_rmac_vni_mac
,
2242 show_evpn_rmac_vni_mac_cmd
,
2243 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2250 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2255 bool uj
= use_json(argc
, argv
);
2257 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2258 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2259 vty_out(vty
, "%% Malformed MAC address\n");
2262 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2266 DEFUN (show_evpn_rmac_vni
,
2267 show_evpn_rmac_vni_cmd
,
2268 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2277 bool uj
= use_json(argc
, argv
);
2279 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2280 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2285 DEFUN (show_evpn_rmac_vni_all
,
2286 show_evpn_rmac_vni_all_cmd
,
2287 "show evpn rmac vni all [json]",
2295 bool uj
= use_json(argc
, argv
);
2297 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2302 DEFUN (show_evpn_nh_vni_ip
,
2303 show_evpn_nh_vni_ip_cmd
,
2304 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2311 "Host address (ipv4 or ipv6)\n"
2316 bool uj
= use_json(argc
, argv
);
2318 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2319 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2321 vty_out(vty
, "%% Malformed Neighbor address\n");
2324 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2329 DEFUN (show_evpn_nh_vni
,
2330 show_evpn_nh_vni_cmd
,
2331 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2340 bool uj
= use_json(argc
, argv
);
2342 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2343 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2348 DEFUN (show_evpn_nh_vni_all
,
2349 show_evpn_nh_vni_all_cmd
,
2350 "show evpn next-hops vni all [json]",
2358 bool uj
= use_json(argc
, argv
);
2360 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2365 DEFUN (show_evpn_mac_vni
,
2366 show_evpn_mac_vni_cmd
,
2367 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2371 "VxLAN Network Identifier\n"
2375 struct zebra_vrf
*zvrf
;
2377 bool uj
= use_json(argc
, argv
);
2379 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2380 zvrf
= zebra_vrf_get_evpn();
2381 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2385 DEFUN (show_evpn_mac_vni_all
,
2386 show_evpn_mac_vni_all_cmd
,
2387 "show evpn mac vni all [json]",
2391 "VxLAN Network Identifier\n"
2395 struct zebra_vrf
*zvrf
;
2396 bool uj
= use_json(argc
, argv
);
2398 zvrf
= zebra_vrf_get_evpn();
2399 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
2403 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
2404 "show evpn mac vni all detail [json]",
2408 "VxLAN Network Identifier\n"
2410 "Detailed Information On Each VNI MAC\n"
2413 struct zebra_vrf
*zvrf
;
2414 bool uj
= use_json(argc
, argv
);
2416 zvrf
= zebra_vrf_get_evpn();
2417 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
2421 DEFUN (show_evpn_mac_vni_all_vtep
,
2422 show_evpn_mac_vni_all_vtep_cmd
,
2423 "show evpn mac vni all vtep A.B.C.D [json]",
2427 "VxLAN Network Identifier\n"
2430 "Remote VTEP IP address\n"
2433 struct zebra_vrf
*zvrf
;
2434 struct in_addr vtep_ip
;
2435 bool uj
= use_json(argc
, argv
);
2437 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2439 vty_out(vty
, "%% Malformed VTEP IP address\n");
2442 zvrf
= zebra_vrf_get_evpn();
2443 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2449 DEFUN (show_evpn_mac_vni_mac
,
2450 show_evpn_mac_vni_mac_cmd
,
2451 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
2455 "VxLAN Network Identifier\n"
2458 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2462 struct zebra_vrf
*zvrf
;
2465 bool uj
= use_json(argc
, argv
);
2467 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2468 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2469 vty_out(vty
, "%% Malformed MAC address");
2472 zvrf
= zebra_vrf_get_evpn();
2473 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
2477 DEFUN (show_evpn_mac_vni_vtep
,
2478 show_evpn_mac_vni_vtep_cmd
,
2479 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2483 "VxLAN Network Identifier\n"
2486 "Remote VTEP IP address\n"
2489 struct zebra_vrf
*zvrf
;
2491 struct in_addr vtep_ip
;
2492 bool uj
= use_json(argc
, argv
);
2494 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2495 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2497 vty_out(vty
, "%% Malformed VTEP IP address\n");
2501 zvrf
= zebra_vrf_get_evpn();
2502 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2506 DEFPY (show_evpn_mac_vni_all_dad
,
2507 show_evpn_mac_vni_all_dad_cmd
,
2508 "show evpn mac vni all duplicate [json]",
2512 "VxLAN Network Identifier\n"
2514 "Duplicate address list\n"
2517 struct zebra_vrf
*zvrf
;
2518 bool uj
= use_json(argc
, argv
);
2520 zvrf
= zebra_vrf_get_evpn();
2521 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
2526 DEFPY (show_evpn_mac_vni_dad
,
2527 show_evpn_mac_vni_dad_cmd
,
2528 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
2532 "VxLAN Network Identifier\n"
2534 "Duplicate address list\n"
2537 struct zebra_vrf
*zvrf
;
2538 bool uj
= use_json(argc
, argv
);
2540 zvrf
= zebra_vrf_get_evpn();
2542 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
2547 DEFPY (show_evpn_neigh_vni_dad
,
2548 show_evpn_neigh_vni_dad_cmd
,
2549 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
2552 "ARP and ND cache\n"
2553 "VxLAN Network Identifier\n"
2555 "Duplicate address list\n"
2558 struct zebra_vrf
*zvrf
;
2559 bool uj
= use_json(argc
, argv
);
2561 zvrf
= zebra_vrf_get_evpn();
2562 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
2566 DEFPY (show_evpn_neigh_vni_all_dad
,
2567 show_evpn_neigh_vni_all_dad_cmd
,
2568 "show evpn arp-cache vni all duplicate [json]",
2571 "ARP and ND cache\n"
2572 "VxLAN Network Identifier\n"
2574 "Duplicate address list\n"
2577 struct zebra_vrf
*zvrf
;
2578 bool uj
= use_json(argc
, argv
);
2580 zvrf
= zebra_vrf_get_evpn();
2581 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
2586 DEFUN (show_evpn_neigh_vni
,
2587 show_evpn_neigh_vni_cmd
,
2588 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2591 "ARP and ND cache\n"
2592 "VxLAN Network Identifier\n"
2596 struct zebra_vrf
*zvrf
;
2598 bool uj
= use_json(argc
, argv
);
2600 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2601 zvrf
= zebra_vrf_get_evpn();
2602 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2606 DEFUN (show_evpn_neigh_vni_all
,
2607 show_evpn_neigh_vni_all_cmd
,
2608 "show evpn arp-cache vni all [json]",
2611 "ARP and ND cache\n"
2612 "VxLAN Network Identifier\n"
2616 struct zebra_vrf
*zvrf
;
2617 bool uj
= use_json(argc
, argv
);
2619 zvrf
= zebra_vrf_get_evpn();
2620 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
2624 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
2625 "show evpn arp-cache vni all detail [json]",
2628 "ARP and ND cache\n"
2629 "VxLAN Network Identifier\n"
2631 "Neighbor details for all vnis in detail\n" JSON_STR
)
2633 struct zebra_vrf
*zvrf
;
2634 bool uj
= use_json(argc
, argv
);
2636 zvrf
= zebra_vrf_get_evpn();
2637 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
2641 DEFUN (show_evpn_neigh_vni_neigh
,
2642 show_evpn_neigh_vni_neigh_cmd
,
2643 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2646 "ARP and ND cache\n"
2647 "VxLAN Network Identifier\n"
2650 "Neighbor address (IPv4 or IPv6 address)\n"
2653 struct zebra_vrf
*zvrf
;
2656 bool uj
= use_json(argc
, argv
);
2658 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2659 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2661 vty_out(vty
, "%% Malformed Neighbor address\n");
2664 zvrf
= zebra_vrf_get_evpn();
2665 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2669 DEFUN (show_evpn_neigh_vni_vtep
,
2670 show_evpn_neigh_vni_vtep_cmd
,
2671 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2674 "ARP and ND cache\n"
2675 "VxLAN Network Identifier\n"
2678 "Remote VTEP IP address\n"
2681 struct zebra_vrf
*zvrf
;
2683 struct in_addr vtep_ip
;
2684 bool uj
= use_json(argc
, argv
);
2686 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2687 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2689 vty_out(vty
, "%% Malformed VTEP IP address\n");
2693 zvrf
= zebra_vrf_get_evpn();
2694 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2698 /* policy routing contexts */
2699 DEFUN (show_pbr_ipset
,
2701 "show pbr ipset [WORD]",
2703 "Policy-Based Routing\n"
2704 "IPset Context information\n"
2705 "IPset Name information\n")
2709 found
= argv_find(argv
, argc
, "WORD", &idx
);
2711 zebra_pbr_show_ipset_list(vty
, NULL
);
2713 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
2717 /* policy routing contexts */
2718 DEFUN (show_pbr_iptable
,
2719 show_pbr_iptable_cmd
,
2720 "show pbr iptable [WORD]",
2722 "Policy-Based Routing\n"
2723 "IPtable Context information\n"
2724 "IPtable Name information\n")
2729 found
= argv_find(argv
, argc
, "WORD", &idx
);
2731 zebra_pbr_show_iptable(vty
, NULL
);
2733 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
2737 DEFPY (clear_evpn_dup_addr
,
2738 clear_evpn_dup_addr_cmd
,
2739 "clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE
"$vni [mac X:X:X:X:X:X | ip <A.B.C.D|X:X::X:X>]>",
2742 "Duplicate address \n"
2743 "VxLAN Network Identifier\n"
2747 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
2752 struct zebra_vrf
*zvrf
;
2753 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
2754 int ret
= CMD_SUCCESS
;
2756 zvrf
= zebra_vrf_get_evpn();
2758 if (!is_zero_mac(&mac
->eth_addr
)) {
2759 ret
= zebra_vxlan_clear_dup_detect_vni_mac(vty
, zvrf
,
2763 if (sockunion_family(ip
) == AF_INET
) {
2764 host_ip
.ipa_type
= IPADDR_V4
;
2765 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
2767 host_ip
.ipa_type
= IPADDR_V6
;
2768 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
2769 sizeof(struct in6_addr
));
2771 ret
= zebra_vxlan_clear_dup_detect_vni_ip(vty
, zvrf
,
2775 ret
= zebra_vxlan_clear_dup_detect_vni(vty
, zvrf
, vni
);
2778 ret
= zebra_vxlan_clear_dup_detect_vni_all(vty
, zvrf
);
2784 /* Static ip route configuration write function. */
2785 static int zebra_ip_config(struct vty
*vty
)
2789 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
2794 DEFUN (ip_zebra_import_table_distance
,
2795 ip_zebra_import_table_distance_cmd
,
2796 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2798 "import routes from non-main kernel table\n"
2799 "kernel routing table id\n"
2800 "Distance for imported routes\n"
2801 "Default distance value\n"
2802 "route-map for filtering\n"
2805 uint32_t table_id
= 0;
2807 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2808 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2810 strmatch(argv
[argc
- 2]->text
, "route-map")
2811 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2815 if (argc
== 7 || (argc
== 5 && !rmap
))
2816 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2818 if (!is_zebra_valid_kernel_table(table_id
)) {
2820 "Invalid routing table ID, %d. Must be in range 1-252\n",
2823 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2827 if (is_zebra_main_routing_table(table_id
)) {
2829 "Invalid routing table ID, %d. Must be non-default table\n",
2832 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2836 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
2839 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2844 DEFUN_HIDDEN (zebra_packet_process
,
2845 zebra_packet_process_cmd
,
2846 "zebra zapi-packets (1-10000)",
2849 "Number of packets to process before relinquishing thread\n")
2851 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2853 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
2854 memory_order_relaxed
);
2859 DEFUN_HIDDEN (no_zebra_packet_process
,
2860 no_zebra_packet_process_cmd
,
2861 "no zebra zapi-packets [(1-10000)]",
2865 "Number of packets to process before relinquishing thread\n")
2867 atomic_store_explicit(&zrouter
.packets_to_process
,
2868 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
2869 memory_order_relaxed
);
2874 DEFUN_HIDDEN (zebra_workqueue_timer
,
2875 zebra_workqueue_timer_cmd
,
2876 "zebra work-queue (0-10000)",
2879 "Time in milliseconds\n")
2881 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2882 zrouter
.ribq
->spec
.hold
= timer
;
2887 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2888 no_zebra_workqueue_timer_cmd
,
2889 "no zebra work-queue [(0-10000)]",
2893 "Time in milliseconds\n")
2895 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2900 DEFUN (no_ip_zebra_import_table
,
2901 no_ip_zebra_import_table_cmd
,
2902 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2905 "import routes from non-main kernel table\n"
2906 "kernel routing table id\n"
2907 "Distance for imported routes\n"
2908 "Default distance value\n"
2909 "route-map for filtering\n"
2912 uint32_t table_id
= 0;
2913 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2915 if (!is_zebra_valid_kernel_table(table_id
)) {
2917 "Invalid routing table ID. Must be in range 1-252\n");
2921 if (is_zebra_main_routing_table(table_id
)) {
2923 "Invalid routing table ID, %d. Must be non-default table\n",
2928 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
2931 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
2934 static int config_write_protocol(struct vty
*vty
)
2937 vty_out(vty
, "allow-external-route-update\n");
2939 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2940 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
2942 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2943 vty_out(vty
, "zebra zapi-packets %u\n",
2944 zrouter
.packets_to_process
);
2946 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2948 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2949 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2950 ipv4_multicast_mode
== MCAST_URIB_ONLY
2952 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2954 : ipv4_multicast_mode
2955 == MCAST_MIX_MRIB_FIRST
2957 : ipv4_multicast_mode
2958 == MCAST_MIX_DISTANCE
2962 /* Include dataplane info */
2963 dplane_config_write_helper(vty
);
2977 " Route Route Neighbor LSP LSP\n");
2979 "VRF Installs Removals Updates Installs Removals\n");
2981 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2982 struct zebra_vrf
*zvrf
= vrf
->info
;
2984 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2985 " %10" PRIu64
" %10" PRIu64
"\n",
2986 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2987 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2988 zvrf
->lsp_removals
);
2994 DEFUN (ip_forwarding
,
2998 "Turn on IP forwarding\n")
3004 ret
= ipforward_on();
3007 vty_out(vty
, "Can't turn on IP forwarding\n");
3008 return CMD_WARNING_CONFIG_FAILED
;
3014 DEFUN (no_ip_forwarding
,
3015 no_ip_forwarding_cmd
,
3019 "Turn off IP forwarding\n")
3025 ret
= ipforward_off();
3028 vty_out(vty
, "Can't turn off IP forwarding\n");
3029 return CMD_WARNING_CONFIG_FAILED
;
3035 /* Only display ip forwarding is enabled or not. */
3036 DEFUN (show_ip_forwarding
,
3037 show_ip_forwarding_cmd
,
3038 "show ip forwarding",
3041 "IP forwarding status\n")
3048 vty_out(vty
, "IP forwarding is off\n");
3050 vty_out(vty
, "IP forwarding is on\n");
3054 /* Only display ipv6 forwarding is enabled or not. */
3055 DEFUN (show_ipv6_forwarding
,
3056 show_ipv6_forwarding_cmd
,
3057 "show ipv6 forwarding",
3059 "IPv6 information\n"
3060 "Forwarding status\n")
3064 ret
= ipforward_ipv6();
3068 vty_out(vty
, "ipv6 forwarding is unknown\n");
3071 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3074 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3077 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3083 DEFUN (ipv6_forwarding
,
3084 ipv6_forwarding_cmd
,
3087 "Turn on IPv6 forwarding\n")
3091 ret
= ipforward_ipv6();
3093 ret
= ipforward_ipv6_on();
3096 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3097 return CMD_WARNING_CONFIG_FAILED
;
3103 DEFUN (no_ipv6_forwarding
,
3104 no_ipv6_forwarding_cmd
,
3105 "no ipv6 forwarding",
3108 "Turn off IPv6 forwarding\n")
3112 ret
= ipforward_ipv6();
3114 ret
= ipforward_ipv6_off();
3117 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3118 return CMD_WARNING_CONFIG_FAILED
;
3124 /* Display dataplane info */
3125 DEFUN (show_dataplane
,
3127 "show zebra dplane [detailed]",
3130 "Zebra dataplane information\n"
3131 "Detailed output\n")
3134 bool detailed
= false;
3136 if (argv_find(argv
, argc
, "detailed", &idx
))
3139 return dplane_show_helper(vty
, detailed
);
3142 /* Display dataplane providers info */
3143 DEFUN (show_dataplane_providers
,
3144 show_dataplane_providers_cmd
,
3145 "show zebra dplane providers [detailed]",
3148 "Zebra dataplane information\n"
3149 "Zebra dataplane provider information\n"
3150 "Detailed output\n")
3153 bool detailed
= false;
3155 if (argv_find(argv
, argc
, "detailed", &idx
))
3158 return dplane_show_provs_helper(vty
, detailed
);
3161 /* Configure dataplane incoming queue limit */
3162 DEFUN (zebra_dplane_queue_limit
,
3163 zebra_dplane_queue_limit_cmd
,
3164 "zebra dplane limit (0-10000)",
3167 "Limit incoming queued updates\n"
3168 "Number of queued updates\n")
3172 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3174 dplane_set_in_queue_limit(limit
, true);
3179 /* Reset dataplane queue limit to default value */
3180 DEFUN (no_zebra_dplane_queue_limit
,
3181 no_zebra_dplane_queue_limit_cmd
,
3182 "no zebra dplane limit [(0-10000)]",
3186 "Limit incoming queued updates\n"
3187 "Number of queued updates\n")
3189 dplane_set_in_queue_limit(0, false);
3194 DEFUN (zebra_show_routing_tables_summary
,
3195 zebra_show_routing_tables_summary_cmd
,
3196 "show zebra router table summary",
3199 "The Zebra Router Information\n"
3200 "Table Information about this Zebra Router\n"
3201 "Summary Information\n")
3203 zebra_router_show_table_summary(vty
);
3208 /* Table configuration write function. */
3209 static int config_write_table(struct vty
*vty
)
3214 /* IPForwarding configuration write function. */
3215 static int config_write_forwarding(struct vty
*vty
)
3217 /* FIXME: Find better place for that. */
3218 router_id_write(vty
);
3221 vty_out(vty
, "no ip forwarding\n");
3222 if (!ipforward_ipv6())
3223 vty_out(vty
, "no ipv6 forwarding\n");
3224 vty_out(vty
, "!\n");
3228 DEFUN_HIDDEN (show_frr
,
3234 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3235 vty_out(vty
, ".............................7777:..............................................\n");
3236 vty_out(vty
, ".............................777777,............................................\n");
3237 vty_out(vty
, "... .........................77777777,..........................................\n");
3238 vty_out(vty
, "............................=7777777777:........................................\n");
3239 vty_out(vty
, "........................:7777777777777777,......................................\n");
3240 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3241 vty_out(vty
, "...................I7777777777+.................................................\n");
3242 vty_out(vty
, "................,777777777?............ .......................................\n");
3243 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3244 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3245 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3246 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3247 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3248 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3249 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3250 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3251 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3252 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3253 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3254 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3255 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3256 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3257 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3258 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3259 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3260 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3261 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3262 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3263 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3264 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3265 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3266 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3267 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3268 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3269 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3270 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3271 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3272 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3273 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3274 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3275 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3276 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3277 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3278 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3279 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3280 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3281 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3282 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3283 vty_out(vty
, "................................~77777777...............=777777.................\n");
3284 vty_out(vty
, ".....................................:=?I................~777777................\n");
3285 vty_out(vty
, "..........................................................:777777,..............\n");
3286 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3291 /* IP node for static routes. */
3292 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3293 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3294 /* table node for routing tables. */
3295 static struct cmd_node table_node
= {TABLE_NODE
,
3296 "", /* This node has no interface. */
3298 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3299 "", /* This node has no interface. */
3303 void zebra_vty_init(void)
3305 /* Install configuration write function. */
3306 install_node(&table_node
, config_write_table
);
3307 install_node(&forwarding_node
, config_write_forwarding
);
3309 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3310 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3311 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3312 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3314 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3315 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3316 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3319 zebra_route_map_init();
3321 install_node(&ip_node
, zebra_ip_config
);
3322 install_node(&protocol_node
, config_write_protocol
);
3324 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3325 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3327 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3328 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3330 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3331 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3332 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3333 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3334 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3335 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3337 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
3338 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
3340 install_element(VIEW_NODE
, &show_vrf_cmd
);
3341 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3342 install_element(VIEW_NODE
, &show_route_cmd
);
3343 install_element(VIEW_NODE
, &show_route_table_cmd
);
3344 if (vrf_is_backend_netns())
3345 install_element(VIEW_NODE
, &show_route_table_vrf_cmd
);
3346 install_element(VIEW_NODE
, &show_route_all_table_vrf_cmd
);
3347 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3348 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3349 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3351 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3352 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3354 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3355 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3356 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3357 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3358 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
3359 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
3360 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
3361 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
3362 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3364 /* Commands for VRF */
3365 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3367 install_element(VIEW_NODE
, &show_frr_cmd
);
3368 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3369 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3370 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
3371 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3372 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3373 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3374 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3375 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3376 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3377 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3378 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3379 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3380 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
3381 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3382 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3383 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3384 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
3385 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
3386 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3387 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3388 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
3389 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3390 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3391 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
3392 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
3393 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
3395 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
3396 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
3398 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3399 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3400 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3401 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
3403 install_element(VIEW_NODE
, &show_dataplane_cmd
);
3404 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
3405 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
3406 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
3408 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);