2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "zebra_memory.h"
35 #include "srcdest_table.h"
38 #include "zebra/zebra_router.h"
39 #include "zebra/zserv.h"
40 #include "zebra/zebra_vrf.h"
41 #include "zebra/zebra_mpls.h"
42 #include "zebra/zebra_rnh.h"
43 #include "zebra/redistribute.h"
44 #include "zebra/zebra_routemap.h"
46 #include "zebra/zebra_vxlan.h"
47 #include "zebra/zebra_evpn_mh.h"
48 #ifndef VTYSH_EXTRACT_PL
49 #include "zebra/zebra_vty_clippy.c"
51 #include "zebra/zserv.h"
52 #include "zebra/router-id.h"
53 #include "zebra/ipforward.h"
54 #include "zebra/zebra_vxlan_private.h"
55 #include "zebra/zebra_pbr.h"
56 #include "zebra/zebra_nhg.h"
57 #include "zebra/zebra_evpn_mh.h"
58 #include "zebra/interface.h"
59 #include "northbound_cli.h"
60 #include "zebra/zebra_nb.h"
61 #include "zebra/kernel_netlink.h"
63 extern int allow_delete
;
65 /* context to manage dumps in multiple tables or vrfs */
66 struct route_show_ctx
{
67 bool multi
; /* dump multiple tables or vrf */
68 bool header_done
; /* common header already displayed */
71 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
72 safi_t safi
, bool use_fib
, bool use_json
,
74 const struct prefix
*longer_prefix_p
,
75 bool supernets_only
, int type
,
76 unsigned short ospf_instance_id
, uint32_t tableid
,
77 struct route_show_ctx
*ctx
);
78 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
79 int mcast
, bool use_fib
, bool show_ng
);
80 static void vty_show_ip_route_summary(struct vty
*vty
,
81 struct route_table
*table
, bool use_json
);
82 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
83 struct route_table
*table
,
85 /* Helper api to format a nexthop in the 'detailed' output path. */
86 static void show_nexthop_detail_helper(struct vty
*vty
,
87 const struct route_entry
*re
,
88 const struct nexthop
*nexthop
,
92 DEFUN (ip_multicast_mode
,
93 ip_multicast_mode_cmd
,
94 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
97 "RPF lookup behavior\n"
98 "Lookup in unicast RIB only\n"
99 "Lookup in multicast RIB only\n"
100 "Try multicast RIB first, fall back to unicast RIB\n"
101 "Lookup both, use entry with lower distance\n"
102 "Lookup both, use entry with longer prefix\n")
104 char *mode
= argv
[3]->text
;
106 if (strmatch(mode
, "urib-only"))
107 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
108 else if (strmatch(mode
, "mrib-only"))
109 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
110 else if (strmatch(mode
, "mrib-then-urib"))
111 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
112 else if (strmatch(mode
, "lower-distance"))
113 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
114 else if (strmatch(mode
, "longer-prefix"))
115 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
117 vty_out(vty
, "Invalid mode specified\n");
118 return CMD_WARNING_CONFIG_FAILED
;
124 DEFUN (no_ip_multicast_mode
,
125 no_ip_multicast_mode_cmd
,
126 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
129 "Multicast options\n"
130 "RPF lookup behavior\n"
131 "Lookup in unicast RIB only\n"
132 "Lookup in multicast RIB only\n"
133 "Try multicast RIB first, fall back to unicast RIB\n"
134 "Lookup both, use entry with lower distance\n"
135 "Lookup both, use entry with longer prefix\n")
137 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
144 "show ip rpf [json]",
147 "Display RPF information for multicast source\n"
150 bool uj
= use_json(argc
, argv
);
151 struct route_show_ctx ctx
= {
155 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
156 false, uj
, 0, NULL
, false, 0, 0, 0, &ctx
);
159 DEFUN (show_ip_rpf_addr
,
160 show_ip_rpf_addr_cmd
,
161 "show ip rpf A.B.C.D",
164 "Display RPF information for multicast source\n"
165 "IP multicast source address (e.g. 10.0.0.0)\n")
169 struct route_node
*rn
;
170 struct route_entry
*re
;
173 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
175 vty_out(vty
, "%% Malformed address\n");
179 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
182 vty_show_ip_route_detail(vty
, rn
, 1, false, false);
184 vty_out(vty
, "%% No match for RPF lookup\n");
189 static char re_status_output_char(const struct route_entry
*re
,
190 const struct nexthop
*nhop
,
193 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
197 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
198 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
)) {
199 /* More-specific test for 'fib' output */
201 star_p
= !!CHECK_FLAG(nhop
->flags
,
207 if (zrouter
.asic_offloaded
&&
208 CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
211 if (zrouter
.asic_offloaded
212 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
))
215 if (zrouter
.asic_offloaded
216 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
225 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
226 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
232 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
239 * Show backup nexthop info, in the 'detailed' output path
241 static void show_nh_backup_helper(struct vty
*vty
,
242 const struct route_entry
*re
,
243 const struct nexthop
*nexthop
)
245 const struct nexthop
*start
, *backup
, *temp
;
248 /* Double-check that there _is_ a backup */
249 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
) ||
250 re
->nhe
->backup_info
== NULL
|| re
->nhe
->backup_info
->nhe
== NULL
||
251 re
->nhe
->backup_info
->nhe
->nhg
.nexthop
== NULL
)
254 /* Locate the backup nexthop(s) */
255 start
= re
->nhe
->backup_info
->nhe
->nhg
.nexthop
;
256 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
257 /* Format the backup(s) (indented) */
259 for (idx
= 0; idx
< nexthop
->backup_idx
[i
]; idx
++) {
260 backup
= backup
->next
;
265 /* It's possible for backups to be recursive too,
266 * so walk the recursive resolution list if present.
271 show_nexthop_detail_helper(vty
, re
, backup
,
275 if (backup
->resolved
&& temp
== backup
)
276 backup
= backup
->resolved
;
278 backup
= nexthop_next(backup
);
280 if (backup
== temp
->next
)
288 * Helper api to format output for a nexthop, used in the 'detailed'
291 static void show_nexthop_detail_helper(struct vty
*vty
,
292 const struct route_entry
*re
,
293 const struct nexthop
*nexthop
,
297 char buf
[MPLS_LABEL_STRLEN
];
302 nexthop
->rparent
? " " : "");
304 vty_out(vty
, " %c%s",
305 re_status_output_char(re
, nexthop
, false),
306 nexthop
->rparent
? " " : "");
308 switch (nexthop
->type
) {
309 case NEXTHOP_TYPE_IPV4
:
310 case NEXTHOP_TYPE_IPV4_IFINDEX
:
311 vty_out(vty
, " %pI4",
312 &nexthop
->gate
.ipv4
);
313 if (nexthop
->ifindex
)
314 vty_out(vty
, ", via %s",
319 case NEXTHOP_TYPE_IPV6
:
320 case NEXTHOP_TYPE_IPV6_IFINDEX
:
322 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
324 if (nexthop
->ifindex
)
325 vty_out(vty
, ", via %s",
331 case NEXTHOP_TYPE_IFINDEX
:
332 vty_out(vty
, " directly connected, %s",
333 ifindex2ifname(nexthop
->ifindex
,
336 case NEXTHOP_TYPE_BLACKHOLE
:
337 vty_out(vty
, " unreachable");
338 switch (nexthop
->bh_type
) {
339 case BLACKHOLE_REJECT
:
340 vty_out(vty
, " (ICMP unreachable)");
342 case BLACKHOLE_ADMINPROHIB
:
344 " (ICMP admin-prohibited)");
347 vty_out(vty
, " (blackhole)");
349 case BLACKHOLE_UNSPEC
:
357 if ((re
->vrf_id
!= nexthop
->vrf_id
)
358 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
))
359 vty_out(vty
, "(vrf %s)", vrf_id_to_name(nexthop
->vrf_id
));
361 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
362 vty_out(vty
, " (duplicate nexthop removed)");
364 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
365 vty_out(vty
, " inactive");
367 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
368 vty_out(vty
, " onlink");
370 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
371 vty_out(vty
, " (recursive)");
373 /* Source specified? */
374 switch (nexthop
->type
) {
375 case NEXTHOP_TYPE_IPV4
:
376 case NEXTHOP_TYPE_IPV4_IFINDEX
:
377 if (nexthop
->src
.ipv4
.s_addr
) {
378 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
,
379 addrstr
, sizeof(addrstr
)))
380 vty_out(vty
, ", src %s",
385 case NEXTHOP_TYPE_IPV6
:
386 case NEXTHOP_TYPE_IPV6_IFINDEX
:
387 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
389 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
,
390 addrstr
, sizeof(addrstr
)))
391 vty_out(vty
, ", src %s",
401 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
403 /* Label information */
404 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
405 vty_out(vty
, ", label %s",
406 mpls_label2str(nexthop
->nh_label
->num_labels
,
407 nexthop
->nh_label
->label
, buf
,
408 sizeof(buf
), 1 /*pretty*/));
412 vty_out(vty
, ", weight %u", nexthop
->weight
);
414 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
415 vty_out(vty
, ", backup %d", nexthop
->backup_idx
[0]);
417 for (i
= 1; i
< nexthop
->backup_num
; i
++)
418 vty_out(vty
, ",%d", nexthop
->backup_idx
[i
]);
422 static void zebra_show_ip_route_opaque(struct vty
*vty
, struct route_entry
*re
,
423 struct json_object
*json
)
429 case ZEBRA_ROUTE_SHARP
:
431 json_object_string_add(json
, "opaque",
432 (char *)re
->opaque
->data
);
434 vty_out(vty
, " Opaque Data: %s",
435 (char *)re
->opaque
->data
);
437 case ZEBRA_ROUTE_BGP
:
439 json_object_string_add(json
, "asPath",
440 (char *)re
->opaque
->data
);
442 vty_out(vty
, " AS-Path: %s",
443 (char *)re
->opaque
->data
);
449 /* New RIB. Detailed information for IPv4 route. */
450 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
451 int mcast
, bool use_fib
, bool show_ng
)
453 struct route_entry
*re
;
454 struct nexthop
*nexthop
;
455 char buf
[SRCDEST2STR_BUFFER
];
456 struct zebra_vrf
*zvrf
;
459 dest
= rib_dest_from_rnode(rn
);
461 RNODE_FOREACH_RE (rn
, re
) {
463 * If re not selected for forwarding, skip re
464 * for "show ip/ipv6 fib <prefix>"
466 if (use_fib
&& re
!= dest
->selected_fib
)
469 const char *mcast_info
= "";
471 struct rib_table_info
*info
=
472 srcdest_rnode_table_info(rn
);
473 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
474 ? " using Multicast RIB"
475 : " using Unicast RIB";
478 vty_out(vty
, "Routing entry for %s%s\n",
479 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
480 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
482 vty_out(vty
, "[%d]", re
->instance
);
484 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
487 vty_out(vty
, ", tag %u", re
->tag
);
488 #if defined(SUPPORT_REALMS)
489 if (re
->tag
> 0 && re
->tag
<= 255)
490 vty_out(vty
, "(realm)");
494 vty_out(vty
, ", mtu %u", re
->mtu
);
495 if (re
->vrf_id
!= VRF_DEFAULT
) {
496 zvrf
= vrf_info_lookup(re
->vrf_id
);
497 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
499 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
500 vty_out(vty
, ", best");
505 uptime
= monotime(NULL
);
506 uptime
-= re
->uptime
;
508 frrtime_to_interval(uptime
, buf
, sizeof(buf
));
510 vty_out(vty
, " Last update %s ago\n", buf
);
513 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
515 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
)) {
516 /* Use helper to format each nexthop */
517 show_nexthop_detail_helper(vty
, re
, nexthop
,
518 false /*not backup*/);
521 /* Include backup(s), if present */
522 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
))
523 show_nh_backup_helper(vty
, re
, nexthop
);
525 zebra_show_ip_route_opaque(vty
, re
, NULL
);
532 * Helper for nexthop output, used in the 'show ip route' path
534 static void show_route_nexthop_helper(struct vty
*vty
,
535 const struct route_entry
*re
,
536 const struct nexthop
*nexthop
)
538 char buf
[MPLS_LABEL_STRLEN
];
541 switch (nexthop
->type
) {
542 case NEXTHOP_TYPE_IPV4
:
543 case NEXTHOP_TYPE_IPV4_IFINDEX
:
544 vty_out(vty
, " via %pI4", &nexthop
->gate
.ipv4
);
545 if (nexthop
->ifindex
)
547 ifindex2ifname(nexthop
->ifindex
,
550 case NEXTHOP_TYPE_IPV6
:
551 case NEXTHOP_TYPE_IPV6_IFINDEX
:
552 vty_out(vty
, " via %s",
553 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
555 if (nexthop
->ifindex
)
557 ifindex2ifname(nexthop
->ifindex
,
561 case NEXTHOP_TYPE_IFINDEX
:
562 vty_out(vty
, " is directly connected, %s",
563 ifindex2ifname(nexthop
->ifindex
,
566 case NEXTHOP_TYPE_BLACKHOLE
:
567 vty_out(vty
, " unreachable");
568 switch (nexthop
->bh_type
) {
569 case BLACKHOLE_REJECT
:
570 vty_out(vty
, " (ICMP unreachable)");
572 case BLACKHOLE_ADMINPROHIB
:
573 vty_out(vty
, " (ICMP admin-prohibited)");
576 vty_out(vty
, " (blackhole)");
578 case BLACKHOLE_UNSPEC
:
586 if ((re
== NULL
|| (nexthop
->vrf_id
!= re
->vrf_id
))
587 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
))
588 vty_out(vty
, " (vrf %s)", vrf_id_to_name(nexthop
->vrf_id
));
590 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
591 vty_out(vty
, " inactive");
593 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
594 vty_out(vty
, " onlink");
596 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
597 vty_out(vty
, " (recursive)");
599 switch (nexthop
->type
) {
600 case NEXTHOP_TYPE_IPV4
:
601 case NEXTHOP_TYPE_IPV4_IFINDEX
:
602 if (nexthop
->src
.ipv4
.s_addr
) {
603 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
605 vty_out(vty
, ", src %s", buf
);
606 /* SR-TE information */
607 if (nexthop
->srte_color
)
608 vty_out(vty
, ", SR-TE color %u",
609 nexthop
->srte_color
);
612 case NEXTHOP_TYPE_IPV6
:
613 case NEXTHOP_TYPE_IPV6_IFINDEX
:
614 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
615 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
617 vty_out(vty
, ", src %s", buf
);
624 /* Label information */
625 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
626 vty_out(vty
, ", label %s",
627 mpls_label2str(nexthop
->nh_label
->num_labels
,
628 nexthop
->nh_label
->label
, buf
,
633 vty_out(vty
, ", weight %u", nexthop
->weight
);
635 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
636 vty_out(vty
, ", backup %d", nexthop
->backup_idx
[0]);
638 for (i
= 1; i
< nexthop
->backup_num
; i
++)
639 vty_out(vty
, ",%d", nexthop
->backup_idx
[i
]);
644 * Render a nexthop into a json object; the caller allocates and owns
645 * the json object memory.
647 static void show_nexthop_json_helper(json_object
*json_nexthop
,
648 const struct nexthop
*nexthop
,
649 const struct route_entry
*re
)
651 char buf
[SRCDEST2STR_BUFFER
];
652 json_object
*json_labels
= NULL
;
653 json_object
*json_backups
= NULL
;
656 json_object_int_add(json_nexthop
, "flags",
659 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
660 json_object_boolean_true_add(json_nexthop
,
663 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
664 json_object_boolean_true_add(json_nexthop
,
667 switch (nexthop
->type
) {
668 case NEXTHOP_TYPE_IPV4
:
669 case NEXTHOP_TYPE_IPV4_IFINDEX
:
670 json_object_string_add(
672 inet_ntop(AF_INET
, &nexthop
->gate
.ipv4
,
674 json_object_string_add(json_nexthop
, "afi",
677 if (nexthop
->ifindex
) {
678 json_object_int_add(json_nexthop
,
681 json_object_string_add(
682 json_nexthop
, "interfaceName",
688 case NEXTHOP_TYPE_IPV6
:
689 case NEXTHOP_TYPE_IPV6_IFINDEX
:
690 json_object_string_add(
692 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
694 json_object_string_add(json_nexthop
, "afi",
697 if (nexthop
->ifindex
) {
698 json_object_int_add(json_nexthop
,
701 json_object_string_add(
702 json_nexthop
, "interfaceName",
709 case NEXTHOP_TYPE_IFINDEX
:
710 json_object_boolean_true_add(
711 json_nexthop
, "directlyConnected");
712 json_object_int_add(json_nexthop
,
715 json_object_string_add(
716 json_nexthop
, "interfaceName",
717 ifindex2ifname(nexthop
->ifindex
,
720 case NEXTHOP_TYPE_BLACKHOLE
:
721 json_object_boolean_true_add(json_nexthop
,
723 switch (nexthop
->bh_type
) {
724 case BLACKHOLE_REJECT
:
725 json_object_boolean_true_add(
726 json_nexthop
, "reject");
728 case BLACKHOLE_ADMINPROHIB
:
729 json_object_boolean_true_add(
734 json_object_boolean_true_add(
735 json_nexthop
, "blackhole");
737 case BLACKHOLE_UNSPEC
:
745 if ((nexthop
->vrf_id
!= re
->vrf_id
)
746 && (nexthop
->type
!= NEXTHOP_TYPE_BLACKHOLE
))
747 json_object_string_add(json_nexthop
, "vrf",
748 vrf_id_to_name(nexthop
->vrf_id
));
750 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
751 json_object_boolean_true_add(json_nexthop
,
754 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
755 json_object_boolean_true_add(json_nexthop
,
758 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
759 json_object_boolean_true_add(json_nexthop
,
762 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
763 json_object_boolean_true_add(json_nexthop
,
766 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
767 json_backups
= json_object_new_array();
768 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
769 json_object_array_add(
771 json_object_new_int(nexthop
->backup_idx
[i
]));
774 json_object_object_add(json_nexthop
, "backupIndex",
778 switch (nexthop
->type
) {
779 case NEXTHOP_TYPE_IPV4
:
780 case NEXTHOP_TYPE_IPV4_IFINDEX
:
781 if (nexthop
->src
.ipv4
.s_addr
) {
782 if (inet_ntop(AF_INET
,
783 &nexthop
->src
.ipv4
, buf
,
785 json_object_string_add(
786 json_nexthop
, "source",
790 case NEXTHOP_TYPE_IPV6
:
791 case NEXTHOP_TYPE_IPV6_IFINDEX
:
792 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
794 if (inet_ntop(AF_INET6
,
795 &nexthop
->src
.ipv6
, buf
,
797 json_object_string_add(
798 json_nexthop
, "source",
806 if (nexthop
->nh_label
807 && nexthop
->nh_label
->num_labels
) {
808 json_labels
= json_object_new_array();
810 for (int label_index
= 0;
812 < nexthop
->nh_label
->num_labels
;
814 json_object_array_add(
817 nexthop
->nh_label
->label
820 json_object_object_add(json_nexthop
, "labels",
825 json_object_int_add(json_nexthop
, "weight",
828 if (nexthop
->srte_color
)
829 json_object_int_add(json_nexthop
, "srteColor",
830 nexthop
->srte_color
);
833 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
834 struct route_entry
*re
, json_object
*json
,
837 const struct nexthop
*nexthop
;
839 char buf
[SRCDEST2STR_BUFFER
];
840 json_object
*json_nexthops
= NULL
;
841 json_object
*json_nexthop
= NULL
;
842 json_object
*json_route
= NULL
;
844 const rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
845 const struct nexthop_group
*nhg
;
846 char up_str
[MONOTIME_STRLEN
];
848 bool nhg_from_backup
= false;
850 uptime
= monotime(NULL
);
851 uptime
-= re
->uptime
;
853 frrtime_to_interval(uptime
, up_str
, sizeof(up_str
));
855 /* If showing fib information, use the fib view of the
859 nhg
= rib_get_fib_nhg(re
);
861 nhg
= &(re
->nhe
->nhg
);
864 json_route
= json_object_new_object();
865 json_nexthops
= json_object_new_array();
867 json_object_string_add(json_route
, "prefix",
868 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
869 json_object_string_add(json_route
, "protocol",
870 zebra_route_string(re
->type
));
873 json_object_int_add(json_route
, "instance",
876 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
877 json_object_string_add(json_route
, "vrfName",
878 vrf_id_to_name(re
->vrf_id
));
880 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
881 json_object_boolean_true_add(json_route
, "selected");
883 if (dest
->selected_fib
== re
)
884 json_object_boolean_true_add(json_route
,
887 json_object_int_add(json_route
, "distance",
889 json_object_int_add(json_route
, "metric", re
->metric
);
891 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
892 json_object_boolean_true_add(json_route
, "installed");
894 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
895 json_object_boolean_true_add(json_route
, "failed");
897 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
898 json_object_boolean_true_add(json_route
, "queued");
900 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
))
901 json_object_boolean_true_add(json_route
, "trapped");
903 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
))
904 json_object_boolean_true_add(json_route
, "offloaded");
906 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
907 json_object_boolean_false_add(json_route
, "offloaded");
910 json_object_int_add(json_route
, "tag", re
->tag
);
913 json_object_int_add(json_route
, "table", re
->table
);
915 json_object_int_add(json_route
, "internalStatus",
917 json_object_int_add(json_route
, "internalFlags",
919 json_object_int_add(json_route
, "internalNextHopNum",
920 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)));
921 json_object_int_add(json_route
, "internalNextHopActiveNum",
922 nexthop_group_active_nexthop_num(
925 json_object_string_add(json_route
, "uptime", up_str
);
927 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
928 json_nexthop
= json_object_new_object();
929 show_nexthop_json_helper(json_nexthop
,
932 json_object_array_add(json_nexthops
,
936 json_object_object_add(json_route
, "nexthops", json_nexthops
);
938 /* If there are backup nexthops, include them */
940 nhg
= rib_get_fib_backup_nhg(re
);
942 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
944 if (nhg
&& nhg
->nexthop
) {
945 json_nexthops
= json_object_new_array();
947 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
948 json_nexthop
= json_object_new_object();
950 show_nexthop_json_helper(json_nexthop
,
952 json_object_array_add(json_nexthops
,
956 json_object_object_add(json_route
, "backupNexthops",
959 zebra_show_ip_route_opaque(NULL
, re
, json_route
);
961 json_object_array_add(json
, json_route
);
965 /* Prefix information, and first nexthop. If we're showing 'fib',
966 * and there are no installed primary nexthops, see if there are any
967 * backup nexthops and start with those.
969 if (is_fib
&& nhg
->nexthop
== NULL
) {
970 nhg
= rib_get_fib_backup_nhg(re
);
971 nhg_from_backup
= true;
974 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
976 len
+= vty_out(vty
, "[%d]", re
->instance
);
977 if (nhg_from_backup
&& nhg
->nexthop
) {
980 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
) ? '>' : ' ',
981 re_status_output_char(re
, nhg
->nexthop
, is_fib
),
982 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
986 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
) ? '>' : ' ',
987 re_status_output_char(re
, nhg
->nexthop
, is_fib
),
988 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
991 /* Distance and metric display. */
992 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
993 (re
->distance
|| re
->metric
)) ||
994 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
995 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
998 /* Nexthop information. */
999 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1002 } else if (nhg_from_backup
) {
1003 vty_out(vty
, " b%c%*c",
1004 re_status_output_char(re
, nexthop
, is_fib
),
1005 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1007 vty_out(vty
, " %c%*c",
1008 re_status_output_char(re
, nexthop
, is_fib
),
1009 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1012 show_route_nexthop_helper(vty
, re
, nexthop
);
1013 vty_out(vty
, ", %s\n", up_str
);
1016 /* If we only had backup nexthops, we're done */
1017 if (nhg_from_backup
)
1020 /* Check for backup nexthop info if present */
1022 nhg
= rib_get_fib_backup_nhg(re
);
1024 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1029 /* Print backup info */
1030 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1031 bool star_p
= false;
1034 star_p
= CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1036 /* TODO -- it'd be nice to be able to include
1037 * the entire list of backups, *and* include the
1038 * real installation state.
1040 vty_out(vty
, " b%c %*c",
1041 (star_p
? '*' : ' '),
1042 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1043 show_route_nexthop_helper(vty
, re
, nexthop
);
1049 static void vty_show_ip_route_detail_json(struct vty
*vty
,
1050 struct route_node
*rn
, bool use_fib
)
1052 json_object
*json
= NULL
;
1053 json_object
*json_prefix
= NULL
;
1054 struct route_entry
*re
;
1058 dest
= rib_dest_from_rnode(rn
);
1060 json
= json_object_new_object();
1061 json_prefix
= json_object_new_array();
1063 RNODE_FOREACH_RE (rn
, re
) {
1065 * If re not selected for forwarding, skip re
1066 * for "show ip/ipv6 fib <prefix> json"
1068 if (use_fib
&& re
!= dest
->selected_fib
)
1070 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
1073 prefix2str(&rn
->p
, buf
, sizeof(buf
));
1074 json_object_object_add(json
, buf
, json_prefix
);
1075 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1076 json
, JSON_C_TO_STRING_PRETTY
));
1077 json_object_free(json
);
1080 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1081 struct route_table
*table
, afi_t afi
,
1082 bool use_fib
, route_tag_t tag
,
1083 const struct prefix
*longer_prefix_p
,
1084 bool supernets_only
, int type
,
1085 unsigned short ospf_instance_id
, bool use_json
,
1086 uint32_t tableid
, struct route_show_ctx
*ctx
)
1088 struct route_node
*rn
;
1089 struct route_entry
*re
;
1092 json_object
*json
= NULL
;
1093 json_object
*json_prefix
= NULL
;
1098 * ctx->multi indicates if we are dumping multiple tables or vrfs.
1100 * => display the common header at most once
1101 * => add newline at each call except first
1102 * => always display the VRF and table
1104 * => display the common header if at least one entry is found
1105 * => display the VRF and table if specific
1109 json
= json_object_new_object();
1111 /* Show all routes. */
1112 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
1113 dest
= rib_dest_from_rnode(rn
);
1115 RNODE_FOREACH_RE (rn
, re
) {
1116 if (use_fib
&& re
!= dest
->selected_fib
)
1119 if (tag
&& re
->tag
!= tag
)
1123 && !prefix_match(longer_prefix_p
, &rn
->p
))
1126 /* This can only be true when the afi is IPv4 */
1127 if (supernets_only
) {
1128 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1130 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1133 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1136 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1140 if (type
&& re
->type
!= type
)
1143 if (ospf_instance_id
1144 && (re
->type
!= ZEBRA_ROUTE_OSPF
1145 || re
->instance
!= ospf_instance_id
))
1150 json_prefix
= json_object_new_array();
1152 if (!ctx
->header_done
) {
1155 SHOW_ROUTE_V4_HEADER
);
1158 SHOW_ROUTE_V6_HEADER
);
1160 if (ctx
->multi
&& ctx
->header_done
)
1162 if (ctx
->multi
|| zvrf_id(zvrf
) != VRF_DEFAULT
1165 vty_out(vty
, "VRF %s:\n",
1169 "VRF %s table %u:\n",
1173 ctx
->header_done
= true;
1177 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
);
1181 prefix2str(&rn
->p
, buf
, sizeof(buf
));
1182 json_object_object_add(json
, buf
, json_prefix
);
1188 vty_out(vty
, "%s\n", json_object_to_json_string_ext(json
,
1189 JSON_C_TO_STRING_PRETTY
));
1190 json_object_free(json
);
1194 static void do_show_ip_route_all(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1195 afi_t afi
, bool use_fib
, bool use_json
,
1197 const struct prefix
*longer_prefix_p
,
1198 bool supernets_only
, int type
,
1199 unsigned short ospf_instance_id
,
1200 struct route_show_ctx
*ctx
)
1202 struct zebra_router_table
*zrt
;
1203 struct rib_table_info
*info
;
1205 RB_FOREACH (zrt
, zebra_router_table_head
,
1207 info
= route_table_get_info(zrt
->table
);
1209 if (zvrf
!= info
->zvrf
)
1211 if (zrt
->afi
!= afi
||
1212 zrt
->safi
!= SAFI_UNICAST
)
1215 do_show_ip_route(vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
,
1216 use_fib
, use_json
, tag
, longer_prefix_p
,
1217 supernets_only
, type
, ospf_instance_id
,
1222 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
1223 safi_t safi
, bool use_fib
, bool use_json
,
1225 const struct prefix
*longer_prefix_p
,
1226 bool supernets_only
, int type
,
1227 unsigned short ospf_instance_id
, uint32_t tableid
,
1228 struct route_show_ctx
*ctx
)
1230 struct route_table
*table
;
1231 struct zebra_vrf
*zvrf
= NULL
;
1233 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
1235 vty_out(vty
, "{}\n");
1237 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
1241 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
1243 vty_out(vty
, "{}\n");
1245 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
1250 table
= zebra_router_find_table(zvrf
, tableid
, afi
, SAFI_UNICAST
);
1252 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
1255 vty_out(vty
, "{}\n");
1259 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
1260 longer_prefix_p
, supernets_only
, type
,
1261 ospf_instance_id
, use_json
, tableid
, ctx
);
1268 "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]",
1272 "IP nexthop tracking table\n"
1273 "IP import check tracking table\n"
1279 VRF_ALL_CMD_HELP_STR
)
1281 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1282 vrf_id_t vrf_id
= VRF_DEFAULT
;
1283 struct prefix prefix
, *p
= NULL
;
1284 enum rnh_type rtype
;
1286 if (strcmp(type
, "nht") == 0)
1287 rtype
= RNH_NEXTHOP_TYPE
;
1289 rtype
= RNH_IMPORT_CHECK_TYPE
;
1293 struct zebra_vrf
*zvrf
;
1295 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1296 if ((zvrf
= vrf
->info
) != NULL
) {
1297 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1298 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, vty
,
1304 VRF_GET_ID(vrf_id
, vrf_name
, false);
1306 memset(&prefix
, 0, sizeof(prefix
));
1308 p
= sockunion2hostprefix(addr
, &prefix
);
1313 zebra_print_rnh_table(vrf_id
, afi
, vty
, rtype
, p
);
1317 DEFUN (ip_nht_default_route
,
1318 ip_nht_default_route_cmd
,
1319 "ip nht resolve-via-default",
1321 "Filter Next Hop tracking route resolution\n"
1322 "Resolve via default route\n")
1324 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1329 if (zvrf
->zebra_rnh_ip_default_route
)
1332 zvrf
->zebra_rnh_ip_default_route
= 1;
1334 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1338 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1340 struct nexthop
*nexthop
= NULL
;
1341 struct nhg_connected
*rb_node_dep
= NULL
;
1342 struct nexthop_group
*backup_nhg
;
1344 vty_out(vty
, "ID: %u (%s)\n", nhe
->id
, zebra_route_string(nhe
->type
));
1345 vty_out(vty
, " RefCnt: %d\n", nhe
->refcnt
);
1346 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(nhe
->vrf_id
));
1348 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1349 vty_out(vty
, " Valid");
1350 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1351 vty_out(vty
, ", Installed");
1355 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1357 if (!zebra_nhg_depends_is_empty(nhe
)) {
1358 vty_out(vty
, " Depends:");
1359 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1360 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1365 /* Output nexthops */
1366 for (ALL_NEXTHOPS(nhe
->nhg
, nexthop
)) {
1367 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1370 /* Make recursive nexthops a bit more clear */
1373 show_route_nexthop_helper(vty
, NULL
, nexthop
);
1375 if (nhe
->backup_info
== NULL
|| nhe
->backup_info
->nhe
== NULL
) {
1376 if (CHECK_FLAG(nexthop
->flags
,
1377 NEXTHOP_FLAG_HAS_BACKUP
))
1378 vty_out(vty
, " [backup %d]",
1379 nexthop
->backup_idx
[0]);
1385 /* TODO -- print more useful backup info */
1386 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
1389 vty_out(vty
, "[backup");
1390 for (i
= 0; i
< nexthop
->backup_num
; i
++)
1391 vty_out(vty
, " %d", nexthop
->backup_idx
[i
]);
1399 /* Output backup nexthops (if any) */
1400 backup_nhg
= zebra_nhg_get_backup_nhg(nhe
);
1402 vty_out(vty
, " Backups:\n");
1404 for (ALL_NEXTHOPS_PTR(backup_nhg
, nexthop
)) {
1405 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1408 /* Make recursive nexthops a bit more clear */
1411 show_route_nexthop_helper(vty
, NULL
, nexthop
);
1416 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1417 vty_out(vty
, " Dependents:");
1418 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1420 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1427 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1429 struct nhg_hash_entry
*nhe
= NULL
;
1431 nhe
= zebra_nhg_lookup_id(id
);
1434 show_nexthop_group_out(vty
, nhe
);
1436 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1442 /* Helper function for iteration through the hash of nexthop-groups/nhe-s */
1444 struct nhe_show_context
{
1451 static int nhe_show_walker(struct hash_bucket
*bucket
, void *arg
)
1453 struct nhe_show_context
*ctx
= arg
;
1454 struct nhg_hash_entry
*nhe
;
1456 nhe
= bucket
->data
; /* We won't be offered NULL buckets */
1458 if (ctx
->afi
&& nhe
->afi
!= ctx
->afi
)
1461 if (ctx
->vrf_id
&& nhe
->vrf_id
!= ctx
->vrf_id
)
1464 if (ctx
->type
&& nhe
->type
!= ctx
->type
)
1467 show_nexthop_group_out(ctx
->vty
, nhe
);
1470 return HASHWALK_CONTINUE
;
1473 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1474 struct zebra_vrf
*zvrf
, afi_t afi
,
1477 struct nhe_show_context ctx
;
1481 ctx
.vrf_id
= zvrf
->vrf
->vrf_id
;
1484 hash_walk(zrouter
.nhgs_id
, nhe_show_walker
, &ctx
);
1487 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1489 struct zebra_if
*zebra_if
= NULL
;
1490 struct nhg_connected
*rb_node_dep
= NULL
;
1492 zebra_if
= ifp
->info
;
1494 if (!if_nhg_dependents_is_empty(ifp
)) {
1495 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1497 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1500 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1505 DEFPY (show_interface_nexthop_group
,
1506 show_interface_nexthop_group_cmd
,
1507 "show interface [IFNAME$if_name] nexthop-group",
1509 "Interface status and configuration\n"
1511 "Show Nexthop Groups\n")
1513 struct vrf
*vrf
= NULL
;
1514 struct interface
*ifp
= NULL
;
1517 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1519 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1521 if_nexthop_group_dump_vty(vty
, ifp
);
1525 FOR_ALL_INTERFACES (vrf
, ifp
)
1526 if_nexthop_group_dump_vty(vty
, ifp
);
1532 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1539 DEFPY (show_nexthop_group
,
1540 show_nexthop_group_cmd
,
1541 "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>]>",
1543 "Show Nexthop Groups\n"
1545 "Nexthop Group ID\n"
1546 "Show Singleton Nexthop-Groups\n"
1549 "Kernel (not installed via the zebra RIB)\n"
1550 "Zebra (implicitly created by zebra)\n"
1551 "Border Gateway Protocol (BGP)\n"
1552 "Super Happy Advanced Routing Protocol (SHARP)\n"
1553 VRF_FULL_CMD_HELP_STR
)
1556 struct zebra_vrf
*zvrf
= NULL
;
1557 afi_t afi
= AFI_UNSPEC
;
1561 return show_nexthop_group_id_cmd_helper(vty
, id
);
1569 type
= proto_redistnum((afi
? afi
: AFI_IP
), type_str
);
1572 type
= ZEBRA_ROUTE_NHG
;
1576 if (!vrf_is_backend_netns() && (vrf_name
|| vrf_all
)) {
1578 "VRF subcommand does not make any sense in l3mdev based vrf's\n");
1585 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1586 struct zebra_vrf
*zvrf
;
1592 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1593 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
, type
);
1600 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1602 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1605 vty_out(vty
, "%% VRF '%s' specified does not exist\n",
1610 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
, type
);
1615 DEFPY_HIDDEN(nexthop_group_use_enable
,
1616 nexthop_group_use_enable_cmd
,
1617 "[no] zebra nexthop kernel enable",
1620 "Nexthop configuration \n"
1621 "Configure use of kernel nexthops\n"
1622 "Enable kernel nexthops\n")
1624 zebra_nhg_enable_kernel_nexthops(!no
);
1628 DEFPY_HIDDEN(proto_nexthop_group_only
, proto_nexthop_group_only_cmd
,
1629 "[no] zebra nexthop proto only",
1631 "Nexthop configuration\n"
1632 "Configure exclusive use of proto nexthops\n"
1633 "Only use proto nexthops\n")
1635 zebra_nhg_set_proto_nexthops_only(!no
);
1639 DEFUN (no_ip_nht_default_route
,
1640 no_ip_nht_default_route_cmd
,
1641 "no ip nht resolve-via-default",
1644 "Filter Next Hop tracking route resolution\n"
1645 "Resolve via default route\n")
1647 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1652 if (!zvrf
->zebra_rnh_ip_default_route
)
1655 zvrf
->zebra_rnh_ip_default_route
= 0;
1656 zebra_evaluate_rnh(zvrf
, AFI_IP
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1660 DEFUN (ipv6_nht_default_route
,
1661 ipv6_nht_default_route_cmd
,
1662 "ipv6 nht resolve-via-default",
1664 "Filter Next Hop tracking route resolution\n"
1665 "Resolve via default route\n")
1667 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1672 if (zvrf
->zebra_rnh_ipv6_default_route
)
1675 zvrf
->zebra_rnh_ipv6_default_route
= 1;
1676 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1680 DEFUN (no_ipv6_nht_default_route
,
1681 no_ipv6_nht_default_route_cmd
,
1682 "no ipv6 nht resolve-via-default",
1685 "Filter Next Hop tracking route resolution\n"
1686 "Resolve via default route\n")
1689 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1694 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1697 zvrf
->zebra_rnh_ipv6_default_route
= 0;
1698 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1706 ip$ipv4 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1707 [vrf <NAME$vrf_name|all$vrf_all>]\
1710 |A.B.C.D/M$prefix longer-prefixes\
1711 |supernets-only$supernets_only\
1714 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1715 |ospf$type_str (1-65535)$ospf_instance_id\
1717 |ipv6$ipv6 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1718 [vrf <NAME$vrf_name|all$vrf_all>]\
1721 |X:X::X:X/M$prefix longer-prefixes\
1723 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1728 "IP forwarding table\n"
1729 "IP routing table\n"
1730 "Table to display\n"
1731 "The table number to display\n"
1733 VRF_FULL_CMD_HELP_STR
1734 "Show only routes with tag\n"
1736 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1737 "Show route matching the specified Network/Mask pair only\n"
1738 "Show supernet entries only\n"
1739 FRR_IP_REDIST_HELP_STR_ZEBRA
1740 "Open Shortest Path First (OSPFv2)\n"
1743 "IP forwarding table\n"
1744 "IP routing table\n"
1745 "Table to display\n"
1746 "The table number to display\n"
1748 VRF_FULL_CMD_HELP_STR
1749 "Show only routes with tag\n"
1752 "Show route matching the specified Network/Mask pair only\n"
1753 FRR_IP6_REDIST_HELP_STR_ZEBRA
1756 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1759 struct zebra_vrf
*zvrf
;
1760 struct route_show_ctx ctx
= {
1761 .multi
= vrf_all
|| table_all
,
1764 if (!vrf_is_backend_netns()) {
1765 if ((vrf_all
|| vrf_name
) && (table
|| table_all
)) {
1767 vty_out(vty
, "{}\n");
1769 vty_out(vty
, "Linux vrf backend already points to table id\n");
1770 vty_out(vty
, "Either remove table parameter or vrf parameter\n");
1776 type
= proto_redistnum(afi
, type_str
);
1778 vty_out(vty
, "Unknown route type\n");
1784 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1785 if ((zvrf
= vrf
->info
) == NULL
1786 || (zvrf
->table
[afi
][SAFI_UNICAST
] == NULL
))
1790 do_show_ip_route_all(vty
, zvrf
, afi
, !!fib
,
1792 prefix_str
? prefix
: NULL
,
1793 !!supernets_only
, type
,
1794 ospf_instance_id
, &ctx
);
1796 do_show_ip_route(vty
, zvrf_name(zvrf
), afi
,
1797 SAFI_UNICAST
, !!fib
, !!json
,
1799 prefix_str
? prefix
: NULL
,
1800 !!supernets_only
, type
,
1801 ospf_instance_id
, table
, &ctx
);
1804 vrf_id_t vrf_id
= VRF_DEFAULT
;
1807 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1808 vrf
= vrf_lookup_by_id(vrf_id
);
1817 do_show_ip_route_all(vty
, zvrf
, afi
, !!fib
, !!json
, tag
,
1818 prefix_str
? prefix
: NULL
,
1819 !!supernets_only
, type
,
1820 ospf_instance_id
, &ctx
);
1822 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
,
1824 prefix_str
? prefix
: NULL
,
1825 !!supernets_only
, type
,
1826 ospf_instance_id
, table
, &ctx
);
1832 ALIAS_HIDDEN (show_route
,
1834 "show <ip$ipv4|ipv6$ipv6> ro",
1838 "IP routing table\n");
1841 DEFPY (show_route_detail
,
1842 show_route_detail_cmd
,
1845 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1850 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1856 [json$json] [nexthop-group$ng]",
1859 "IPv6 forwarding table\n"
1860 "IP routing table\n"
1861 VRF_FULL_CMD_HELP_STR
1862 "Network in the IP routing table to display\n"
1863 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1865 "IPv6 forwarding table\n"
1866 "IPv6 routing table\n"
1867 VRF_FULL_CMD_HELP_STR
1871 "Nexthop Group Information\n")
1873 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1874 struct route_table
*table
;
1876 struct route_node
*rn
;
1877 bool use_fib
= !!fib
;
1879 bool network_found
= false;
1880 bool show_ng
= !!ng
;
1883 prefix_str
= address_str
;
1884 if (str2prefix(prefix_str
, &p
) < 0) {
1885 vty_out(vty
, "%% Malformed address\n");
1891 struct zebra_vrf
*zvrf
;
1893 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1894 if ((zvrf
= vrf
->info
) == NULL
1895 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1898 rn
= route_node_match(table
, &p
);
1901 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1902 route_unlock_node(rn
);
1906 dest
= rib_dest_from_rnode(rn
);
1907 if (use_fib
&& !dest
->selected_fib
) {
1908 route_unlock_node(rn
);
1912 network_found
= true;
1914 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1916 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
1919 route_unlock_node(rn
);
1922 if (!network_found
) {
1924 vty_out(vty
, "{}\n");
1928 "%% Network not in FIB\n");
1931 "%% Network not in RIB\n");
1936 vrf_id_t vrf_id
= VRF_DEFAULT
;
1939 VRF_GET_ID(vrf_id
, vrf_name
, false);
1941 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1945 rn
= route_node_match(table
, &p
);
1947 dest
= rib_dest_from_rnode(rn
);
1949 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
1950 (use_fib
&& dest
&& !dest
->selected_fib
)) {
1952 vty_out(vty
, "{}\n");
1956 "%% Network not in FIB\n");
1959 "%% Network not in table\n");
1962 route_unlock_node(rn
);
1967 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
1969 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
1971 route_unlock_node(rn
);
1977 DEFPY (show_route_summary
,
1978 show_route_summary_cmd
,
1979 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
1980 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
1984 "IP routing table\n"
1985 VRF_FULL_CMD_HELP_STR
1986 "Summary of all routes\n"
1987 "Table to display summary for\n"
1988 "The table number\n"
1992 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1993 struct route_table
*table
;
1994 bool uj
= use_json(argc
, argv
);
1998 struct zebra_vrf
*zvrf
;
2000 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2001 if ((zvrf
= vrf
->info
) == NULL
)
2005 table
= zebra_vrf_table(afi
, SAFI_UNICAST
,
2008 table
= zebra_vrf_lookup_table_with_table_id(
2009 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
,
2016 vty_show_ip_route_summary_prefix(vty
, table
,
2019 vty_show_ip_route_summary(vty
, table
, uj
);
2022 vrf_id_t vrf_id
= VRF_DEFAULT
;
2025 VRF_GET_ID(vrf_id
, vrf_name
, false);
2028 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
2030 table
= zebra_vrf_lookup_table_with_table_id(
2031 afi
, SAFI_UNICAST
, vrf_id
, table_id
);
2036 vty_show_ip_route_summary_prefix(vty
, table
, uj
);
2038 vty_show_ip_route_summary(vty
, table
, uj
);
2044 static void vty_show_ip_route_summary(struct vty
*vty
,
2045 struct route_table
*table
, bool use_json
)
2047 struct route_node
*rn
;
2048 struct route_entry
*re
;
2049 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2050 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
2051 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2052 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2053 uint32_t offload_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2054 uint32_t trap_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2057 json_object
*json_route_summary
= NULL
;
2058 json_object
*json_route_routes
= NULL
;
2060 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
2061 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
2062 memset(&offload_cnt
, 0, sizeof(offload_cnt
));
2063 memset(&trap_cnt
, 0, sizeof(trap_cnt
));
2066 json_route_summary
= json_object_new_object();
2067 json_route_routes
= json_object_new_array();
2068 json_object_object_add(json_route_summary
, "routes",
2072 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2073 RNODE_FOREACH_RE (rn
, re
) {
2074 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
2075 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
2077 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2079 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2081 rib_cnt
[re
->type
]++;
2083 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
2084 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2087 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2089 fib_cnt
[re
->type
]++;
2092 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
)) {
2094 trap_cnt
[ZEBRA_ROUTE_IBGP
]++;
2096 trap_cnt
[re
->type
]++;
2099 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
)) {
2101 offload_cnt
[ZEBRA_ROUTE_IBGP
]++;
2103 offload_cnt
[re
->type
]++;
2108 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2110 zvrf_name(((struct rib_table_info
*)
2111 route_table_get_info(table
))
2114 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
2115 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
2116 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
2117 if (i
== ZEBRA_ROUTE_BGP
) {
2119 json_object
*json_route_ebgp
=
2120 json_object_new_object();
2122 json_object_int_add(
2123 json_route_ebgp
, "fib",
2124 fib_cnt
[ZEBRA_ROUTE_BGP
]);
2125 json_object_int_add(
2126 json_route_ebgp
, "rib",
2127 rib_cnt
[ZEBRA_ROUTE_BGP
]);
2128 json_object_int_add(
2129 json_route_ebgp
, "fibOffLoaded",
2130 offload_cnt
[ZEBRA_ROUTE_BGP
]);
2131 json_object_int_add(
2132 json_route_ebgp
, "fibTrapped",
2133 trap_cnt
[ZEBRA_ROUTE_BGP
]);
2135 json_object_string_add(json_route_ebgp
,
2137 json_object_array_add(json_route_routes
,
2140 json_object
*json_route_ibgp
=
2141 json_object_new_object();
2143 json_object_int_add(
2144 json_route_ibgp
, "fib",
2145 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2146 json_object_int_add(
2147 json_route_ibgp
, "rib",
2148 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2149 json_object_int_add(
2150 json_route_ibgp
, "fibOffLoaded",
2151 offload_cnt
[ZEBRA_ROUTE_IBGP
]);
2152 json_object_int_add(
2153 json_route_ibgp
, "fibTrapped",
2154 trap_cnt
[ZEBRA_ROUTE_IBGP
]);
2155 json_object_string_add(json_route_ibgp
,
2157 json_object_array_add(json_route_routes
,
2160 vty_out(vty
, "%-20s %-20d %-20d \n",
2162 rib_cnt
[ZEBRA_ROUTE_BGP
],
2163 fib_cnt
[ZEBRA_ROUTE_BGP
]);
2164 vty_out(vty
, "%-20s %-20d %-20d \n",
2166 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2167 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2171 json_object
*json_route_type
=
2172 json_object_new_object();
2174 json_object_int_add(json_route_type
,
2176 json_object_int_add(json_route_type
,
2179 json_object_int_add(json_route_type
,
2182 json_object_int_add(json_route_type
,
2185 json_object_string_add(
2186 json_route_type
, "type",
2187 zebra_route_string(i
));
2188 json_object_array_add(json_route_routes
,
2191 vty_out(vty
, "%-20s %-20d %-20d \n",
2192 zebra_route_string(i
),
2193 rib_cnt
[i
], fib_cnt
[i
]);
2199 json_object_int_add(json_route_summary
, "routesTotal",
2200 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2201 json_object_int_add(json_route_summary
, "routesTotalFib",
2202 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2204 vty_out(vty
, "%s\n",
2205 json_object_to_json_string_ext(
2206 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2207 json_object_free(json_route_summary
);
2209 vty_out(vty
, "------\n");
2210 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2211 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2217 * Implementation of the ip route summary prefix command.
2219 * This command prints the primary prefixes that have been installed by various
2220 * protocols on the box.
2223 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
2224 struct route_table
*table
,
2227 struct route_node
*rn
;
2228 struct route_entry
*re
;
2229 struct nexthop
*nexthop
;
2230 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2231 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
2232 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2233 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2236 json_object
*json_route_summary
= NULL
;
2237 json_object
*json_route_routes
= NULL
;
2239 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
2240 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
2243 json_route_summary
= json_object_new_object();
2244 json_route_routes
= json_object_new_array();
2245 json_object_object_add(json_route_summary
, "prefixRoutes",
2249 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2250 RNODE_FOREACH_RE (rn
, re
) {
2253 * In case of ECMP, count only once.
2256 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
2257 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2258 fib_cnt
[re
->type
]++;
2260 for (nexthop
= re
->nhe
->nhg
.nexthop
; (!cnt
&& nexthop
);
2261 nexthop
= nexthop
->next
) {
2263 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2264 rib_cnt
[re
->type
]++;
2265 if (re
->type
== ZEBRA_ROUTE_BGP
2266 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
2267 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2268 if (CHECK_FLAG(re
->status
,
2269 ROUTE_ENTRY_INSTALLED
))
2270 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2276 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2277 "Prefix Routes", "FIB",
2278 zvrf_name(((struct rib_table_info
*)
2279 route_table_get_info(table
))
2282 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
2283 if (rib_cnt
[i
] > 0) {
2284 if (i
== ZEBRA_ROUTE_BGP
) {
2286 json_object
*json_route_ebgp
=
2287 json_object_new_object();
2289 json_object_int_add(
2290 json_route_ebgp
, "fib",
2291 fib_cnt
[ZEBRA_ROUTE_BGP
]
2292 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2293 json_object_int_add(
2294 json_route_ebgp
, "rib",
2295 rib_cnt
[ZEBRA_ROUTE_BGP
]
2296 - rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2297 json_object_string_add(json_route_ebgp
,
2299 json_object_array_add(json_route_routes
,
2302 json_object
*json_route_ibgp
=
2303 json_object_new_object();
2305 json_object_int_add(
2306 json_route_ibgp
, "fib",
2307 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2308 json_object_int_add(
2309 json_route_ibgp
, "rib",
2310 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2311 json_object_string_add(json_route_ibgp
,
2313 json_object_array_add(json_route_routes
,
2316 vty_out(vty
, "%-20s %-20d %-20d \n",
2318 rib_cnt
[ZEBRA_ROUTE_BGP
]
2319 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
2320 fib_cnt
[ZEBRA_ROUTE_BGP
]
2321 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2322 vty_out(vty
, "%-20s %-20d %-20d \n",
2324 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2325 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2329 json_object
*json_route_type
=
2330 json_object_new_object();
2332 json_object_int_add(json_route_type
,
2334 json_object_int_add(json_route_type
,
2336 json_object_string_add(
2337 json_route_type
, "type",
2338 zebra_route_string(i
));
2339 json_object_array_add(json_route_routes
,
2342 vty_out(vty
, "%-20s %-20d %-20d \n",
2343 zebra_route_string(i
),
2344 rib_cnt
[i
], fib_cnt
[i
]);
2350 json_object_int_add(json_route_summary
, "prefixRoutesTotal",
2351 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2352 json_object_int_add(json_route_summary
, "prefixRoutesTotalFib",
2353 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2355 vty_out(vty
, "%s\n",
2356 json_object_to_json_string_ext(
2357 json_route_summary
, JSON_C_TO_STRING_PRETTY
));
2358 json_object_free(json_route_summary
);
2360 vty_out(vty
, "------\n");
2361 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2362 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2368 * Show IPv6 mroute command.Used to dump
2369 * the Multicast routing table.
2371 DEFUN (show_ipv6_mroute
,
2372 show_ipv6_mroute_cmd
,
2373 "show ipv6 mroute [vrf NAME]",
2376 "IPv6 Multicast routing table\n"
2379 struct route_table
*table
;
2380 struct route_node
*rn
;
2381 struct route_entry
*re
;
2383 vrf_id_t vrf_id
= VRF_DEFAULT
;
2386 VRF_GET_ID(vrf_id
, argv
[4]->arg
, false);
2388 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2392 /* Show all IPv6 route. */
2393 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2394 RNODE_FOREACH_RE (rn
, re
) {
2396 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2399 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2404 DEFUN (show_ipv6_mroute_vrf_all
,
2405 show_ipv6_mroute_vrf_all_cmd
,
2406 "show ipv6 mroute vrf all",
2409 "IPv6 Multicast routing table\n"
2410 VRF_ALL_CMD_HELP_STR
)
2412 struct route_table
*table
;
2413 struct route_node
*rn
;
2414 struct route_entry
*re
;
2416 struct zebra_vrf
*zvrf
;
2419 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2420 if ((zvrf
= vrf
->info
) == NULL
2421 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2424 /* Show all IPv6 route. */
2425 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2426 RNODE_FOREACH_RE (rn
, re
) {
2428 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2431 vty_show_ip_route(vty
, rn
, re
, NULL
, false);
2437 DEFUN (allow_external_route_update
,
2438 allow_external_route_update_cmd
,
2439 "allow-external-route-update",
2440 "Allow FRR routes to be overwritten by external processes\n")
2447 DEFUN (no_allow_external_route_update
,
2448 no_allow_external_route_update_cmd
,
2449 "no allow-external-route-update",
2451 "Allow FRR routes to be overwritten by external processes\n")
2466 struct zebra_vrf
*zvrf
;
2468 if (vrf_is_backend_netns())
2469 vty_out(vty
, "netns-based vrfs\n");
2471 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2472 if (!(zvrf
= vrf
->info
))
2474 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2477 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2478 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
2479 vty_out(vty
, "inactive");
2480 else if (zvrf_ns_name(zvrf
))
2481 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2482 zvrf_ns_name(zvrf
));
2484 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2486 if (vrf_is_user_cfged(vrf
))
2487 vty_out(vty
, " (configured)");
2494 DEFPY (evpn_mh_mac_holdtime
,
2495 evpn_mh_mac_holdtime_cmd
,
2496 "[no$no] evpn mh mac-holdtime (0-86400)$duration",
2501 "Duration in seconds\n")
2503 return zebra_evpn_mh_mac_holdtime_update(vty
, duration
,
2507 DEFPY (evpn_mh_neigh_holdtime
,
2508 evpn_mh_neigh_holdtime_cmd
,
2509 "[no$no] evpn mh neigh-holdtime (0-86400)$duration",
2513 "Neighbor entry hold time\n"
2514 "Duration in seconds\n")
2517 return zebra_evpn_mh_neigh_holdtime_update(vty
, duration
,
2521 DEFPY (evpn_mh_startup_delay
,
2522 evpn_mh_startup_delay_cmd
,
2523 "[no] evpn mh startup-delay(0-3600)$duration",
2528 "duration in seconds\n")
2531 return zebra_evpn_mh_startup_delay_update(vty
, duration
,
2535 DEFPY(evpn_mh_redirect_off
, evpn_mh_redirect_off_cmd
,
2536 "[no$no] evpn mh redirect-off",
2540 "ES bond redirect for fast-failover off\n")
2544 redirect_off
= no
? false : true;
2546 return zebra_evpn_mh_redirect_off(vty
, redirect_off
);
2549 DEFUN (default_vrf_vni_mapping
,
2550 default_vrf_vni_mapping_cmd
,
2551 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2552 "VNI corresponding to the DEFAULT VRF\n"
2554 "Prefix routes only \n")
2557 char err
[ERR_STR_SZ
];
2558 struct zebra_vrf
*zvrf
= NULL
;
2559 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2562 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2569 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2572 vty_out(vty
, "%s\n", err
);
2579 DEFUN (no_default_vrf_vni_mapping
,
2580 no_default_vrf_vni_mapping_cmd
,
2581 "no vni " CMD_VNI_RANGE
,
2583 "VNI corresponding to DEFAULT VRF\n"
2587 char err
[ERR_STR_SZ
];
2588 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2589 struct zebra_vrf
*zvrf
= NULL
;
2591 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2595 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2597 vty_out(vty
, "%s\n", err
);
2604 DEFUN (vrf_vni_mapping
,
2605 vrf_vni_mapping_cmd
,
2606 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2607 "VNI corresponding to tenant VRF\n"
2609 "prefix-routes-only\n")
2613 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2621 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra", NB_OP_CREATE
, NULL
);
2622 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY
,
2626 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/prefix-only",
2627 NB_OP_MODIFY
, "true");
2629 nb_cli_apply_changes(vty
, NULL
);
2634 DEFUN (no_vrf_vni_mapping
,
2635 no_vrf_vni_mapping_cmd
,
2636 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2638 "VNI corresponding to tenant VRF\n"
2640 "prefix-routes-only\n")
2644 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2645 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2653 if (zvrf
->l3vni
!= vni
) {
2654 vty_out(vty
, "VNI %d doesn't exist in VRF: %s \n", vni
,
2659 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY
,
2663 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/prefix-only",
2664 NB_OP_DESTROY
, "true");
2666 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra", NB_OP_DESTROY
, NULL
);
2668 nb_cli_apply_changes(vty
, NULL
);
2674 DEFUN (show_vrf_vni
,
2676 "show vrf vni [json]",
2683 struct zebra_vrf
*zvrf
;
2684 json_object
*json
= NULL
;
2685 json_object
*json_vrfs
= NULL
;
2686 bool uj
= use_json(argc
, argv
);
2689 json
= json_object_new_object();
2690 json_vrfs
= json_object_new_array();
2694 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2695 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2697 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2702 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2706 json_object_object_add(json
, "vrfs", json_vrfs
);
2707 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2708 json
, JSON_C_TO_STRING_PRETTY
));
2709 json_object_free(json
);
2715 DEFUN (show_evpn_global
,
2716 show_evpn_global_cmd
,
2722 bool uj
= use_json(argc
, argv
);
2724 zebra_vxlan_print_evpn(vty
, uj
);
2728 DEFPY(show_evpn_l2_nh
,
2729 show_evpn_l2_nh_cmd
,
2730 "show evpn l2-nh [json$json]",
2738 zebra_evpn_l2_nh_show(vty
, uj
);
2745 "show evpn es [NAME$esi_str|detail$detail] [json$json]",
2748 "Ethernet Segment\n"
2750 "Detailed information\n"
2757 if (!str_to_esi(esi_str
, &esi
)) {
2758 vty_out(vty
, "%% Malformed ESI\n");
2761 zebra_evpn_es_show_esi(vty
, uj
, &esi
);
2764 zebra_evpn_es_show_detail(vty
, uj
);
2766 zebra_evpn_es_show(vty
, uj
);
2772 DEFPY(show_evpn_es_evi
,
2773 show_evpn_es_evi_cmd
,
2774 "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]",
2777 "Ethernet Segment per EVI\n"
2778 "VxLAN Network Identifier\n"
2780 "Detailed information\n"
2787 zebra_evpn_es_evi_show_vni(vty
, uj
, vni
, ud
);
2789 zebra_evpn_es_evi_show(vty
, uj
, ud
);
2794 DEFPY(show_evpn_access_vlan
,
2795 show_evpn_access_vlan_cmd
,
2796 "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]",
2801 "Detailed information\n"
2807 zebra_evpn_acc_vl_show_vid(vty
, uj
, vid
);
2810 zebra_evpn_acc_vl_show_detail(vty
, uj
);
2812 zebra_evpn_acc_vl_show(vty
, uj
);
2818 DEFUN (show_evpn_vni
,
2820 "show evpn vni [json]",
2823 "VxLAN Network Identifier\n"
2826 struct zebra_vrf
*zvrf
;
2827 bool uj
= use_json(argc
, argv
);
2829 zvrf
= zebra_vrf_get_evpn();
2830 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2834 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
2835 "show evpn vni detail [json]",
2838 "VxLAN Network Identifier\n"
2839 "Detailed Information On Each VNI\n"
2842 struct zebra_vrf
*zvrf
;
2843 bool uj
= use_json(argc
, argv
);
2845 zvrf
= zebra_vrf_get_evpn();
2846 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
2850 DEFUN (show_evpn_vni_vni
,
2851 show_evpn_vni_vni_cmd
,
2852 "show evpn vni " CMD_VNI_RANGE
"[json]",
2855 "VxLAN Network Identifier\n"
2859 struct zebra_vrf
*zvrf
;
2861 bool uj
= use_json(argc
, argv
);
2863 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2864 zvrf
= zebra_vrf_get_evpn();
2865 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
2869 DEFUN (show_evpn_rmac_vni_mac
,
2870 show_evpn_rmac_vni_mac_cmd
,
2871 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2878 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2883 bool uj
= use_json(argc
, argv
);
2885 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2886 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2887 vty_out(vty
, "%% Malformed MAC address\n");
2890 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2894 DEFUN (show_evpn_rmac_vni
,
2895 show_evpn_rmac_vni_cmd
,
2896 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2905 bool uj
= use_json(argc
, argv
);
2907 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2908 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2913 DEFUN (show_evpn_rmac_vni_all
,
2914 show_evpn_rmac_vni_all_cmd
,
2915 "show evpn rmac vni all [json]",
2923 bool uj
= use_json(argc
, argv
);
2925 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2930 DEFUN (show_evpn_nh_vni_ip
,
2931 show_evpn_nh_vni_ip_cmd
,
2932 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2939 "Host address (ipv4 or ipv6)\n"
2944 bool uj
= use_json(argc
, argv
);
2946 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2947 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2949 vty_out(vty
, "%% Malformed Neighbor address\n");
2952 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2957 DEFUN (show_evpn_nh_vni
,
2958 show_evpn_nh_vni_cmd
,
2959 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2968 bool uj
= use_json(argc
, argv
);
2970 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2971 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2976 DEFUN (show_evpn_nh_vni_all
,
2977 show_evpn_nh_vni_all_cmd
,
2978 "show evpn next-hops vni all [json]",
2986 bool uj
= use_json(argc
, argv
);
2988 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2993 DEFUN (show_evpn_mac_vni
,
2994 show_evpn_mac_vni_cmd
,
2995 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2999 "VxLAN Network Identifier\n"
3003 struct zebra_vrf
*zvrf
;
3005 bool uj
= use_json(argc
, argv
);
3007 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3008 zvrf
= zebra_vrf_get_evpn();
3009 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
3013 DEFUN (show_evpn_mac_vni_all
,
3014 show_evpn_mac_vni_all_cmd
,
3015 "show evpn mac vni all [json]",
3019 "VxLAN Network Identifier\n"
3023 struct zebra_vrf
*zvrf
;
3024 bool uj
= use_json(argc
, argv
);
3026 zvrf
= zebra_vrf_get_evpn();
3027 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
3031 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
3032 "show evpn mac vni all detail [json]",
3036 "VxLAN Network Identifier\n"
3038 "Detailed Information On Each VNI MAC\n"
3041 struct zebra_vrf
*zvrf
;
3042 bool uj
= use_json(argc
, argv
);
3044 zvrf
= zebra_vrf_get_evpn();
3045 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
3049 DEFUN (show_evpn_mac_vni_all_vtep
,
3050 show_evpn_mac_vni_all_vtep_cmd
,
3051 "show evpn mac vni all vtep A.B.C.D [json]",
3055 "VxLAN Network Identifier\n"
3058 "Remote VTEP IP address\n"
3061 struct zebra_vrf
*zvrf
;
3062 struct in_addr vtep_ip
;
3063 bool uj
= use_json(argc
, argv
);
3065 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3067 vty_out(vty
, "%% Malformed VTEP IP address\n");
3070 zvrf
= zebra_vrf_get_evpn();
3071 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
3077 DEFUN (show_evpn_mac_vni_mac
,
3078 show_evpn_mac_vni_mac_cmd
,
3079 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
3083 "VxLAN Network Identifier\n"
3086 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3090 struct zebra_vrf
*zvrf
;
3093 bool uj
= use_json(argc
, argv
);
3095 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3096 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
3097 vty_out(vty
, "%% Malformed MAC address");
3100 zvrf
= zebra_vrf_get_evpn();
3101 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
3105 DEFUN (show_evpn_mac_vni_vtep
,
3106 show_evpn_mac_vni_vtep_cmd
,
3107 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
3111 "VxLAN Network Identifier\n"
3114 "Remote VTEP IP address\n"
3117 struct zebra_vrf
*zvrf
;
3119 struct in_addr vtep_ip
;
3120 bool uj
= use_json(argc
, argv
);
3122 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3123 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3125 vty_out(vty
, "%% Malformed VTEP IP address\n");
3129 zvrf
= zebra_vrf_get_evpn();
3130 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
3134 DEFPY (show_evpn_mac_vni_all_dad
,
3135 show_evpn_mac_vni_all_dad_cmd
,
3136 "show evpn mac vni all duplicate [json]",
3140 "VxLAN Network Identifier\n"
3142 "Duplicate address list\n"
3145 struct zebra_vrf
*zvrf
;
3146 bool uj
= use_json(argc
, argv
);
3148 zvrf
= zebra_vrf_get_evpn();
3149 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
3154 DEFPY (show_evpn_mac_vni_dad
,
3155 show_evpn_mac_vni_dad_cmd
,
3156 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
3160 "VxLAN Network Identifier\n"
3162 "Duplicate address list\n"
3165 struct zebra_vrf
*zvrf
;
3166 bool uj
= use_json(argc
, argv
);
3168 zvrf
= zebra_vrf_get_evpn();
3170 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
3175 DEFPY (show_evpn_neigh_vni_dad
,
3176 show_evpn_neigh_vni_dad_cmd
,
3177 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
3180 "ARP and ND cache\n"
3181 "VxLAN Network Identifier\n"
3183 "Duplicate address list\n"
3186 struct zebra_vrf
*zvrf
;
3187 bool uj
= use_json(argc
, argv
);
3189 zvrf
= zebra_vrf_get_evpn();
3190 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
3194 DEFPY (show_evpn_neigh_vni_all_dad
,
3195 show_evpn_neigh_vni_all_dad_cmd
,
3196 "show evpn arp-cache vni all duplicate [json]",
3199 "ARP and ND cache\n"
3200 "VxLAN Network Identifier\n"
3202 "Duplicate address list\n"
3205 struct zebra_vrf
*zvrf
;
3206 bool uj
= use_json(argc
, argv
);
3208 zvrf
= zebra_vrf_get_evpn();
3209 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
3214 DEFUN (show_evpn_neigh_vni
,
3215 show_evpn_neigh_vni_cmd
,
3216 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
3219 "ARP and ND cache\n"
3220 "VxLAN Network Identifier\n"
3224 struct zebra_vrf
*zvrf
;
3226 bool uj
= use_json(argc
, argv
);
3228 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3229 zvrf
= zebra_vrf_get_evpn();
3230 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
3234 DEFUN (show_evpn_neigh_vni_all
,
3235 show_evpn_neigh_vni_all_cmd
,
3236 "show evpn arp-cache vni all [json]",
3239 "ARP and ND cache\n"
3240 "VxLAN Network Identifier\n"
3244 struct zebra_vrf
*zvrf
;
3245 bool uj
= use_json(argc
, argv
);
3247 zvrf
= zebra_vrf_get_evpn();
3248 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
3252 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
3253 "show evpn arp-cache vni all detail [json]",
3256 "ARP and ND cache\n"
3257 "VxLAN Network Identifier\n"
3259 "Neighbor details for all vnis in detail\n" JSON_STR
)
3261 struct zebra_vrf
*zvrf
;
3262 bool uj
= use_json(argc
, argv
);
3264 zvrf
= zebra_vrf_get_evpn();
3265 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
3269 DEFUN (show_evpn_neigh_vni_neigh
,
3270 show_evpn_neigh_vni_neigh_cmd
,
3271 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
3274 "ARP and ND cache\n"
3275 "VxLAN Network Identifier\n"
3278 "Neighbor address (IPv4 or IPv6 address)\n"
3281 struct zebra_vrf
*zvrf
;
3284 bool uj
= use_json(argc
, argv
);
3286 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3287 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
3289 vty_out(vty
, "%% Malformed Neighbor address\n");
3292 zvrf
= zebra_vrf_get_evpn();
3293 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
3297 DEFUN (show_evpn_neigh_vni_vtep
,
3298 show_evpn_neigh_vni_vtep_cmd
,
3299 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
3302 "ARP and ND cache\n"
3303 "VxLAN Network Identifier\n"
3306 "Remote VTEP IP address\n"
3309 struct zebra_vrf
*zvrf
;
3311 struct in_addr vtep_ip
;
3312 bool uj
= use_json(argc
, argv
);
3314 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3315 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3317 vty_out(vty
, "%% Malformed VTEP IP address\n");
3321 zvrf
= zebra_vrf_get_evpn();
3322 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
3326 /* policy routing contexts */
3327 DEFUN (show_pbr_ipset
,
3329 "show pbr ipset [WORD]",
3331 "Policy-Based Routing\n"
3332 "IPset Context information\n"
3333 "IPset Name information\n")
3337 found
= argv_find(argv
, argc
, "WORD", &idx
);
3339 zebra_pbr_show_ipset_list(vty
, NULL
);
3341 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
3345 /* policy routing contexts */
3346 DEFUN (show_pbr_iptable
,
3347 show_pbr_iptable_cmd
,
3348 "show pbr iptable [WORD]",
3350 "Policy-Based Routing\n"
3351 "IPtable Context information\n"
3352 "IPtable Name information\n")
3357 found
= argv_find(argv
, argc
, "WORD", &idx
);
3359 zebra_pbr_show_iptable(vty
, NULL
);
3361 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
3365 DEFPY (clear_evpn_dup_addr
,
3366 clear_evpn_dup_addr_cmd
,
3367 "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>]>",
3370 "Duplicate address \n"
3371 "VxLAN Network Identifier\n"
3375 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3380 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
3381 int ret
= CMD_SUCCESS
;
3383 struct yang_data
*yang_dup
= NULL
, *yang_dup_ip
= NULL
,
3384 *yang_dup_mac
= NULL
;
3389 yang_dup
= yang_data_new(
3390 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice",
3393 yang_dup
= yang_data_new_uint32(
3394 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id",
3396 if (!is_zero_mac(&mac
->eth_addr
)) {
3397 yang_dup_mac
= yang_data_new_mac(
3398 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr",
3401 listnode_add(input
, yang_dup_mac
);
3403 if (sockunion_family(ip
) == AF_INET
) {
3404 host_ip
.ipa_type
= IPADDR_V4
;
3405 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
3407 host_ip
.ipa_type
= IPADDR_V6
;
3408 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
3409 sizeof(struct in6_addr
));
3412 yang_dup_ip
= yang_data_new_ip(
3413 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr",
3417 listnode_add(input
, yang_dup_ip
);
3422 listnode_add(input
, yang_dup
);
3423 ret
= nb_cli_rpc(vty
, "/frr-zebra:clear-evpn-dup-addr", input
,
3427 list_delete(&input
);
3432 /* Static ip route configuration write function. */
3433 static int zebra_ip_config(struct vty
*vty
)
3437 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
3442 DEFUN (ip_zebra_import_table_distance
,
3443 ip_zebra_import_table_distance_cmd
,
3444 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
3446 "import routes from non-main kernel table\n"
3447 "kernel routing table id\n"
3448 "Distance for imported routes\n"
3449 "Default distance value\n"
3450 "route-map for filtering\n"
3453 uint32_t table_id
= 0;
3455 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
3456 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
3458 strmatch(argv
[argc
- 2]->text
, "route-map")
3459 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
3463 if (argc
== 7 || (argc
== 5 && !rmap
))
3464 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
3466 if (!is_zebra_valid_kernel_table(table_id
)) {
3468 "Invalid routing table ID, %d. Must be in range 1-252\n",
3471 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3475 if (is_zebra_main_routing_table(table_id
)) {
3477 "Invalid routing table ID, %d. Must be non-default table\n",
3480 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3484 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
3487 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3492 DEFUN_HIDDEN (zebra_packet_process
,
3493 zebra_packet_process_cmd
,
3494 "zebra zapi-packets (1-10000)",
3497 "Number of packets to process before relinquishing thread\n")
3499 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3501 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
3502 memory_order_relaxed
);
3507 DEFUN_HIDDEN (no_zebra_packet_process
,
3508 no_zebra_packet_process_cmd
,
3509 "no zebra zapi-packets [(1-10000)]",
3513 "Number of packets to process before relinquishing thread\n")
3515 atomic_store_explicit(&zrouter
.packets_to_process
,
3516 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
3517 memory_order_relaxed
);
3522 DEFUN_HIDDEN (zebra_workqueue_timer
,
3523 zebra_workqueue_timer_cmd
,
3524 "zebra work-queue (0-10000)",
3527 "Time in milliseconds\n")
3529 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3530 zrouter
.ribq
->spec
.hold
= timer
;
3535 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3536 no_zebra_workqueue_timer_cmd
,
3537 "no zebra work-queue [(0-10000)]",
3541 "Time in milliseconds\n")
3543 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3548 DEFUN (no_ip_zebra_import_table
,
3549 no_ip_zebra_import_table_cmd
,
3550 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3553 "import routes from non-main kernel table\n"
3554 "kernel routing table id\n"
3555 "Distance for imported routes\n"
3556 "Default distance value\n"
3557 "route-map for filtering\n"
3560 uint32_t table_id
= 0;
3561 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3563 if (!is_zebra_valid_kernel_table(table_id
)) {
3565 "Invalid routing table ID. Must be in range 1-252\n");
3569 if (is_zebra_main_routing_table(table_id
)) {
3571 "Invalid routing table ID, %d. Must be non-default table\n",
3576 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
3579 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
3582 static int config_write_protocol(struct vty
*vty
)
3585 vty_out(vty
, "allow-external-route-update\n");
3587 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3588 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
3590 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3591 vty_out(vty
, "zebra zapi-packets %u\n",
3592 zrouter
.packets_to_process
);
3594 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3596 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3597 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3598 ipv4_multicast_mode
== MCAST_URIB_ONLY
3600 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3602 : ipv4_multicast_mode
3603 == MCAST_MIX_MRIB_FIRST
3605 : ipv4_multicast_mode
3606 == MCAST_MIX_DISTANCE
3610 /* Include dataplane info */
3611 dplane_config_write_helper(vty
);
3613 zebra_evpn_mh_config_write(vty
);
3615 /* Include nexthop-group config */
3616 if (!zebra_nhg_kernel_nexthops_enabled())
3617 vty_out(vty
, "no zebra nexthop kernel enable\n");
3619 if (zebra_nhg_proto_nexthops_only())
3620 vty_out(vty
, "zebra nexthop proto only\n");
3623 /* Include netlink info */
3624 netlink_config_write_helper(vty
);
3625 #endif /* HAVE_NETLINK */
3638 if (zrouter
.asic_offloaded
)
3639 vty_out(vty
, "Asic Offload is being used\n");
3642 " Route Route Neighbor LSP LSP\n");
3644 "VRF Installs Removals Updates Installs Removals\n");
3646 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
3647 struct zebra_vrf
*zvrf
= vrf
->info
;
3649 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
"\n",
3650 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3651 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3652 zvrf
->lsp_removals
);
3658 DEFUN (ip_forwarding
,
3662 "Turn on IP forwarding\n")
3668 ret
= ipforward_on();
3671 vty_out(vty
, "Can't turn on IP forwarding\n");
3672 return CMD_WARNING_CONFIG_FAILED
;
3678 DEFUN (no_ip_forwarding
,
3679 no_ip_forwarding_cmd
,
3683 "Turn off IP forwarding\n")
3689 ret
= ipforward_off();
3692 vty_out(vty
, "Can't turn off IP forwarding\n");
3693 return CMD_WARNING_CONFIG_FAILED
;
3699 /* Only display ip forwarding is enabled or not. */
3700 DEFUN (show_ip_forwarding
,
3701 show_ip_forwarding_cmd
,
3702 "show ip forwarding",
3705 "IP forwarding status\n")
3712 vty_out(vty
, "IP forwarding is off\n");
3714 vty_out(vty
, "IP forwarding is on\n");
3718 /* Only display ipv6 forwarding is enabled or not. */
3719 DEFUN (show_ipv6_forwarding
,
3720 show_ipv6_forwarding_cmd
,
3721 "show ipv6 forwarding",
3723 "IPv6 information\n"
3724 "Forwarding status\n")
3728 ret
= ipforward_ipv6();
3732 vty_out(vty
, "ipv6 forwarding is unknown\n");
3735 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3738 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3741 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3747 DEFUN (ipv6_forwarding
,
3748 ipv6_forwarding_cmd
,
3751 "Turn on IPv6 forwarding\n")
3755 ret
= ipforward_ipv6();
3757 ret
= ipforward_ipv6_on();
3760 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3761 return CMD_WARNING_CONFIG_FAILED
;
3767 DEFUN (no_ipv6_forwarding
,
3768 no_ipv6_forwarding_cmd
,
3769 "no ipv6 forwarding",
3772 "Turn off IPv6 forwarding\n")
3776 ret
= ipforward_ipv6();
3778 ret
= ipforward_ipv6_off();
3781 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3782 return CMD_WARNING_CONFIG_FAILED
;
3788 /* Display dataplane info */
3789 DEFUN (show_dataplane
,
3791 "show zebra dplane [detailed]",
3794 "Zebra dataplane information\n"
3795 "Detailed output\n")
3798 bool detailed
= false;
3800 if (argv_find(argv
, argc
, "detailed", &idx
))
3803 return dplane_show_helper(vty
, detailed
);
3806 /* Display dataplane providers info */
3807 DEFUN (show_dataplane_providers
,
3808 show_dataplane_providers_cmd
,
3809 "show zebra dplane providers [detailed]",
3812 "Zebra dataplane information\n"
3813 "Zebra dataplane provider information\n"
3814 "Detailed output\n")
3817 bool detailed
= false;
3819 if (argv_find(argv
, argc
, "detailed", &idx
))
3822 return dplane_show_provs_helper(vty
, detailed
);
3825 /* Configure dataplane incoming queue limit */
3826 DEFUN (zebra_dplane_queue_limit
,
3827 zebra_dplane_queue_limit_cmd
,
3828 "zebra dplane limit (0-10000)",
3831 "Limit incoming queued updates\n"
3832 "Number of queued updates\n")
3836 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
3838 dplane_set_in_queue_limit(limit
, true);
3843 /* Reset dataplane queue limit to default value */
3844 DEFUN (no_zebra_dplane_queue_limit
,
3845 no_zebra_dplane_queue_limit_cmd
,
3846 "no zebra dplane limit [(0-10000)]",
3850 "Limit incoming queued updates\n"
3851 "Number of queued updates\n")
3853 dplane_set_in_queue_limit(0, false);
3858 DEFUN (zebra_show_routing_tables_summary
,
3859 zebra_show_routing_tables_summary_cmd
,
3860 "show zebra router table summary",
3863 "The Zebra Router Information\n"
3864 "Table Information about this Zebra Router\n"
3865 "Summary Information\n")
3867 zebra_router_show_table_summary(vty
);
3872 /* Table configuration write function. */
3873 static int config_write_table(struct vty
*vty
)
3878 /* IPForwarding configuration write function. */
3879 static int config_write_forwarding(struct vty
*vty
)
3882 vty_out(vty
, "no ip forwarding\n");
3883 if (!ipforward_ipv6())
3884 vty_out(vty
, "no ipv6 forwarding\n");
3885 vty_out(vty
, "!\n");
3889 DEFUN_HIDDEN (show_frr
,
3895 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
3896 vty_out(vty
, ".............................7777:..............................................\n");
3897 vty_out(vty
, ".............................777777,............................................\n");
3898 vty_out(vty
, "... .........................77777777,..........................................\n");
3899 vty_out(vty
, "............................=7777777777:........................................\n");
3900 vty_out(vty
, "........................:7777777777777777,......................................\n");
3901 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
3902 vty_out(vty
, "...................I7777777777+.................................................\n");
3903 vty_out(vty
, "................,777777777?............ .......................................\n");
3904 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
3905 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
3906 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
3907 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
3908 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
3909 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
3910 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
3911 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
3912 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
3913 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
3914 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
3915 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
3916 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
3917 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
3918 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
3919 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
3920 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
3921 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
3922 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
3923 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
3924 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
3925 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
3926 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
3927 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
3928 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
3929 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
3930 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
3931 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
3932 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
3933 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
3934 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
3935 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
3936 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
3937 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
3938 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
3939 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
3940 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
3941 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
3942 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
3943 vty_out(vty
, "............................~777777777777..............+777777..................\n");
3944 vty_out(vty
, "................................~77777777...............=777777.................\n");
3945 vty_out(vty
, ".....................................:=?I................~777777................\n");
3946 vty_out(vty
, "..........................................................:777777,..............\n");
3947 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
3953 DEFUN_HIDDEN(zebra_kernel_netlink_batch_tx_buf
,
3954 zebra_kernel_netlink_batch_tx_buf_cmd
,
3955 "zebra kernel netlink batch-tx-buf (1-1048576) (1-1048576)",
3957 "Zebra kernel interface\n"
3958 "Set Netlink parameters\n"
3959 "Set batch buffer size and send threshold\n"
3960 "Size of the buffer\n"
3963 uint32_t bufsize
= 0, threshold
= 0;
3965 bufsize
= strtoul(argv
[4]->arg
, NULL
, 10);
3966 threshold
= strtoul(argv
[5]->arg
, NULL
, 10);
3968 netlink_set_batch_buffer_size(bufsize
, threshold
, true);
3973 DEFUN_HIDDEN(no_zebra_kernel_netlink_batch_tx_buf
,
3974 no_zebra_kernel_netlink_batch_tx_buf_cmd
,
3975 "no zebra kernel netlink batch-tx-buf [(0-1048576)] [(0-1048576)]",
3977 "Zebra kernel interface\n"
3978 "Set Netlink parameters\n"
3979 "Set batch buffer size and send threshold\n"
3980 "Size of the buffer\n"
3983 netlink_set_batch_buffer_size(0, 0, false);
3988 #endif /* HAVE_NETLINK */
3990 /* IP node for static routes. */
3991 static int zebra_ip_config(struct vty
*vty
);
3992 static struct cmd_node ip_node
= {
3993 .name
= "static ip",
3996 .config_write
= zebra_ip_config
,
3998 static int config_write_protocol(struct vty
*vty
);
3999 static struct cmd_node protocol_node
= {
4001 .node
= PROTOCOL_NODE
,
4003 .config_write
= config_write_protocol
,
4005 /* table node for routing tables. */
4006 static int config_write_table(struct vty
*vty
);
4007 static struct cmd_node table_node
= {
4011 .config_write
= config_write_table
,
4013 static int config_write_forwarding(struct vty
*vty
);
4014 static struct cmd_node forwarding_node
= {
4015 .name
= "forwarding",
4016 .node
= FORWARDING_NODE
,
4018 .config_write
= config_write_forwarding
,
4022 void zebra_vty_init(void)
4024 /* Install configuration write function. */
4025 install_node(&table_node
);
4026 install_node(&forwarding_node
);
4028 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
4029 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
4030 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
4031 install_element(ENABLE_NODE
, &show_zebra_cmd
);
4033 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
4034 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
4035 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
4038 zebra_route_map_init();
4040 install_node(&ip_node
);
4041 install_node(&protocol_node
);
4043 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
4044 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
4046 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
4047 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
4049 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
4050 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
4051 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
4052 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
4053 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
4054 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
4055 install_element(CONFIG_NODE
, &nexthop_group_use_enable_cmd
);
4056 install_element(CONFIG_NODE
, &proto_nexthop_group_only_cmd
);
4058 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
4059 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
4061 install_element(VIEW_NODE
, &show_vrf_cmd
);
4062 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
4063 install_element(VIEW_NODE
, &show_route_cmd
);
4064 install_element(VIEW_NODE
, &show_ro_cmd
);
4065 install_element(VIEW_NODE
, &show_route_detail_cmd
);
4066 install_element(VIEW_NODE
, &show_route_summary_cmd
);
4067 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
4069 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
4070 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
4072 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
4073 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
4074 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
4075 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
4076 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
4077 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
4078 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
4079 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
4080 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
4082 /* Commands for VRF */
4083 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
4085 install_element(VIEW_NODE
, &show_frr_cmd
);
4086 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
4087 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
4088 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
4089 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
4090 install_element(VIEW_NODE
, &show_evpn_l2_nh_cmd
);
4091 install_element(VIEW_NODE
, &show_evpn_es_cmd
);
4092 install_element(VIEW_NODE
, &show_evpn_es_evi_cmd
);
4093 install_element(VIEW_NODE
, &show_evpn_access_vlan_cmd
);
4094 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
4095 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
4096 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
4097 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
4098 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
4099 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
4100 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
4101 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
4102 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
4103 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
4104 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
4105 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
4106 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
4107 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
4108 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
4109 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
4110 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
4111 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
4112 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
4113 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
4114 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
4115 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
4117 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
4118 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
4120 install_element(CONFIG_NODE
, &evpn_mh_mac_holdtime_cmd
);
4121 install_element(CONFIG_NODE
, &evpn_mh_neigh_holdtime_cmd
);
4122 install_element(CONFIG_NODE
, &evpn_mh_startup_delay_cmd
);
4123 install_element(CONFIG_NODE
, &evpn_mh_redirect_off_cmd
);
4124 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
4125 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
4126 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
4127 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
4129 install_element(VIEW_NODE
, &show_dataplane_cmd
);
4130 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
4131 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
4132 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
4135 install_element(CONFIG_NODE
, &zebra_kernel_netlink_batch_tx_buf_cmd
);
4136 install_element(CONFIG_NODE
, &no_zebra_kernel_netlink_batch_tx_buf_cmd
);
4137 #endif /* HAVE_NETLINK */
4139 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);