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
34 #include "srcdest_table.h"
37 #include "zebra/zebra_router.h"
38 #include "zebra/zserv.h"
39 #include "zebra/zebra_vrf.h"
40 #include "zebra/zebra_mpls.h"
41 #include "zebra/zebra_rnh.h"
42 #include "zebra/redistribute.h"
43 #include "zebra/zebra_routemap.h"
45 #include "zebra/zebra_vxlan.h"
46 #include "zebra/zebra_evpn_mh.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/zebra_evpn_mh.h"
57 #include "zebra/interface.h"
58 #include "northbound_cli.h"
59 #include "zebra/zebra_nb.h"
60 #include "zebra/kernel_netlink.h"
62 extern int allow_delete
;
64 /* context to manage dumps in multiple tables or vrfs */
65 struct route_show_ctx
{
66 bool multi
; /* dump multiple tables or vrf */
67 bool header_done
; /* common header already displayed */
70 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
71 safi_t safi
, bool use_fib
, bool use_json
,
73 const struct prefix
*longer_prefix_p
,
74 bool supernets_only
, int type
,
75 unsigned short ospf_instance_id
, uint32_t tableid
,
76 struct route_show_ctx
*ctx
);
77 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
78 int mcast
, bool use_fib
, bool show_ng
);
79 static void vty_show_ip_route_summary(struct vty
*vty
,
80 struct route_table
*table
, bool use_json
);
81 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
82 struct route_table
*table
,
84 /* Helper api to format a nexthop in the 'detailed' output path. */
85 static void show_nexthop_detail_helper(struct vty
*vty
,
86 const struct route_entry
*re
,
87 const struct nexthop
*nexthop
,
91 DEFUN (ip_multicast_mode
,
92 ip_multicast_mode_cmd
,
93 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
96 "RPF lookup behavior\n"
97 "Lookup in unicast RIB only\n"
98 "Lookup in multicast RIB only\n"
99 "Try multicast RIB first, fall back to unicast RIB\n"
100 "Lookup both, use entry with lower distance\n"
101 "Lookup both, use entry with longer prefix\n")
103 char *mode
= argv
[3]->text
;
105 if (strmatch(mode
, "urib-only"))
106 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
107 else if (strmatch(mode
, "mrib-only"))
108 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
109 else if (strmatch(mode
, "mrib-then-urib"))
110 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
111 else if (strmatch(mode
, "lower-distance"))
112 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
113 else if (strmatch(mode
, "longer-prefix"))
114 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
116 vty_out(vty
, "Invalid mode specified\n");
117 return CMD_WARNING_CONFIG_FAILED
;
123 DEFUN (no_ip_multicast_mode
,
124 no_ip_multicast_mode_cmd
,
125 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
128 "Multicast options\n"
129 "RPF lookup behavior\n"
130 "Lookup in unicast RIB only\n"
131 "Lookup in multicast RIB only\n"
132 "Try multicast RIB first, fall back to unicast RIB\n"
133 "Lookup both, use entry with lower distance\n"
134 "Lookup both, use entry with longer prefix\n")
136 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
143 "show ip rpf [json]",
146 "Display RPF information for multicast source\n"
149 bool uj
= use_json(argc
, argv
);
150 struct route_show_ctx ctx
= {
154 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
155 false, uj
, 0, NULL
, false, 0, 0, 0, &ctx
);
158 DEFUN (show_ip_rpf_addr
,
159 show_ip_rpf_addr_cmd
,
160 "show ip rpf A.B.C.D",
163 "Display RPF information for multicast source\n"
164 "IP multicast source address (e.g. 10.0.0.0)\n")
168 struct route_node
*rn
;
169 struct route_entry
*re
;
172 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
174 vty_out(vty
, "%% Malformed address\n");
178 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
181 vty_show_ip_route_detail(vty
, rn
, 1, false, false);
183 vty_out(vty
, "%% No match for RPF lookup\n");
188 static char re_status_output_char(const struct route_entry
*re
,
189 const struct nexthop
*nhop
,
192 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
196 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
197 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
)) {
198 /* More-specific test for 'fib' output */
200 star_p
= !!CHECK_FLAG(nhop
->flags
,
206 if (zrouter
.asic_offloaded
&&
207 CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
210 if (zrouter
.asic_offloaded
211 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
))
214 if (zrouter
.asic_offloaded
215 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
224 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
225 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
231 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
238 * Show backup nexthop info, in the 'detailed' output path
240 static void show_nh_backup_helper(struct vty
*vty
,
241 const struct route_entry
*re
,
242 const struct nexthop
*nexthop
)
244 const struct nexthop
*start
, *backup
, *temp
;
247 /* Double-check that there _is_ a backup */
248 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
) ||
249 re
->nhe
->backup_info
== NULL
|| re
->nhe
->backup_info
->nhe
== NULL
||
250 re
->nhe
->backup_info
->nhe
->nhg
.nexthop
== NULL
)
253 /* Locate the backup nexthop(s) */
254 start
= re
->nhe
->backup_info
->nhe
->nhg
.nexthop
;
255 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
256 /* Format the backup(s) (indented) */
258 for (idx
= 0; idx
< nexthop
->backup_idx
[i
]; idx
++) {
259 backup
= backup
->next
;
264 /* It's possible for backups to be recursive too,
265 * so walk the recursive resolution list if present.
270 show_nexthop_detail_helper(vty
, re
, backup
,
274 if (backup
->resolved
&& temp
== backup
)
275 backup
= backup
->resolved
;
277 backup
= nexthop_next(backup
);
279 if (backup
== temp
->next
)
287 * Helper api to format output for a nexthop, used in the 'detailed'
290 static void show_nexthop_detail_helper(struct vty
*vty
,
291 const struct route_entry
*re
,
292 const struct nexthop
*nexthop
,
296 char buf
[MPLS_LABEL_STRLEN
];
301 nexthop
->rparent
? " " : "");
303 vty_out(vty
, " %c%s",
304 re_status_output_char(re
, nexthop
, false),
305 nexthop
->rparent
? " " : "");
307 switch (nexthop
->type
) {
308 case NEXTHOP_TYPE_IPV4
:
309 case NEXTHOP_TYPE_IPV4_IFINDEX
:
310 vty_out(vty
, " %pI4",
311 &nexthop
->gate
.ipv4
);
312 if (nexthop
->ifindex
)
313 vty_out(vty
, ", via %s",
318 case NEXTHOP_TYPE_IPV6
:
319 case NEXTHOP_TYPE_IPV6_IFINDEX
:
321 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
323 if (nexthop
->ifindex
)
324 vty_out(vty
, ", via %s",
330 case NEXTHOP_TYPE_IFINDEX
:
331 vty_out(vty
, " directly connected, %s",
332 ifindex2ifname(nexthop
->ifindex
,
335 case NEXTHOP_TYPE_BLACKHOLE
:
336 vty_out(vty
, " unreachable");
337 switch (nexthop
->bh_type
) {
338 case BLACKHOLE_REJECT
:
339 vty_out(vty
, " (ICMP unreachable)");
341 case BLACKHOLE_ADMINPROHIB
:
343 " (ICMP admin-prohibited)");
346 vty_out(vty
, " (blackhole)");
348 case BLACKHOLE_UNSPEC
:
356 if ((re
->vrf_id
!= nexthop
->vrf_id
)
357 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
))
358 vty_out(vty
, "(vrf %s)", vrf_id_to_name(nexthop
->vrf_id
));
360 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
361 vty_out(vty
, " (duplicate nexthop removed)");
363 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
364 vty_out(vty
, " inactive");
366 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
367 vty_out(vty
, " onlink");
369 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
370 vty_out(vty
, " (recursive)");
372 /* Source specified? */
373 switch (nexthop
->type
) {
374 case NEXTHOP_TYPE_IPV4
:
375 case NEXTHOP_TYPE_IPV4_IFINDEX
:
376 if (nexthop
->src
.ipv4
.s_addr
) {
377 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
,
378 addrstr
, sizeof(addrstr
)))
379 vty_out(vty
, ", src %s",
384 case NEXTHOP_TYPE_IPV6
:
385 case NEXTHOP_TYPE_IPV6_IFINDEX
:
386 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
388 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
,
389 addrstr
, sizeof(addrstr
)))
390 vty_out(vty
, ", src %s",
400 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
402 /* Label information */
403 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
404 vty_out(vty
, ", label %s",
405 mpls_label2str(nexthop
->nh_label
->num_labels
,
406 nexthop
->nh_label
->label
, buf
,
407 sizeof(buf
), 1 /*pretty*/));
411 vty_out(vty
, ", weight %u", nexthop
->weight
);
413 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
414 vty_out(vty
, ", backup %d", nexthop
->backup_idx
[0]);
416 for (i
= 1; i
< nexthop
->backup_num
; i
++)
417 vty_out(vty
, ",%d", nexthop
->backup_idx
[i
]);
421 static void zebra_show_ip_route_opaque(struct vty
*vty
, struct route_entry
*re
,
422 struct json_object
*json
)
428 case ZEBRA_ROUTE_SHARP
:
430 json_object_string_add(json
, "opaque",
431 (char *)re
->opaque
->data
);
433 vty_out(vty
, " Opaque Data: %s",
434 (char *)re
->opaque
->data
);
436 case ZEBRA_ROUTE_BGP
:
438 json_object_string_add(json
, "asPath",
439 (char *)re
->opaque
->data
);
441 vty_out(vty
, " AS-Path: %s",
442 (char *)re
->opaque
->data
);
448 /* New RIB. Detailed information for IPv4 route. */
449 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
450 int mcast
, bool use_fib
, bool show_ng
)
452 struct route_entry
*re
;
453 struct nexthop
*nexthop
;
454 char buf
[SRCDEST2STR_BUFFER
];
455 struct zebra_vrf
*zvrf
;
458 dest
= rib_dest_from_rnode(rn
);
460 RNODE_FOREACH_RE (rn
, re
) {
462 * If re not selected for forwarding, skip re
463 * for "show ip/ipv6 fib <prefix>"
465 if (use_fib
&& re
!= dest
->selected_fib
)
468 const char *mcast_info
= "";
470 struct rib_table_info
*info
=
471 srcdest_rnode_table_info(rn
);
472 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
473 ? " using Multicast RIB"
474 : " using Unicast RIB";
477 vty_out(vty
, "Routing entry for %s%s\n",
478 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
479 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
481 vty_out(vty
, "[%d]", re
->instance
);
483 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
486 vty_out(vty
, ", tag %u", re
->tag
);
487 #if defined(SUPPORT_REALMS)
488 if (re
->tag
> 0 && re
->tag
<= 255)
489 vty_out(vty
, "(realm)");
493 vty_out(vty
, ", mtu %u", re
->mtu
);
494 if (re
->vrf_id
!= VRF_DEFAULT
) {
495 zvrf
= vrf_info_lookup(re
->vrf_id
);
496 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
498 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
499 vty_out(vty
, ", best");
504 uptime
= monotime(NULL
);
505 uptime
-= re
->uptime
;
507 frrtime_to_interval(uptime
, buf
, sizeof(buf
));
509 vty_out(vty
, " Last update %s ago\n", buf
);
512 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
514 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
)) {
515 /* Use helper to format each nexthop */
516 show_nexthop_detail_helper(vty
, re
, nexthop
,
517 false /*not backup*/);
520 /* Include backup(s), if present */
521 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
))
522 show_nh_backup_helper(vty
, re
, nexthop
);
524 zebra_show_ip_route_opaque(vty
, re
, NULL
);
531 * Helper for nexthop output, used in the 'show ip route' path
533 static void show_route_nexthop_helper(struct vty
*vty
,
534 const struct route_entry
*re
,
535 const struct nexthop
*nexthop
)
537 char buf
[MPLS_LABEL_STRLEN
];
540 switch (nexthop
->type
) {
541 case NEXTHOP_TYPE_IPV4
:
542 case NEXTHOP_TYPE_IPV4_IFINDEX
:
543 vty_out(vty
, " via %pI4", &nexthop
->gate
.ipv4
);
544 if (nexthop
->ifindex
)
546 ifindex2ifname(nexthop
->ifindex
,
549 case NEXTHOP_TYPE_IPV6
:
550 case NEXTHOP_TYPE_IPV6_IFINDEX
:
551 vty_out(vty
, " via %s",
552 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
554 if (nexthop
->ifindex
)
556 ifindex2ifname(nexthop
->ifindex
,
560 case NEXTHOP_TYPE_IFINDEX
:
561 vty_out(vty
, " is directly connected, %s",
562 ifindex2ifname(nexthop
->ifindex
,
565 case NEXTHOP_TYPE_BLACKHOLE
:
566 vty_out(vty
, " unreachable");
567 switch (nexthop
->bh_type
) {
568 case BLACKHOLE_REJECT
:
569 vty_out(vty
, " (ICMP unreachable)");
571 case BLACKHOLE_ADMINPROHIB
:
572 vty_out(vty
, " (ICMP admin-prohibited)");
575 vty_out(vty
, " (blackhole)");
577 case BLACKHOLE_UNSPEC
:
585 if ((re
== NULL
|| (nexthop
->vrf_id
!= re
->vrf_id
))
586 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
))
587 vty_out(vty
, " (vrf %s)", vrf_id_to_name(nexthop
->vrf_id
));
589 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
590 vty_out(vty
, " inactive");
592 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
593 vty_out(vty
, " onlink");
595 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
596 vty_out(vty
, " (recursive)");
598 switch (nexthop
->type
) {
599 case NEXTHOP_TYPE_IPV4
:
600 case NEXTHOP_TYPE_IPV4_IFINDEX
:
601 if (nexthop
->src
.ipv4
.s_addr
) {
602 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
604 vty_out(vty
, ", src %s", buf
);
605 /* SR-TE information */
606 if (nexthop
->srte_color
)
607 vty_out(vty
, ", SR-TE color %u",
608 nexthop
->srte_color
);
611 case NEXTHOP_TYPE_IPV6
:
612 case NEXTHOP_TYPE_IPV6_IFINDEX
:
613 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
614 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
616 vty_out(vty
, ", src %s", buf
);
623 /* Label information */
624 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
625 vty_out(vty
, ", label %s",
626 mpls_label2str(nexthop
->nh_label
->num_labels
,
627 nexthop
->nh_label
->label
, buf
,
632 vty_out(vty
, ", weight %u", nexthop
->weight
);
634 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
635 vty_out(vty
, ", backup %d", nexthop
->backup_idx
[0]);
637 for (i
= 1; i
< nexthop
->backup_num
; i
++)
638 vty_out(vty
, ",%d", nexthop
->backup_idx
[i
]);
643 * Render a nexthop into a json object; the caller allocates and owns
644 * the json object memory.
646 static void show_nexthop_json_helper(json_object
*json_nexthop
,
647 const struct nexthop
*nexthop
,
648 const struct route_entry
*re
)
650 char buf
[SRCDEST2STR_BUFFER
];
651 json_object
*json_labels
= NULL
;
652 json_object
*json_backups
= NULL
;
655 json_object_int_add(json_nexthop
, "flags",
658 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
659 json_object_boolean_true_add(json_nexthop
,
662 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
663 json_object_boolean_true_add(json_nexthop
,
666 switch (nexthop
->type
) {
667 case NEXTHOP_TYPE_IPV4
:
668 case NEXTHOP_TYPE_IPV4_IFINDEX
:
669 json_object_string_add(
671 inet_ntop(AF_INET
, &nexthop
->gate
.ipv4
,
673 json_object_string_add(json_nexthop
, "afi",
676 if (nexthop
->ifindex
) {
677 json_object_int_add(json_nexthop
,
680 json_object_string_add(
681 json_nexthop
, "interfaceName",
687 case NEXTHOP_TYPE_IPV6
:
688 case NEXTHOP_TYPE_IPV6_IFINDEX
:
689 json_object_string_add(
691 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
693 json_object_string_add(json_nexthop
, "afi",
696 if (nexthop
->ifindex
) {
697 json_object_int_add(json_nexthop
,
700 json_object_string_add(
701 json_nexthop
, "interfaceName",
708 case NEXTHOP_TYPE_IFINDEX
:
709 json_object_boolean_true_add(
710 json_nexthop
, "directlyConnected");
711 json_object_int_add(json_nexthop
,
714 json_object_string_add(
715 json_nexthop
, "interfaceName",
716 ifindex2ifname(nexthop
->ifindex
,
719 case NEXTHOP_TYPE_BLACKHOLE
:
720 json_object_boolean_true_add(json_nexthop
,
722 switch (nexthop
->bh_type
) {
723 case BLACKHOLE_REJECT
:
724 json_object_boolean_true_add(
725 json_nexthop
, "reject");
727 case BLACKHOLE_ADMINPROHIB
:
728 json_object_boolean_true_add(
733 json_object_boolean_true_add(
734 json_nexthop
, "blackhole");
736 case BLACKHOLE_UNSPEC
:
744 if ((nexthop
->vrf_id
!= re
->vrf_id
)
745 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
))
746 json_object_string_add(json_nexthop
, "vrf",
747 vrf_id_to_name(nexthop
->vrf_id
));
749 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
750 json_object_boolean_true_add(json_nexthop
,
753 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
754 json_object_boolean_true_add(json_nexthop
,
757 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
758 json_object_boolean_true_add(json_nexthop
,
761 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
762 json_object_boolean_true_add(json_nexthop
,
765 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
766 json_backups
= json_object_new_array();
767 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
768 json_object_array_add(
770 json_object_new_int(nexthop
->backup_idx
[i
]));
773 json_object_object_add(json_nexthop
, "backupIndex",
777 switch (nexthop
->type
) {
778 case NEXTHOP_TYPE_IPV4
:
779 case NEXTHOP_TYPE_IPV4_IFINDEX
:
780 if (nexthop
->src
.ipv4
.s_addr
) {
781 if (inet_ntop(AF_INET
,
782 &nexthop
->src
.ipv4
, buf
,
784 json_object_string_add(
785 json_nexthop
, "source",
789 case NEXTHOP_TYPE_IPV6
:
790 case NEXTHOP_TYPE_IPV6_IFINDEX
:
791 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
793 if (inet_ntop(AF_INET6
,
794 &nexthop
->src
.ipv6
, buf
,
796 json_object_string_add(
797 json_nexthop
, "source",
805 if (nexthop
->nh_label
806 && nexthop
->nh_label
->num_labels
) {
807 json_labels
= json_object_new_array();
809 for (int label_index
= 0;
811 < nexthop
->nh_label
->num_labels
;
813 json_object_array_add(
816 nexthop
->nh_label
->label
819 json_object_object_add(json_nexthop
, "labels",
824 json_object_int_add(json_nexthop
, "weight",
827 if (nexthop
->srte_color
)
828 json_object_int_add(json_nexthop
, "srteColor",
829 nexthop
->srte_color
);
832 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
833 struct route_entry
*re
, json_object
*json
,
836 const struct nexthop
*nexthop
;
838 char buf
[SRCDEST2STR_BUFFER
];
839 json_object
*json_nexthops
= NULL
;
840 json_object
*json_nexthop
= NULL
;
841 json_object
*json_route
= NULL
;
843 const rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
844 const struct nexthop_group
*nhg
;
845 char up_str
[MONOTIME_STRLEN
];
847 bool nhg_from_backup
= false;
849 uptime
= monotime(NULL
);
850 uptime
-= re
->uptime
;
852 frrtime_to_interval(uptime
, up_str
, sizeof(up_str
));
854 /* If showing fib information, use the fib view of the
858 nhg
= rib_get_fib_nhg(re
);
860 nhg
= &(re
->nhe
->nhg
);
863 json_route
= json_object_new_object();
864 json_nexthops
= json_object_new_array();
866 json_object_string_add(json_route
, "prefix",
867 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
868 json_object_string_add(json_route
, "protocol",
869 zebra_route_string(re
->type
));
872 json_object_int_add(json_route
, "instance",
875 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
876 json_object_string_add(json_route
, "vrfName",
877 vrf_id_to_name(re
->vrf_id
));
879 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
880 json_object_boolean_true_add(json_route
, "selected");
882 if (dest
->selected_fib
== re
)
883 json_object_boolean_true_add(json_route
,
886 json_object_int_add(json_route
, "distance",
888 json_object_int_add(json_route
, "metric", re
->metric
);
890 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
891 json_object_boolean_true_add(json_route
, "installed");
893 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
894 json_object_boolean_true_add(json_route
, "failed");
896 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
897 json_object_boolean_true_add(json_route
, "queued");
899 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
))
900 json_object_boolean_true_add(json_route
, "trapped");
902 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
))
903 json_object_boolean_true_add(json_route
, "offloaded");
905 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
906 json_object_boolean_false_add(json_route
, "offloaded");
909 json_object_int_add(json_route
, "tag", re
->tag
);
912 json_object_int_add(json_route
, "table", re
->table
);
914 json_object_int_add(json_route
, "internalStatus",
916 json_object_int_add(json_route
, "internalFlags",
918 json_object_int_add(json_route
, "internalNextHopNum",
919 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)));
920 json_object_int_add(json_route
, "internalNextHopActiveNum",
921 nexthop_group_active_nexthop_num(
924 json_object_string_add(json_route
, "uptime", up_str
);
926 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
927 json_nexthop
= json_object_new_object();
928 show_nexthop_json_helper(json_nexthop
,
931 json_object_array_add(json_nexthops
,
935 json_object_object_add(json_route
, "nexthops", json_nexthops
);
937 /* If there are backup nexthops, include them */
939 nhg
= rib_get_fib_backup_nhg(re
);
941 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
943 if (nhg
&& nhg
->nexthop
) {
944 json_nexthops
= json_object_new_array();
946 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
947 json_nexthop
= json_object_new_object();
949 show_nexthop_json_helper(json_nexthop
,
951 json_object_array_add(json_nexthops
,
955 json_object_object_add(json_route
, "backupNexthops",
958 zebra_show_ip_route_opaque(NULL
, re
, json_route
);
960 json_object_array_add(json
, json_route
);
964 /* Prefix information, and first nexthop. If we're showing 'fib',
965 * and there are no installed primary nexthops, see if there are any
966 * backup nexthops and start with those.
968 if (is_fib
&& nhg
->nexthop
== NULL
) {
969 nhg
= rib_get_fib_backup_nhg(re
);
970 nhg_from_backup
= true;
973 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
975 len
+= vty_out(vty
, "[%d]", re
->instance
);
976 if (nhg_from_backup
&& nhg
->nexthop
) {
979 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
) ? '>' : ' ',
980 re_status_output_char(re
, nhg
->nexthop
, is_fib
),
981 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
985 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
) ? '>' : ' ',
986 re_status_output_char(re
, nhg
->nexthop
, is_fib
),
987 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
990 /* Distance and metric display. */
991 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
992 (re
->distance
|| re
->metric
)) ||
993 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
994 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
997 /* Nexthop information. */
998 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1001 } else if (nhg_from_backup
) {
1002 vty_out(vty
, " b%c%*c",
1003 re_status_output_char(re
, nexthop
, is_fib
),
1004 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1006 vty_out(vty
, " %c%*c",
1007 re_status_output_char(re
, nexthop
, is_fib
),
1008 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1011 show_route_nexthop_helper(vty
, re
, nexthop
);
1012 vty_out(vty
, ", %s\n", up_str
);
1015 /* If we only had backup nexthops, we're done */
1016 if (nhg_from_backup
)
1019 /* Check for backup nexthop info if present */
1021 nhg
= rib_get_fib_backup_nhg(re
);
1023 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1028 /* Print backup info */
1029 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1030 bool star_p
= false;
1033 star_p
= CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1035 /* TODO -- it'd be nice to be able to include
1036 * the entire list of backups, *and* include the
1037 * real installation state.
1039 vty_out(vty
, " b%c %*c",
1040 (star_p
? '*' : ' '),
1041 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1042 show_route_nexthop_helper(vty
, re
, nexthop
);
1048 static void vty_show_ip_route_detail_json(struct vty
*vty
,
1049 struct route_node
*rn
, bool use_fib
)
1051 json_object
*json
= NULL
;
1052 json_object
*json_prefix
= NULL
;
1053 struct route_entry
*re
;
1057 dest
= rib_dest_from_rnode(rn
);
1059 json
= json_object_new_object();
1060 json_prefix
= json_object_new_array();
1062 RNODE_FOREACH_RE (rn
, re
) {
1064 * If re not selected for forwarding, skip re
1065 * for "show ip/ipv6 fib <prefix> json"
1067 if (use_fib
&& re
!= dest
->selected_fib
)
1069 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
1072 prefix2str(&rn
->p
, buf
, sizeof(buf
));
1073 json_object_object_add(json
, buf
, json_prefix
);
1074 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1075 json
, JSON_C_TO_STRING_PRETTY
));
1076 json_object_free(json
);
1079 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1080 struct route_table
*table
, afi_t afi
,
1081 bool use_fib
, route_tag_t tag
,
1082 const struct prefix
*longer_prefix_p
,
1083 bool supernets_only
, int type
,
1084 unsigned short ospf_instance_id
, bool use_json
,
1085 uint32_t tableid
, struct route_show_ctx
*ctx
)
1087 struct route_node
*rn
;
1088 struct route_entry
*re
;
1091 json_object
*json
= NULL
;
1092 json_object
*json_prefix
= NULL
;
1097 * ctx->multi indicates if we are dumping multiple tables or vrfs.
1099 * => display the common header at most once
1100 * => add newline at each call except first
1101 * => always display the VRF and table
1103 * => display the common header if at least one entry is found
1104 * => display the VRF and table if specific
1108 json
= json_object_new_object();
1110 /* Show all routes. */
1111 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
1112 dest
= rib_dest_from_rnode(rn
);
1114 RNODE_FOREACH_RE (rn
, re
) {
1115 if (use_fib
&& re
!= dest
->selected_fib
)
1118 if (tag
&& re
->tag
!= tag
)
1122 && !prefix_match(longer_prefix_p
, &rn
->p
))
1125 /* This can only be true when the afi is IPv4 */
1126 if (supernets_only
) {
1127 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1129 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1132 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1135 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1139 if (type
&& re
->type
!= type
)
1142 if (ospf_instance_id
1143 && (re
->type
!= ZEBRA_ROUTE_OSPF
1144 || re
->instance
!= ospf_instance_id
))
1149 json_prefix
= json_object_new_array();
1151 if (!ctx
->header_done
) {
1154 SHOW_ROUTE_V4_HEADER
);
1157 SHOW_ROUTE_V6_HEADER
);
1159 if (ctx
->multi
&& ctx
->header_done
)
1161 if (ctx
->multi
|| zvrf_id(zvrf
) != VRF_DEFAULT
1164 vty_out(vty
, "VRF %s:\n",
1168 "VRF %s table %u:\n",
1172 ctx
->header_done
= true;
1176 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
1180 prefix2str(&rn
->p
, buf
, sizeof(buf
));
1181 json_object_object_add(json
, buf
, json_prefix
);
1187 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
1188 JSON_C_TO_STRING_PRETTY
));
1189 json_object_free(json
);
1193 static void do_show_ip_route_all(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1194 afi_t afi
, bool use_fib
, bool use_json
,
1196 const struct prefix
*longer_prefix_p
,
1197 bool supernets_only
, int type
,
1198 unsigned short ospf_instance_id
,
1199 struct route_show_ctx
*ctx
)
1201 struct zebra_router_table
*zrt
;
1202 struct rib_table_info
*info
;
1204 RB_FOREACH (zrt
, zebra_router_table_head
,
1206 info
= route_table_get_info(zrt
->table
);
1208 if (zvrf
!= info
->zvrf
)
1210 if (zrt
->afi
!= afi
||
1211 zrt
->safi
!= SAFI_UNICAST
)
1214 do_show_ip_route(vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
,
1215 use_fib
, use_json
, tag
, longer_prefix_p
,
1216 supernets_only
, type
, ospf_instance_id
,
1221 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
1222 safi_t safi
, bool use_fib
, bool use_json
,
1224 const struct prefix
*longer_prefix_p
,
1225 bool supernets_only
, int type
,
1226 unsigned short ospf_instance_id
, uint32_t tableid
,
1227 struct route_show_ctx
*ctx
)
1229 struct route_table
*table
;
1230 struct zebra_vrf
*zvrf
= NULL
;
1232 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
1234 vty_out(vty
, "{}\n");
1236 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
1240 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
1242 vty_out(vty
, "{}\n");
1244 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
1249 table
= zebra_router_find_table(zvrf
, tableid
, afi
, SAFI_UNICAST
);
1251 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
1254 vty_out(vty
, "{}\n");
1258 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
1259 longer_prefix_p
, supernets_only
, type
,
1260 ospf_instance_id
, use_json
, tableid
, ctx
);
1267 "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]",
1271 "IP nexthop tracking table\n"
1272 "IP import check tracking table\n"
1278 VRF_ALL_CMD_HELP_STR
)
1280 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1281 vrf_id_t vrf_id
= VRF_DEFAULT
;
1282 struct prefix prefix
, *p
= NULL
;
1283 enum rnh_type rtype
;
1285 if (strcmp(type
, "nht") == 0)
1286 rtype
= RNH_NEXTHOP_TYPE
;
1288 rtype
= RNH_IMPORT_CHECK_TYPE
;
1292 struct zebra_vrf
*zvrf
;
1294 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1295 if ((zvrf
= vrf
->info
) != NULL
) {
1296 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1297 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1303 VRF_GET_ID(vrf_id
, vrf_name
, false);
1305 memset(&prefix
, 0, sizeof(prefix
));
1307 p
= sockunion2hostprefix(addr
, &prefix
);
1312 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1316 DEFUN (ip_nht_default_route
,
1317 ip_nht_default_route_cmd
,
1318 "ip nht resolve-via-default",
1320 "Filter Next Hop tracking route resolution\n"
1321 "Resolve via default route\n")
1323 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1328 if (zvrf
->zebra_rnh_ip_default_route
)
1331 zvrf
->zebra_rnh_ip_default_route
= 1;
1333 zebra_evaluate_rnh(zvrf
, AFI_IP
, 0, RNH_NEXTHOP_TYPE
, NULL
);
1337 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1339 struct nexthop
*nexthop
= NULL
;
1340 struct nhg_connected
*rb_node_dep
= NULL
;
1341 struct nexthop_group
*backup_nhg
;
1343 vty_out(vty
, "ID: %u (%s)\n", nhe
->id
, zebra_route_string(nhe
->type
));
1344 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1345 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(nhe
->vrf_id
));
1347 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1348 vty_out(vty
, " Valid");
1349 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1350 vty_out(vty
, ", Installed");
1354 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1356 if (!zebra_nhg_depends_is_empty(nhe
)) {
1357 vty_out(vty
, " Depends:");
1358 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1359 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1364 /* Output nexthops */
1365 for (ALL_NEXTHOPS(nhe
->nhg
, nexthop
)) {
1366 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1369 /* Make recursive nexthops a bit more clear */
1372 show_route_nexthop_helper(vty
, NULL
, nexthop
);
1374 if (nhe
->backup_info
== NULL
|| nhe
->backup_info
->nhe
== NULL
) {
1375 if (CHECK_FLAG(nexthop
->flags
,
1376 NEXTHOP_FLAG_HAS_BACKUP
))
1377 vty_out(vty
, " [backup %d]",
1378 nexthop
->backup_idx
[0]);
1384 /* TODO -- print more useful backup info */
1385 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
1388 vty_out(vty
, "[backup");
1389 for (i
= 0; i
< nexthop
->backup_num
; i
++)
1390 vty_out(vty
, " %d", nexthop
->backup_idx
[i
]);
1398 /* Output backup nexthops (if any) */
1399 backup_nhg
= zebra_nhg_get_backup_nhg(nhe
);
1401 vty_out(vty
, " Backups:\n");
1403 for (ALL_NEXTHOPS_PTR(backup_nhg
, nexthop
)) {
1404 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1407 /* Make recursive nexthops a bit more clear */
1410 show_route_nexthop_helper(vty
, NULL
, nexthop
);
1415 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1416 vty_out(vty
, " Dependents:");
1417 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1419 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1426 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1428 struct nhg_hash_entry
*nhe
= NULL
;
1430 nhe
= zebra_nhg_lookup_id(id
);
1433 show_nexthop_group_out(vty
, nhe
);
1435 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1441 /* Helper function for iteration through the hash of nexthop-groups/nhe-s */
1443 struct nhe_show_context
{
1450 static int nhe_show_walker(struct hash_bucket
*bucket
, void *arg
)
1452 struct nhe_show_context
*ctx
= arg
;
1453 struct nhg_hash_entry
*nhe
;
1455 nhe
= bucket
->data
; /* We won't be offered NULL buckets */
1457 if (ctx
->afi
&& nhe
->afi
!= ctx
->afi
)
1460 if (ctx
->vrf_id
&& nhe
->vrf_id
!= ctx
->vrf_id
)
1463 if (ctx
->type
&& nhe
->type
!= ctx
->type
)
1466 show_nexthop_group_out(ctx
->vty
, nhe
);
1469 return HASHWALK_CONTINUE
;
1472 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1473 struct zebra_vrf
*zvrf
, afi_t afi
,
1476 struct nhe_show_context ctx
;
1480 ctx
.vrf_id
= zvrf
->vrf
->vrf_id
;
1483 hash_walk(zrouter
.nhgs_id
, nhe_show_walker
, &ctx
);
1486 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1488 struct zebra_if
*zebra_if
= NULL
;
1489 struct nhg_connected
*rb_node_dep
= NULL
;
1491 zebra_if
= ifp
->info
;
1493 if (!if_nhg_dependents_is_empty(ifp
)) {
1494 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1496 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1499 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1504 DEFPY (show_interface_nexthop_group
,
1505 show_interface_nexthop_group_cmd
,
1506 "show interface [IFNAME$if_name] nexthop-group",
1508 "Interface status and configuration\n"
1510 "Show Nexthop Groups\n")
1512 struct vrf
*vrf
= NULL
;
1513 struct interface
*ifp
= NULL
;
1516 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1518 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1520 if_nexthop_group_dump_vty(vty
, ifp
);
1524 FOR_ALL_INTERFACES (vrf
, ifp
)
1525 if_nexthop_group_dump_vty(vty
, ifp
);
1531 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1538 DEFPY (show_nexthop_group
,
1539 show_nexthop_group_cmd
,
1540 "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [<kernel|zebra|bgp|sharp>$type_str] [vrf <NAME$vrf_name|all$vrf_all>]>",
1542 "Show Nexthop Groups\n"
1544 "Nexthop Group ID\n"
1545 "Show Singleton Nexthop-Groups\n"
1548 "Kernel (not installed via the zebra RIB)\n"
1549 "Zebra (implicitly created by zebra)\n"
1550 "Border Gateway Protocol (BGP)\n"
1551 "Super Happy Advanced Routing Protocol (SHARP)\n"
1552 VRF_FULL_CMD_HELP_STR
)
1555 struct zebra_vrf
*zvrf
= NULL
;
1556 afi_t afi
= AFI_UNSPEC
;
1560 return show_nexthop_group_id_cmd_helper(vty
, id
);
1568 type
= proto_redistnum((afi
? afi
: AFI_IP
), type_str
);
1571 type
= ZEBRA_ROUTE_NHG
;
1575 if (!vrf_is_backend_netns() && (vrf_name
|| vrf_all
)) {
1577 "VRF subcommand does not make any sense in l3mdev based vrf's\n");
1584 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1585 struct zebra_vrf
*zvrf
;
1591 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1592 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
, type
);
1599 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1601 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1604 vty_out(vty
, "%% VRF '%s' specified does not exist\n",
1609 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
, type
);
1614 DEFPY_HIDDEN(nexthop_group_use_enable
,
1615 nexthop_group_use_enable_cmd
,
1616 "[no] zebra nexthop kernel enable",
1619 "Nexthop configuration \n"
1620 "Configure use of kernel nexthops\n"
1621 "Enable kernel nexthops\n")
1623 zebra_nhg_enable_kernel_nexthops(!no
);
1627 DEFPY_HIDDEN(proto_nexthop_group_only
, proto_nexthop_group_only_cmd
,
1628 "[no] zebra nexthop proto only",
1630 "Nexthop configuration\n"
1631 "Configure exclusive use of proto nexthops\n"
1632 "Only use proto nexthops\n")
1634 zebra_nhg_set_proto_nexthops_only(!no
);
1638 DEFPY_HIDDEN(backup_nexthop_recursive_use_enable
,
1639 backup_nexthop_recursive_use_enable_cmd
,
1640 "[no] zebra nexthop resolve-via-backup",
1643 "Nexthop configuration \n"
1644 "Configure use of backup nexthops in recursive resolution\n")
1646 zebra_nhg_set_recursive_use_backups(!no
);
1650 DEFUN (no_ip_nht_default_route
,
1651 no_ip_nht_default_route_cmd
,
1652 "no ip nht resolve-via-default",
1655 "Filter Next Hop tracking route resolution\n"
1656 "Resolve via default route\n")
1658 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1663 if (!zvrf
->zebra_rnh_ip_default_route
)
1666 zvrf
->zebra_rnh_ip_default_route
= 0;
1667 zebra_evaluate_rnh(zvrf
, AFI_IP
, 0, RNH_NEXTHOP_TYPE
, NULL
);
1671 DEFUN (ipv6_nht_default_route
,
1672 ipv6_nht_default_route_cmd
,
1673 "ipv6 nht resolve-via-default",
1675 "Filter Next Hop tracking route resolution\n"
1676 "Resolve via default route\n")
1678 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1683 if (zvrf
->zebra_rnh_ipv6_default_route
)
1686 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1687 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 0, RNH_NEXTHOP_TYPE
, NULL
);
1691 DEFUN (no_ipv6_nht_default_route
,
1692 no_ipv6_nht_default_route_cmd
,
1693 "no ipv6 nht resolve-via-default",
1696 "Filter Next Hop tracking route resolution\n"
1697 "Resolve via default route\n")
1700 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1705 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1708 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1709 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 0, RNH_NEXTHOP_TYPE
, NULL
);
1717 ip$ipv4 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1718 [vrf <NAME$vrf_name|all$vrf_all>]\
1721 |A.B.C.D/M$prefix longer-prefixes\
1722 |supernets-only$supernets_only\
1725 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1726 |ospf$type_str (1-65535)$ospf_instance_id\
1728 |ipv6$ipv6 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1729 [vrf <NAME$vrf_name|all$vrf_all>]\
1732 |X:X::X:X/M$prefix longer-prefixes\
1734 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1739 "IP forwarding table\n"
1740 "IP routing table\n"
1741 "Table to display\n"
1742 "The table number to display\n"
1744 VRF_FULL_CMD_HELP_STR
1745 "Show only routes with tag\n"
1747 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1748 "Show route matching the specified Network/Mask pair only\n"
1749 "Show supernet entries only\n"
1750 FRR_IP_REDIST_HELP_STR_ZEBRA
1751 "Open Shortest Path First (OSPFv2)\n"
1754 "IP forwarding table\n"
1755 "IP routing table\n"
1756 "Table to display\n"
1757 "The table number to display\n"
1759 VRF_FULL_CMD_HELP_STR
1760 "Show only routes with tag\n"
1763 "Show route matching the specified Network/Mask pair only\n"
1764 FRR_IP6_REDIST_HELP_STR_ZEBRA
1767 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1770 struct zebra_vrf
*zvrf
;
1771 struct route_show_ctx ctx
= {
1772 .multi
= vrf_all
|| table_all
,
1775 if (!vrf_is_backend_netns()) {
1776 if ((vrf_all
|| vrf_name
) && (table
|| table_all
)) {
1778 vty_out(vty
, "{}\n");
1780 vty_out(vty
, "Linux vrf backend already points to table id\n");
1781 vty_out(vty
, "Either remove table parameter or vrf parameter\n");
1787 type
= proto_redistnum(afi
, type_str
);
1789 vty_out(vty
, "Unknown route type\n");
1795 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1796 if ((zvrf
= vrf
->info
) == NULL
1797 || (zvrf
->table
[afi
][SAFI_UNICAST
] == NULL
))
1801 do_show_ip_route_all(vty
, zvrf
, afi
, !!fib
,
1803 prefix_str
? prefix
: NULL
,
1804 !!supernets_only
, type
,
1805 ospf_instance_id
, &ctx
);
1807 do_show_ip_route(vty
, zvrf_name(zvrf
), afi
,
1808 SAFI_UNICAST
, !!fib
, !!json
,
1810 prefix_str
? prefix
: NULL
,
1811 !!supernets_only
, type
,
1812 ospf_instance_id
, table
, &ctx
);
1815 vrf_id_t vrf_id
= VRF_DEFAULT
;
1818 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1819 vrf
= vrf_lookup_by_id(vrf_id
);
1828 do_show_ip_route_all(vty
, zvrf
, afi
, !!fib
, !!json
, tag
,
1829 prefix_str
? prefix
: NULL
,
1830 !!supernets_only
, type
,
1831 ospf_instance_id
, &ctx
);
1833 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
,
1835 prefix_str
? prefix
: NULL
,
1836 !!supernets_only
, type
,
1837 ospf_instance_id
, table
, &ctx
);
1843 ALIAS_HIDDEN (show_route
,
1845 "show <ip$ipv4|ipv6$ipv6> ro",
1849 "IP routing table\n");
1852 DEFPY (show_route_detail
,
1853 show_route_detail_cmd
,
1856 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1861 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1867 [json$json] [nexthop-group$ng]",
1870 "IPv6 forwarding table\n"
1871 "IP routing table\n"
1872 VRF_FULL_CMD_HELP_STR
1873 "Network in the IP routing table to display\n"
1874 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1876 "IPv6 forwarding table\n"
1877 "IPv6 routing table\n"
1878 VRF_FULL_CMD_HELP_STR
1882 "Nexthop Group Information\n")
1884 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1885 struct route_table
*table
;
1887 struct route_node
*rn
;
1888 bool use_fib
= !!fib
;
1890 bool network_found
= false;
1891 bool show_ng
= !!ng
;
1894 prefix_str
= address_str
;
1895 if (str2prefix(prefix_str
, &p
) < 0) {
1896 vty_out(vty
, "%% Malformed address\n");
1902 struct zebra_vrf
*zvrf
;
1904 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1905 if ((zvrf
= vrf
->info
) == NULL
1906 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1909 rn
= route_node_match(table
, &p
);
1912 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1913 route_unlock_node(rn
);
1917 dest
= rib_dest_from_rnode(rn
);
1918 if (use_fib
&& !dest
->selected_fib
) {
1919 route_unlock_node(rn
);
1923 network_found
= true;
1925 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1927 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1930 route_unlock_node(rn
);
1933 if (!network_found
) {
1935 vty_out(vty
, "{}\n");
1939 "%% Network not in FIB\n");
1942 "%% Network not in RIB\n");
1947 vrf_id_t vrf_id
= VRF_DEFAULT
;
1950 VRF_GET_ID(vrf_id
, vrf_name
, false);
1952 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1956 rn
= route_node_match(table
, &p
);
1958 dest
= rib_dest_from_rnode(rn
);
1960 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1961 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1963 vty_out(vty
, "{}\n");
1967 "%% Network not in FIB\n");
1970 "%% Network not in table\n");
1973 route_unlock_node(rn
);
1978 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1980 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1982 route_unlock_node(rn
);
1988 DEFPY (show_route_summary
,
1989 show_route_summary_cmd
,
1990 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1991 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
1995 "IP routing table\n"
1996 VRF_FULL_CMD_HELP_STR
1997 "Summary of all routes\n"
1998 "Table to display summary for\n"
1999 "The table number\n"
2003 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
2004 struct route_table
*table
;
2005 bool uj
= use_json(argc
, argv
);
2009 struct zebra_vrf
*zvrf
;
2011 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2012 if ((zvrf
= vrf
->info
) == NULL
)
2016 table
= zebra_vrf_table(afi
, SAFI_UNICAST
,
2019 table
= zebra_vrf_lookup_table_with_table_id(
2020 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
,
2027 vty_show_ip_route_summary_prefix(vty
, table
,
2030 vty_show_ip_route_summary(vty
, table
, uj
);
2033 vrf_id_t vrf_id
= VRF_DEFAULT
;
2036 VRF_GET_ID(vrf_id
, vrf_name
, false);
2039 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
2041 table
= zebra_vrf_lookup_table_with_table_id(
2042 afi
, SAFI_UNICAST
, vrf_id
, table_id
);
2047 vty_show_ip_route_summary_prefix(vty
, table
, uj
);
2049 vty_show_ip_route_summary(vty
, table
, uj
);
2055 static void vty_show_ip_route_summary(struct vty
*vty
,
2056 struct route_table
*table
, bool use_json
)
2058 struct route_node
*rn
;
2059 struct route_entry
*re
;
2060 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2061 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
2062 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2063 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2064 uint32_t offload_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2065 uint32_t trap_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2068 json_object
*json_route_summary
= NULL
;
2069 json_object
*json_route_routes
= NULL
;
2071 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
2072 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
2073 memset(&offload_cnt
, 0, sizeof(offload_cnt
));
2074 memset(&trap_cnt
, 0, sizeof(trap_cnt
));
2077 json_route_summary
= json_object_new_object();
2078 json_route_routes
= json_object_new_array();
2079 json_object_object_add(json_route_summary
, "routes",
2083 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2084 RNODE_FOREACH_RE (rn
, re
) {
2085 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
2086 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
2088 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2090 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2092 rib_cnt
[re
->type
]++;
2094 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
2095 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2098 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2100 fib_cnt
[re
->type
]++;
2103 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
)) {
2105 trap_cnt
[ZEBRA_ROUTE_IBGP
]++;
2107 trap_cnt
[re
->type
]++;
2110 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
)) {
2112 offload_cnt
[ZEBRA_ROUTE_IBGP
]++;
2114 offload_cnt
[re
->type
]++;
2119 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2121 zvrf_name(((struct rib_table_info
*)
2122 route_table_get_info(table
))
2125 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
2126 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
2127 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
2128 if (i
== ZEBRA_ROUTE_BGP
) {
2130 json_object
*json_route_ebgp
=
2131 json_object_new_object();
2133 json_object_int_add(
2134 json_route_ebgp
, "fib",
2135 fib_cnt
[ZEBRA_ROUTE_BGP
]);
2136 json_object_int_add(
2137 json_route_ebgp
, "rib",
2138 rib_cnt
[ZEBRA_ROUTE_BGP
]);
2139 json_object_int_add(
2140 json_route_ebgp
, "fibOffLoaded",
2141 offload_cnt
[ZEBRA_ROUTE_BGP
]);
2142 json_object_int_add(
2143 json_route_ebgp
, "fibTrapped",
2144 trap_cnt
[ZEBRA_ROUTE_BGP
]);
2146 json_object_string_add(json_route_ebgp
,
2148 json_object_array_add(json_route_routes
,
2151 json_object
*json_route_ibgp
=
2152 json_object_new_object();
2154 json_object_int_add(
2155 json_route_ibgp
, "fib",
2156 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2157 json_object_int_add(
2158 json_route_ibgp
, "rib",
2159 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2160 json_object_int_add(
2161 json_route_ibgp
, "fibOffLoaded",
2162 offload_cnt
[ZEBRA_ROUTE_IBGP
]);
2163 json_object_int_add(
2164 json_route_ibgp
, "fibTrapped",
2165 trap_cnt
[ZEBRA_ROUTE_IBGP
]);
2166 json_object_string_add(json_route_ibgp
,
2168 json_object_array_add(json_route_routes
,
2171 vty_out(vty
, "%-20s %-20d %-20d \n",
2173 rib_cnt
[ZEBRA_ROUTE_BGP
],
2174 fib_cnt
[ZEBRA_ROUTE_BGP
]);
2175 vty_out(vty
, "%-20s %-20d %-20d \n",
2177 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2178 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2182 json_object
*json_route_type
=
2183 json_object_new_object();
2185 json_object_int_add(json_route_type
,
2187 json_object_int_add(json_route_type
,
2190 json_object_int_add(json_route_type
,
2193 json_object_int_add(json_route_type
,
2196 json_object_string_add(
2197 json_route_type
, "type",
2198 zebra_route_string(i
));
2199 json_object_array_add(json_route_routes
,
2202 vty_out(vty
, "%-20s %-20d %-20d \n",
2203 zebra_route_string(i
),
2204 rib_cnt
[i
], fib_cnt
[i
]);
2210 json_object_int_add(json_route_summary
, "routesTotal",
2211 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2212 json_object_int_add(json_route_summary
, "routesTotalFib",
2213 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2215 vty_out(vty
, "%s\n",
2216 json_object_to_json_string_ext(
2217 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2218 json_object_free(json_route_summary
);
2220 vty_out(vty
, "------\n");
2221 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2222 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2228 * Implementation of the ip route summary prefix command.
2230 * This command prints the primary prefixes that have been installed by various
2231 * protocols on the box.
2234 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
2235 struct route_table
*table
,
2238 struct route_node
*rn
;
2239 struct route_entry
*re
;
2240 struct nexthop
*nexthop
;
2241 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2242 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
2243 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2244 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2247 json_object
*json_route_summary
= NULL
;
2248 json_object
*json_route_routes
= NULL
;
2250 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
2251 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
2254 json_route_summary
= json_object_new_object();
2255 json_route_routes
= json_object_new_array();
2256 json_object_object_add(json_route_summary
, "prefixRoutes",
2260 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2261 RNODE_FOREACH_RE (rn
, re
) {
2264 * In case of ECMP, count only once.
2267 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
2268 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2269 fib_cnt
[re
->type
]++;
2271 for (nexthop
= re
->nhe
->nhg
.nexthop
; (!cnt
&& nexthop
);
2272 nexthop
= nexthop
->next
) {
2274 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2275 rib_cnt
[re
->type
]++;
2276 if (re
->type
== ZEBRA_ROUTE_BGP
2277 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
2278 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2279 if (CHECK_FLAG(re
->status
,
2280 ROUTE_ENTRY_INSTALLED
))
2281 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2287 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2288 "Prefix Routes", "FIB",
2289 zvrf_name(((struct rib_table_info
*)
2290 route_table_get_info(table
))
2293 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
2294 if (rib_cnt
[i
] > 0) {
2295 if (i
== ZEBRA_ROUTE_BGP
) {
2297 json_object
*json_route_ebgp
=
2298 json_object_new_object();
2300 json_object_int_add(
2301 json_route_ebgp
, "fib",
2302 fib_cnt
[ZEBRA_ROUTE_BGP
]
2303 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2304 json_object_int_add(
2305 json_route_ebgp
, "rib",
2306 rib_cnt
[ZEBRA_ROUTE_BGP
]
2307 - rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2308 json_object_string_add(json_route_ebgp
,
2310 json_object_array_add(json_route_routes
,
2313 json_object
*json_route_ibgp
=
2314 json_object_new_object();
2316 json_object_int_add(
2317 json_route_ibgp
, "fib",
2318 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2319 json_object_int_add(
2320 json_route_ibgp
, "rib",
2321 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2322 json_object_string_add(json_route_ibgp
,
2324 json_object_array_add(json_route_routes
,
2327 vty_out(vty
, "%-20s %-20d %-20d \n",
2329 rib_cnt
[ZEBRA_ROUTE_BGP
]
2330 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
2331 fib_cnt
[ZEBRA_ROUTE_BGP
]
2332 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2333 vty_out(vty
, "%-20s %-20d %-20d \n",
2335 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2336 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2340 json_object
*json_route_type
=
2341 json_object_new_object();
2343 json_object_int_add(json_route_type
,
2345 json_object_int_add(json_route_type
,
2347 json_object_string_add(
2348 json_route_type
, "type",
2349 zebra_route_string(i
));
2350 json_object_array_add(json_route_routes
,
2353 vty_out(vty
, "%-20s %-20d %-20d \n",
2354 zebra_route_string(i
),
2355 rib_cnt
[i
], fib_cnt
[i
]);
2361 json_object_int_add(json_route_summary
, "prefixRoutesTotal",
2362 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2363 json_object_int_add(json_route_summary
, "prefixRoutesTotalFib",
2364 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2366 vty_out(vty
, "%s\n",
2367 json_object_to_json_string_ext(
2368 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2369 json_object_free(json_route_summary
);
2371 vty_out(vty
, "------\n");
2372 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2373 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2379 * Show IPv6 mroute command.Used to dump
2380 * the Multicast routing table.
2382 DEFUN (show_ipv6_mroute
,
2383 show_ipv6_mroute_cmd
,
2384 "show ipv6 mroute [vrf NAME]",
2387 "IPv6 Multicast routing table\n"
2390 struct route_table
*table
;
2391 struct route_node
*rn
;
2392 struct route_entry
*re
;
2394 vrf_id_t vrf_id
= VRF_DEFAULT
;
2397 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
2399 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2403 /* Show all IPv6 route. */
2404 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2405 RNODE_FOREACH_RE (rn
, re
) {
2407 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2410 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2415 DEFUN (show_ipv6_mroute_vrf_all
,
2416 show_ipv6_mroute_vrf_all_cmd
,
2417 "show ipv6 mroute vrf all",
2420 "IPv6 Multicast routing table\n"
2421 VRF_ALL_CMD_HELP_STR
)
2423 struct route_table
*table
;
2424 struct route_node
*rn
;
2425 struct route_entry
*re
;
2427 struct zebra_vrf
*zvrf
;
2430 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2431 if ((zvrf
= vrf
->info
) == NULL
2432 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2435 /* Show all IPv6 route. */
2436 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2437 RNODE_FOREACH_RE (rn
, re
) {
2439 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2442 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2448 DEFUN (allow_external_route_update
,
2449 allow_external_route_update_cmd
,
2450 "allow-external-route-update",
2451 "Allow FRR routes to be overwritten by external processes\n")
2458 DEFUN (no_allow_external_route_update
,
2459 no_allow_external_route_update_cmd
,
2460 "no allow-external-route-update",
2462 "Allow FRR routes to be overwritten by external processes\n")
2477 struct zebra_vrf
*zvrf
;
2479 if (vrf_is_backend_netns())
2480 vty_out(vty
, "netns-based vrfs\n");
2482 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2483 if (!(zvrf
= vrf
->info
))
2485 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2488 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2489 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
2490 vty_out(vty
, "inactive");
2491 else if (zvrf_ns_name(zvrf
))
2492 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2493 zvrf_ns_name(zvrf
));
2495 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2497 if (vrf_is_user_cfged(vrf
))
2498 vty_out(vty
, " (configured)");
2505 DEFPY (evpn_mh_mac_holdtime
,
2506 evpn_mh_mac_holdtime_cmd
,
2507 "[no$no] evpn mh mac-holdtime (0-86400)$duration",
2512 "Duration in seconds\n")
2514 return zebra_evpn_mh_mac_holdtime_update(vty
, duration
,
2518 DEFPY (evpn_mh_neigh_holdtime
,
2519 evpn_mh_neigh_holdtime_cmd
,
2520 "[no$no] evpn mh neigh-holdtime (0-86400)$duration",
2524 "Neighbor entry hold time\n"
2525 "Duration in seconds\n")
2528 return zebra_evpn_mh_neigh_holdtime_update(vty
, duration
,
2532 DEFPY (evpn_mh_startup_delay
,
2533 evpn_mh_startup_delay_cmd
,
2534 "[no] evpn mh startup-delay(0-3600)$duration",
2539 "duration in seconds\n")
2542 return zebra_evpn_mh_startup_delay_update(vty
, duration
,
2546 DEFPY(evpn_mh_redirect_off
, evpn_mh_redirect_off_cmd
,
2547 "[no$no] evpn mh redirect-off",
2551 "ES bond redirect for fast-failover off\n")
2555 redirect_off
= no
? false : true;
2557 return zebra_evpn_mh_redirect_off(vty
, redirect_off
);
2560 DEFUN (default_vrf_vni_mapping
,
2561 default_vrf_vni_mapping_cmd
,
2562 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2563 "VNI corresponding to the DEFAULT VRF\n"
2565 "Prefix routes only \n")
2567 char xpath
[XPATH_MAXLEN
];
2568 struct zebra_vrf
*zvrf
= NULL
;
2571 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2578 snprintf(xpath
, sizeof(xpath
), FRR_VRF_KEY_XPATH
"/frr-zebra:zebra",
2580 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
2582 snprintf(xpath
, sizeof(xpath
),
2583 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/l3vni-id",
2585 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, argv
[1]->arg
);
2588 snprintf(xpath
, sizeof(xpath
),
2589 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/prefix-only",
2591 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, "true");
2594 return nb_cli_apply_changes(vty
, NULL
);
2597 DEFUN (no_default_vrf_vni_mapping
,
2598 no_default_vrf_vni_mapping_cmd
,
2599 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2601 "VNI corresponding to DEFAULT VRF\n"
2603 "Prefix routes only \n")
2605 char xpath
[XPATH_MAXLEN
];
2607 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2608 struct zebra_vrf
*zvrf
= NULL
;
2610 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2617 if (zvrf
->l3vni
!= vni
) {
2618 vty_out(vty
, "VNI %d doesn't exist in VRF: %s \n", vni
,
2623 snprintf(xpath
, sizeof(xpath
),
2624 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/l3vni-id",
2626 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, argv
[2]->arg
);
2629 snprintf(xpath
, sizeof(xpath
),
2630 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/prefix-only",
2632 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, "true");
2635 snprintf(xpath
, sizeof(xpath
), FRR_VRF_KEY_XPATH
"/frr-zebra:zebra",
2637 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
2639 return nb_cli_apply_changes(vty
, NULL
);
2642 DEFUN (vrf_vni_mapping
,
2643 vrf_vni_mapping_cmd
,
2644 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2645 "VNI corresponding to tenant VRF\n"
2647 "prefix-routes-only\n")
2651 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2659 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra", NB_OP_CREATE
, NULL
);
2660 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY
,
2664 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/prefix-only",
2665 NB_OP_MODIFY
, "true");
2667 return nb_cli_apply_changes(vty
, NULL
);
2670 DEFUN (no_vrf_vni_mapping
,
2671 no_vrf_vni_mapping_cmd
,
2672 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2674 "VNI corresponding to tenant VRF\n"
2676 "prefix-routes-only\n")
2680 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2681 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2689 if (zvrf
->l3vni
!= vni
) {
2690 vty_out(vty
, "VNI %d doesn't exist in VRF: %s \n", vni
,
2695 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY
,
2699 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/prefix-only",
2700 NB_OP_DESTROY
, "true");
2702 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra", NB_OP_DESTROY
, NULL
);
2704 return nb_cli_apply_changes(vty
, NULL
);
2708 DEFUN (show_vrf_vni
,
2710 "show vrf vni [json]",
2717 struct zebra_vrf
*zvrf
;
2718 json_object
*json
= NULL
;
2719 json_object
*json_vrfs
= NULL
;
2720 bool uj
= use_json(argc
, argv
);
2723 json
= json_object_new_object();
2724 json_vrfs
= json_object_new_array();
2728 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2729 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2731 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2736 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2740 json_object_object_add(json
, "vrfs", json_vrfs
);
2741 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2742 json
, JSON_C_TO_STRING_PRETTY
));
2743 json_object_free(json
);
2749 DEFUN (show_evpn_global
,
2750 show_evpn_global_cmd
,
2756 bool uj
= use_json(argc
, argv
);
2758 zebra_vxlan_print_evpn(vty
, uj
);
2762 DEFPY(show_evpn_l2_nh
,
2763 show_evpn_l2_nh_cmd
,
2764 "show evpn l2-nh [json$json]",
2772 zebra_evpn_l2_nh_show(vty
, uj
);
2779 "show evpn es [NAME$esi_str|detail$detail] [json$json]",
2782 "Ethernet Segment\n"
2784 "Detailed information\n"
2791 if (!str_to_esi(esi_str
, &esi
)) {
2792 vty_out(vty
, "%% Malformed ESI\n");
2795 zebra_evpn_es_show_esi(vty
, uj
, &esi
);
2798 zebra_evpn_es_show_detail(vty
, uj
);
2800 zebra_evpn_es_show(vty
, uj
);
2806 DEFPY(show_evpn_es_evi
,
2807 show_evpn_es_evi_cmd
,
2808 "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]",
2811 "Ethernet Segment per EVI\n"
2812 "VxLAN Network Identifier\n"
2814 "Detailed information\n"
2821 zebra_evpn_es_evi_show_vni(vty
, uj
, vni
, ud
);
2823 zebra_evpn_es_evi_show(vty
, uj
, ud
);
2828 DEFPY(show_evpn_access_vlan
,
2829 show_evpn_access_vlan_cmd
,
2830 "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]",
2835 "Detailed information\n"
2841 zebra_evpn_acc_vl_show_vid(vty
, uj
, vid
);
2844 zebra_evpn_acc_vl_show_detail(vty
, uj
);
2846 zebra_evpn_acc_vl_show(vty
, uj
);
2852 DEFUN (show_evpn_vni
,
2854 "show evpn vni [json]",
2857 "VxLAN Network Identifier\n"
2860 struct zebra_vrf
*zvrf
;
2861 bool uj
= use_json(argc
, argv
);
2863 zvrf
= zebra_vrf_get_evpn();
2864 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2868 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2869 "show evpn vni detail [json]",
2872 "VxLAN Network Identifier\n"
2873 "Detailed Information On Each VNI\n"
2876 struct zebra_vrf
*zvrf
;
2877 bool uj
= use_json(argc
, argv
);
2879 zvrf
= zebra_vrf_get_evpn();
2880 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2884 DEFUN (show_evpn_vni_vni
,
2885 show_evpn_vni_vni_cmd
,
2886 "show evpn vni " CMD_VNI_RANGE
"[json]",
2889 "VxLAN Network Identifier\n"
2893 struct zebra_vrf
*zvrf
;
2895 bool uj
= use_json(argc
, argv
);
2897 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2898 zvrf
= zebra_vrf_get_evpn();
2899 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2903 DEFUN (show_evpn_rmac_vni_mac
,
2904 show_evpn_rmac_vni_mac_cmd
,
2905 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2912 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2917 bool uj
= use_json(argc
, argv
);
2919 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2920 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2921 vty_out(vty
, "%% Malformed MAC address\n");
2924 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2928 DEFUN (show_evpn_rmac_vni
,
2929 show_evpn_rmac_vni_cmd
,
2930 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2939 bool uj
= use_json(argc
, argv
);
2941 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2942 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2947 DEFUN (show_evpn_rmac_vni_all
,
2948 show_evpn_rmac_vni_all_cmd
,
2949 "show evpn rmac vni all [json]",
2957 bool uj
= use_json(argc
, argv
);
2959 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2964 DEFUN (show_evpn_nh_vni_ip
,
2965 show_evpn_nh_vni_ip_cmd
,
2966 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2973 "Host address (ipv4 or ipv6)\n"
2978 bool uj
= use_json(argc
, argv
);
2980 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2981 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2983 vty_out(vty
, "%% Malformed Neighbor address\n");
2986 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2991 DEFUN (show_evpn_nh_vni
,
2992 show_evpn_nh_vni_cmd
,
2993 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
3002 bool uj
= use_json(argc
, argv
);
3004 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3005 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
3010 DEFUN (show_evpn_nh_vni_all
,
3011 show_evpn_nh_vni_all_cmd
,
3012 "show evpn next-hops vni all [json]",
3020 bool uj
= use_json(argc
, argv
);
3022 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
3027 DEFUN (show_evpn_mac_vni
,
3028 show_evpn_mac_vni_cmd
,
3029 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
3033 "VxLAN Network Identifier\n"
3037 struct zebra_vrf
*zvrf
;
3039 bool uj
= use_json(argc
, argv
);
3041 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3042 zvrf
= zebra_vrf_get_evpn();
3043 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
3047 DEFUN (show_evpn_mac_vni_all
,
3048 show_evpn_mac_vni_all_cmd
,
3049 "show evpn mac vni all [json]",
3053 "VxLAN Network Identifier\n"
3057 struct zebra_vrf
*zvrf
;
3058 bool uj
= use_json(argc
, argv
);
3060 zvrf
= zebra_vrf_get_evpn();
3061 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
3065 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
3066 "show evpn mac vni all detail [json]",
3070 "VxLAN Network Identifier\n"
3072 "Detailed Information On Each VNI MAC\n"
3075 struct zebra_vrf
*zvrf
;
3076 bool uj
= use_json(argc
, argv
);
3078 zvrf
= zebra_vrf_get_evpn();
3079 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
3083 DEFUN (show_evpn_mac_vni_all_vtep
,
3084 show_evpn_mac_vni_all_vtep_cmd
,
3085 "show evpn mac vni all vtep A.B.C.D [json]",
3089 "VxLAN Network Identifier\n"
3092 "Remote VTEP IP address\n"
3095 struct zebra_vrf
*zvrf
;
3096 struct in_addr vtep_ip
;
3097 bool uj
= use_json(argc
, argv
);
3099 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3101 vty_out(vty
, "%% Malformed VTEP IP address\n");
3104 zvrf
= zebra_vrf_get_evpn();
3105 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
3111 DEFUN (show_evpn_mac_vni_mac
,
3112 show_evpn_mac_vni_mac_cmd
,
3113 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
3117 "VxLAN Network Identifier\n"
3120 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3124 struct zebra_vrf
*zvrf
;
3127 bool uj
= use_json(argc
, argv
);
3129 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3130 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
3131 vty_out(vty
, "%% Malformed MAC address");
3134 zvrf
= zebra_vrf_get_evpn();
3135 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
3139 DEFUN (show_evpn_mac_vni_vtep
,
3140 show_evpn_mac_vni_vtep_cmd
,
3141 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
3145 "VxLAN Network Identifier\n"
3148 "Remote VTEP IP address\n"
3151 struct zebra_vrf
*zvrf
;
3153 struct in_addr vtep_ip
;
3154 bool uj
= use_json(argc
, argv
);
3156 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3157 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3159 vty_out(vty
, "%% Malformed VTEP IP address\n");
3163 zvrf
= zebra_vrf_get_evpn();
3164 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
3168 DEFPY (show_evpn_mac_vni_all_dad
,
3169 show_evpn_mac_vni_all_dad_cmd
,
3170 "show evpn mac vni all duplicate [json]",
3174 "VxLAN Network Identifier\n"
3176 "Duplicate address list\n"
3179 struct zebra_vrf
*zvrf
;
3180 bool uj
= use_json(argc
, argv
);
3182 zvrf
= zebra_vrf_get_evpn();
3183 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
3188 DEFPY (show_evpn_mac_vni_dad
,
3189 show_evpn_mac_vni_dad_cmd
,
3190 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
3194 "VxLAN Network Identifier\n"
3196 "Duplicate address list\n"
3199 struct zebra_vrf
*zvrf
;
3200 bool uj
= use_json(argc
, argv
);
3202 zvrf
= zebra_vrf_get_evpn();
3204 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
3209 DEFPY (show_evpn_neigh_vni_dad
,
3210 show_evpn_neigh_vni_dad_cmd
,
3211 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
3214 "ARP and ND cache\n"
3215 "VxLAN Network Identifier\n"
3217 "Duplicate address list\n"
3220 struct zebra_vrf
*zvrf
;
3221 bool uj
= use_json(argc
, argv
);
3223 zvrf
= zebra_vrf_get_evpn();
3224 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
3228 DEFPY (show_evpn_neigh_vni_all_dad
,
3229 show_evpn_neigh_vni_all_dad_cmd
,
3230 "show evpn arp-cache vni all duplicate [json]",
3233 "ARP and ND cache\n"
3234 "VxLAN Network Identifier\n"
3236 "Duplicate address list\n"
3239 struct zebra_vrf
*zvrf
;
3240 bool uj
= use_json(argc
, argv
);
3242 zvrf
= zebra_vrf_get_evpn();
3243 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
3248 DEFUN (show_evpn_neigh_vni
,
3249 show_evpn_neigh_vni_cmd
,
3250 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
3253 "ARP and ND cache\n"
3254 "VxLAN Network Identifier\n"
3258 struct zebra_vrf
*zvrf
;
3260 bool uj
= use_json(argc
, argv
);
3262 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3263 zvrf
= zebra_vrf_get_evpn();
3264 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
3268 DEFUN (show_evpn_neigh_vni_all
,
3269 show_evpn_neigh_vni_all_cmd
,
3270 "show evpn arp-cache vni all [json]",
3273 "ARP and ND cache\n"
3274 "VxLAN Network Identifier\n"
3278 struct zebra_vrf
*zvrf
;
3279 bool uj
= use_json(argc
, argv
);
3281 zvrf
= zebra_vrf_get_evpn();
3282 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
3286 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
3287 "show evpn arp-cache vni all detail [json]",
3290 "ARP and ND cache\n"
3291 "VxLAN Network Identifier\n"
3293 "Neighbor details for all vnis in detail\n" JSON_STR
)
3295 struct zebra_vrf
*zvrf
;
3296 bool uj
= use_json(argc
, argv
);
3298 zvrf
= zebra_vrf_get_evpn();
3299 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
3303 DEFUN (show_evpn_neigh_vni_neigh
,
3304 show_evpn_neigh_vni_neigh_cmd
,
3305 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
3308 "ARP and ND cache\n"
3309 "VxLAN Network Identifier\n"
3312 "Neighbor address (IPv4 or IPv6 address)\n"
3315 struct zebra_vrf
*zvrf
;
3318 bool uj
= use_json(argc
, argv
);
3320 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3321 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
3323 vty_out(vty
, "%% Malformed Neighbor address\n");
3326 zvrf
= zebra_vrf_get_evpn();
3327 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
3331 DEFUN (show_evpn_neigh_vni_vtep
,
3332 show_evpn_neigh_vni_vtep_cmd
,
3333 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
3336 "ARP and ND cache\n"
3337 "VxLAN Network Identifier\n"
3340 "Remote VTEP IP address\n"
3343 struct zebra_vrf
*zvrf
;
3345 struct in_addr vtep_ip
;
3346 bool uj
= use_json(argc
, argv
);
3348 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3349 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3351 vty_out(vty
, "%% Malformed VTEP IP address\n");
3355 zvrf
= zebra_vrf_get_evpn();
3356 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
3360 /* policy routing contexts */
3361 DEFUN (show_pbr_ipset
,
3363 "show pbr ipset [WORD]",
3365 "Policy-Based Routing\n"
3366 "IPset Context information\n"
3367 "IPset Name information\n")
3371 found
= argv_find(argv
, argc
, "WORD", &idx
);
3373 zebra_pbr_show_ipset_list(vty
, NULL
);
3375 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
3379 /* policy routing contexts */
3380 DEFUN (show_pbr_iptable
,
3381 show_pbr_iptable_cmd
,
3382 "show pbr iptable [WORD]",
3384 "Policy-Based Routing\n"
3385 "IPtable Context information\n"
3386 "IPtable Name information\n")
3391 found
= argv_find(argv
, argc
, "WORD", &idx
);
3393 zebra_pbr_show_iptable(vty
, NULL
);
3395 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
3399 DEFPY (clear_evpn_dup_addr
,
3400 clear_evpn_dup_addr_cmd
,
3401 "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>]>",
3404 "Duplicate address \n"
3405 "VxLAN Network Identifier\n"
3409 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3414 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
3415 int ret
= CMD_SUCCESS
;
3417 struct yang_data
*yang_dup
= NULL
, *yang_dup_ip
= NULL
,
3418 *yang_dup_mac
= NULL
;
3423 yang_dup
= yang_data_new(
3424 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice",
3427 yang_dup
= yang_data_new_uint32(
3428 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id",
3430 if (!is_zero_mac(&mac
->eth_addr
)) {
3431 yang_dup_mac
= yang_data_new_mac(
3432 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr",
3435 listnode_add(input
, yang_dup_mac
);
3437 if (sockunion_family(ip
) == AF_INET
) {
3438 host_ip
.ipa_type
= IPADDR_V4
;
3439 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
3441 host_ip
.ipa_type
= IPADDR_V6
;
3442 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
3443 sizeof(struct in6_addr
));
3446 yang_dup_ip
= yang_data_new_ip(
3447 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr",
3451 listnode_add(input
, yang_dup_ip
);
3456 listnode_add(input
, yang_dup
);
3457 ret
= nb_cli_rpc(vty
, "/frr-zebra:clear-evpn-dup-addr", input
,
3461 list_delete(&input
);
3466 /* Static ip route configuration write function. */
3467 static int zebra_ip_config(struct vty
*vty
)
3471 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
3476 DEFUN (ip_zebra_import_table_distance
,
3477 ip_zebra_import_table_distance_cmd
,
3478 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
3480 "import routes from non-main kernel table\n"
3481 "kernel routing table id\n"
3482 "Distance for imported routes\n"
3483 "Default distance value\n"
3484 "route-map for filtering\n"
3487 uint32_t table_id
= 0;
3489 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
3490 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
3492 strmatch(argv
[argc
- 2]->text
, "route-map")
3493 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
3497 if (argc
== 7 || (argc
== 5 && !rmap
))
3498 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
3500 if (!is_zebra_valid_kernel_table(table_id
)) {
3502 "Invalid routing table ID, %d. Must be in range 1-252\n",
3505 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3509 if (is_zebra_main_routing_table(table_id
)) {
3511 "Invalid routing table ID, %d. Must be non-default table\n",
3514 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3518 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
3521 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3526 DEFUN_HIDDEN (zebra_packet_process
,
3527 zebra_packet_process_cmd
,
3528 "zebra zapi-packets (1-10000)",
3531 "Number of packets to process before relinquishing thread\n")
3533 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3535 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
3536 memory_order_relaxed
);
3541 DEFUN_HIDDEN (no_zebra_packet_process
,
3542 no_zebra_packet_process_cmd
,
3543 "no zebra zapi-packets [(1-10000)]",
3547 "Number of packets to process before relinquishing thread\n")
3549 atomic_store_explicit(&zrouter
.packets_to_process
,
3550 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
3551 memory_order_relaxed
);
3556 DEFUN_HIDDEN (zebra_workqueue_timer
,
3557 zebra_workqueue_timer_cmd
,
3558 "zebra work-queue (0-10000)",
3561 "Time in milliseconds\n")
3563 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3564 zrouter
.ribq
->spec
.hold
= timer
;
3569 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3570 no_zebra_workqueue_timer_cmd
,
3571 "no zebra work-queue [(0-10000)]",
3575 "Time in milliseconds\n")
3577 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3582 DEFUN (no_ip_zebra_import_table
,
3583 no_ip_zebra_import_table_cmd
,
3584 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3587 "import routes from non-main kernel table\n"
3588 "kernel routing table id\n"
3589 "Distance for imported routes\n"
3590 "Default distance value\n"
3591 "route-map for filtering\n"
3594 uint32_t table_id
= 0;
3595 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3597 if (!is_zebra_valid_kernel_table(table_id
)) {
3599 "Invalid routing table ID. Must be in range 1-252\n");
3603 if (is_zebra_main_routing_table(table_id
)) {
3605 "Invalid routing table ID, %d. Must be non-default table\n",
3610 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
3613 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
3616 static int config_write_protocol(struct vty
*vty
)
3619 vty_out(vty
, "allow-external-route-update\n");
3621 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3622 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
3624 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3625 vty_out(vty
, "zebra zapi-packets %u\n",
3626 zrouter
.packets_to_process
);
3628 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3630 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3631 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3632 ipv4_multicast_mode
== MCAST_URIB_ONLY
3634 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3636 : ipv4_multicast_mode
3637 == MCAST_MIX_MRIB_FIRST
3639 : ipv4_multicast_mode
3640 == MCAST_MIX_DISTANCE
3644 /* Include dataplane info */
3645 dplane_config_write_helper(vty
);
3647 zebra_evpn_mh_config_write(vty
);
3649 /* Include nexthop-group config */
3650 if (!zebra_nhg_kernel_nexthops_enabled())
3651 vty_out(vty
, "no zebra nexthop kernel enable\n");
3653 if (zebra_nhg_proto_nexthops_only())
3654 vty_out(vty
, "zebra nexthop proto only\n");
3656 if (!zebra_nhg_recursive_use_backups())
3657 vty_out(vty
, "no zebra nexthop resolve-via-backup\n");
3660 /* Include netlink info */
3661 netlink_config_write_helper(vty
);
3662 #endif /* HAVE_NETLINK */
3675 if (zrouter
.asic_offloaded
)
3676 vty_out(vty
, "Asic Offload is being used\n");
3679 " Route Route Neighbor LSP LSP\n");
3681 "VRF Installs Removals Updates Installs Removals\n");
3683 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3684 struct zebra_vrf
*zvrf
= vrf
->info
;
3686 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
"\n",
3687 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3688 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3689 zvrf
->lsp_removals
);
3695 DEFUN (ip_forwarding
,
3699 "Turn on IP forwarding\n")
3705 ret
= ipforward_on();
3708 vty_out(vty
, "Can't turn on IP forwarding\n");
3709 return CMD_WARNING_CONFIG_FAILED
;
3715 DEFUN (no_ip_forwarding
,
3716 no_ip_forwarding_cmd
,
3720 "Turn off IP forwarding\n")
3726 ret
= ipforward_off();
3729 vty_out(vty
, "Can't turn off IP forwarding\n");
3730 return CMD_WARNING_CONFIG_FAILED
;
3736 /* Only display ip forwarding is enabled or not. */
3737 DEFUN (show_ip_forwarding
,
3738 show_ip_forwarding_cmd
,
3739 "show ip forwarding",
3742 "IP forwarding status\n")
3749 vty_out(vty
, "IP forwarding is off\n");
3751 vty_out(vty
, "IP forwarding is on\n");
3755 /* Only display ipv6 forwarding is enabled or not. */
3756 DEFUN (show_ipv6_forwarding
,
3757 show_ipv6_forwarding_cmd
,
3758 "show ipv6 forwarding",
3760 "IPv6 information\n"
3761 "Forwarding status\n")
3765 ret
= ipforward_ipv6();
3769 vty_out(vty
, "ipv6 forwarding is unknown\n");
3772 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3775 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3778 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3784 DEFUN (ipv6_forwarding
,
3785 ipv6_forwarding_cmd
,
3788 "Turn on IPv6 forwarding\n")
3792 ret
= ipforward_ipv6();
3794 ret
= ipforward_ipv6_on();
3797 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3798 return CMD_WARNING_CONFIG_FAILED
;
3804 DEFUN (no_ipv6_forwarding
,
3805 no_ipv6_forwarding_cmd
,
3806 "no ipv6 forwarding",
3809 "Turn off IPv6 forwarding\n")
3813 ret
= ipforward_ipv6();
3815 ret
= ipforward_ipv6_off();
3818 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3819 return CMD_WARNING_CONFIG_FAILED
;
3825 /* Display dataplane info */
3826 DEFUN (show_dataplane
,
3828 "show zebra dplane [detailed]",
3831 "Zebra dataplane information\n"
3832 "Detailed output\n")
3835 bool detailed
= false;
3837 if (argv_find(argv
, argc
, "detailed", &idx
))
3840 return dplane_show_helper(vty
, detailed
);
3843 /* Display dataplane providers info */
3844 DEFUN (show_dataplane_providers
,
3845 show_dataplane_providers_cmd
,
3846 "show zebra dplane providers [detailed]",
3849 "Zebra dataplane information\n"
3850 "Zebra dataplane provider information\n"
3851 "Detailed output\n")
3854 bool detailed
= false;
3856 if (argv_find(argv
, argc
, "detailed", &idx
))
3859 return dplane_show_provs_helper(vty
, detailed
);
3862 /* Configure dataplane incoming queue limit */
3863 DEFUN (zebra_dplane_queue_limit
,
3864 zebra_dplane_queue_limit_cmd
,
3865 "zebra dplane limit (0-10000)",
3868 "Limit incoming queued updates\n"
3869 "Number of queued updates\n")
3873 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3875 dplane_set_in_queue_limit(limit
, true);
3880 /* Reset dataplane queue limit to default value */
3881 DEFUN (no_zebra_dplane_queue_limit
,
3882 no_zebra_dplane_queue_limit_cmd
,
3883 "no zebra dplane limit [(0-10000)]",
3887 "Limit incoming queued updates\n"
3888 "Number of queued updates\n")
3890 dplane_set_in_queue_limit(0, false);
3895 DEFUN (zebra_show_routing_tables_summary
,
3896 zebra_show_routing_tables_summary_cmd
,
3897 "show zebra router table summary",
3900 "The Zebra Router Information\n"
3901 "Table Information about this Zebra Router\n"
3902 "Summary Information\n")
3904 zebra_router_show_table_summary(vty
);
3909 /* Table configuration write function. */
3910 static int config_write_table(struct vty
*vty
)
3915 /* IPForwarding configuration write function. */
3916 static int config_write_forwarding(struct vty
*vty
)
3919 vty_out(vty
, "no ip forwarding\n");
3920 if (!ipforward_ipv6())
3921 vty_out(vty
, "no ipv6 forwarding\n");
3922 vty_out(vty
, "!\n");
3926 DEFUN_HIDDEN (show_frr
,
3932 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3933 vty_out(vty
, ".............................7777:..............................................\n");
3934 vty_out(vty
, ".............................777777,............................................\n");
3935 vty_out(vty
, "... .........................77777777,..........................................\n");
3936 vty_out(vty
, "............................=7777777777:........................................\n");
3937 vty_out(vty
, "........................:7777777777777777,......................................\n");
3938 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3939 vty_out(vty
, "...................I7777777777+.................................................\n");
3940 vty_out(vty
, "................,777777777?............ .......................................\n");
3941 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3942 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3943 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3944 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3945 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3946 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3947 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3948 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3949 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3950 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3951 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3952 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3953 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3954 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3955 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3956 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3957 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3958 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3959 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3960 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3961 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3962 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3963 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3964 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3965 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3966 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3967 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3968 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3969 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3970 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3971 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3972 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3973 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3974 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3975 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3976 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3977 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3978 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3979 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3980 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3981 vty_out(vty
, "................................~77777777...............=777777.................\n");
3982 vty_out(vty
, ".....................................:=?I................~777777................\n");
3983 vty_out(vty
, "..........................................................:777777,..............\n");
3984 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3990 DEFUN_HIDDEN(zebra_kernel_netlink_batch_tx_buf
,
3991 zebra_kernel_netlink_batch_tx_buf_cmd
,
3992 "zebra kernel netlink batch-tx-buf (1-1048576) (1-1048576)",
3994 "Zebra kernel interface\n"
3995 "Set Netlink parameters\n"
3996 "Set batch buffer size and send threshold\n"
3997 "Size of the buffer\n"
4000 uint32_t bufsize
= 0, threshold
= 0;
4002 bufsize
= strtoul(argv
[4]->arg
, NULL
, 10);
4003 threshold
= strtoul(argv
[5]->arg
, NULL
, 10);
4005 netlink_set_batch_buffer_size(bufsize
, threshold
, true);
4010 DEFUN_HIDDEN(no_zebra_kernel_netlink_batch_tx_buf
,
4011 no_zebra_kernel_netlink_batch_tx_buf_cmd
,
4012 "no zebra kernel netlink batch-tx-buf [(0-1048576)] [(0-1048576)]",
4014 "Zebra kernel interface\n"
4015 "Set Netlink parameters\n"
4016 "Set batch buffer size and send threshold\n"
4017 "Size of the buffer\n"
4020 netlink_set_batch_buffer_size(0, 0, false);
4025 #endif /* HAVE_NETLINK */
4027 /* IP node for static routes. */
4028 static int zebra_ip_config(struct vty
*vty
);
4029 static struct cmd_node ip_node
= {
4030 .name
= "static ip",
4033 .config_write
= zebra_ip_config
,
4035 static int config_write_protocol(struct vty
*vty
);
4036 static struct cmd_node protocol_node
= {
4038 .node
= PROTOCOL_NODE
,
4040 .config_write
= config_write_protocol
,
4042 /* table node for routing tables. */
4043 static int config_write_table(struct vty
*vty
);
4044 static struct cmd_node table_node
= {
4048 .config_write
= config_write_table
,
4050 static int config_write_forwarding(struct vty
*vty
);
4051 static struct cmd_node forwarding_node
= {
4052 .name
= "forwarding",
4053 .node
= FORWARDING_NODE
,
4055 .config_write
= config_write_forwarding
,
4059 void zebra_vty_init(void)
4061 /* Install configuration write function. */
4062 install_node(&table_node
);
4063 install_node(&forwarding_node
);
4065 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
4066 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
4067 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
4068 install_element(ENABLE_NODE
, &show_zebra_cmd
);
4070 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
4071 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
4072 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
4075 zebra_route_map_init();
4077 install_node(&ip_node
);
4078 install_node(&protocol_node
);
4080 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
4081 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
4083 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
4084 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
4086 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
4087 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
4088 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
4089 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
4090 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
4091 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
4092 install_element(CONFIG_NODE
, &nexthop_group_use_enable_cmd
);
4093 install_element(CONFIG_NODE
, &proto_nexthop_group_only_cmd
);
4094 install_element(CONFIG_NODE
, &backup_nexthop_recursive_use_enable_cmd
);
4096 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
4097 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
4099 install_element(VIEW_NODE
, &show_vrf_cmd
);
4100 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
4101 install_element(VIEW_NODE
, &show_route_cmd
);
4102 install_element(VIEW_NODE
, &show_ro_cmd
);
4103 install_element(VIEW_NODE
, &show_route_detail_cmd
);
4104 install_element(VIEW_NODE
, &show_route_summary_cmd
);
4105 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
4107 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
4108 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
4110 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
4111 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
4112 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
4113 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
4114 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
4115 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
4116 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
4117 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
4118 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
4120 /* Commands for VRF */
4121 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
4123 install_element(VIEW_NODE
, &show_frr_cmd
);
4124 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
4125 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
4126 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
4127 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
4128 install_element(VIEW_NODE
, &show_evpn_l2_nh_cmd
);
4129 install_element(VIEW_NODE
, &show_evpn_es_cmd
);
4130 install_element(VIEW_NODE
, &show_evpn_es_evi_cmd
);
4131 install_element(VIEW_NODE
, &show_evpn_access_vlan_cmd
);
4132 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
4133 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
4134 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
4135 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
4136 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
4137 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
4138 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
4139 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
4140 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
4141 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
4142 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
4143 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
4144 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
4145 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
4146 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
4147 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
4148 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
4149 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
4150 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
4151 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
4152 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
4153 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
4155 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
4156 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
4158 install_element(CONFIG_NODE
, &evpn_mh_mac_holdtime_cmd
);
4159 install_element(CONFIG_NODE
, &evpn_mh_neigh_holdtime_cmd
);
4160 install_element(CONFIG_NODE
, &evpn_mh_startup_delay_cmd
);
4161 install_element(CONFIG_NODE
, &evpn_mh_redirect_off_cmd
);
4162 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
4163 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
4164 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
4165 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
4167 install_element(VIEW_NODE
, &show_dataplane_cmd
);
4168 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
4169 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
4170 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
4173 install_element(CONFIG_NODE
, &zebra_kernel_netlink_batch_tx_buf_cmd
);
4174 install_element(CONFIG_NODE
, &no_zebra_kernel_netlink_batch_tx_buf_cmd
);
4175 #endif /* HAVE_NETLINK */
4177 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);