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"
36 #include "termtable.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 "lib/route_opaque.h"
47 #include "zebra/zebra_vxlan.h"
48 #include "zebra/zebra_evpn_mh.h"
49 #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"
61 #include "zebra/if_netlink.h"
62 #include "zebra/table_manager.h"
63 #include "zebra/zebra_script.h"
64 #include "zebra/rtadv.h"
65 #include "zebra/zebra_neigh.h"
67 /* context to manage dumps in multiple tables or vrfs */
68 struct route_show_ctx
{
69 bool multi
; /* dump multiple tables or vrf */
70 bool header_done
; /* common header already displayed */
73 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
74 safi_t safi
, bool use_fib
, bool use_json
,
76 const struct prefix
*longer_prefix_p
,
77 bool supernets_only
, int type
,
78 unsigned short ospf_instance_id
, uint32_t tableid
,
79 bool show_ng
, struct route_show_ctx
*ctx
);
80 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
81 int mcast
, bool use_fib
, bool show_ng
);
82 static void vty_show_ip_route_summary(struct vty
*vty
,
83 struct route_table
*table
, bool use_json
);
84 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
85 struct route_table
*table
,
87 /* Helper api to format a nexthop in the 'detailed' output path. */
88 static void show_nexthop_detail_helper(struct vty
*vty
,
89 const struct route_entry
*re
,
90 const struct nexthop
*nexthop
,
93 static void show_ip_route_dump_vty(struct vty
*vty
, struct route_table
*table
);
94 static void show_ip_route_nht_dump(struct vty
*vty
, struct nexthop
*nexthop
,
95 struct route_entry
*re
, unsigned int num
);
97 DEFUN (ip_multicast_mode
,
98 ip_multicast_mode_cmd
,
99 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
101 "Multicast options\n"
102 "RPF lookup behavior\n"
103 "Lookup in unicast RIB only\n"
104 "Lookup in multicast RIB only\n"
105 "Try multicast RIB first, fall back to unicast RIB\n"
106 "Lookup both, use entry with lower distance\n"
107 "Lookup both, use entry with longer prefix\n")
109 char *mode
= argv
[3]->text
;
111 if (strmatch(mode
, "urib-only"))
112 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
113 else if (strmatch(mode
, "mrib-only"))
114 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
115 else if (strmatch(mode
, "mrib-then-urib"))
116 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
117 else if (strmatch(mode
, "lower-distance"))
118 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
119 else if (strmatch(mode
, "longer-prefix"))
120 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
122 vty_out(vty
, "Invalid mode specified\n");
123 return CMD_WARNING_CONFIG_FAILED
;
129 DEFUN (no_ip_multicast_mode
,
130 no_ip_multicast_mode_cmd
,
131 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
134 "Multicast options\n"
135 "RPF lookup behavior\n"
136 "Lookup in unicast RIB only\n"
137 "Lookup in multicast RIB only\n"
138 "Try multicast RIB first, fall back to unicast RIB\n"
139 "Lookup both, use entry with lower distance\n"
140 "Lookup both, use entry with longer prefix\n")
142 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
149 "show ip rpf [json]",
152 "Display RPF information for multicast source\n"
155 bool uj
= use_json(argc
, argv
);
156 struct route_show_ctx ctx
= {
160 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
161 false, uj
, 0, NULL
, false, 0, 0, 0, false,
165 DEFUN (show_ip_rpf_addr
,
166 show_ip_rpf_addr_cmd
,
167 "show ip rpf A.B.C.D",
170 "Display RPF information for multicast source\n"
171 "IP multicast source address (e.g. 10.0.0.0)\n")
175 struct route_node
*rn
;
176 struct route_entry
*re
;
179 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
181 vty_out(vty
, "%% Malformed address\n");
185 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
188 vty_show_ip_route_detail(vty
, rn
, 1, false, false);
190 vty_out(vty
, "%% No match for RPF lookup\n");
195 static char re_status_output_char(const struct route_entry
*re
,
196 const struct nexthop
*nhop
,
199 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
203 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_DUPLICATE
) &&
204 !CHECK_FLAG(nhop
->flags
, NEXTHOP_FLAG_RECURSIVE
)) {
205 /* More-specific test for 'fib' output */
207 star_p
= !!CHECK_FLAG(nhop
->flags
,
213 if (zrouter
.asic_offloaded
&&
214 CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
217 if (zrouter
.asic_offloaded
218 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
))
221 if (zrouter
.asic_offloaded
222 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
225 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OUTOFSYNC
))
234 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
)) {
235 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
241 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
248 * Show backup nexthop info, in the 'detailed' output path
250 static void show_nh_backup_helper(struct vty
*vty
,
251 const struct route_entry
*re
,
252 const struct nexthop
*nexthop
)
254 const struct nexthop
*start
, *backup
, *temp
;
257 /* Double-check that there _is_ a backup */
258 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
) ||
259 re
->nhe
->backup_info
== NULL
|| re
->nhe
->backup_info
->nhe
== NULL
||
260 re
->nhe
->backup_info
->nhe
->nhg
.nexthop
== NULL
)
263 /* Locate the backup nexthop(s) */
264 start
= re
->nhe
->backup_info
->nhe
->nhg
.nexthop
;
265 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
266 /* Format the backup(s) (indented) */
268 for (idx
= 0; idx
< nexthop
->backup_idx
[i
]; idx
++) {
269 backup
= backup
->next
;
274 /* It's possible for backups to be recursive too,
275 * so walk the recursive resolution list if present.
280 show_nexthop_detail_helper(vty
, re
, backup
,
284 if (backup
->resolved
&& temp
== backup
)
285 backup
= backup
->resolved
;
287 backup
= nexthop_next(backup
);
289 if (backup
== temp
->next
)
297 * Helper api to format output for a nexthop, used in the 'detailed'
300 static void show_nexthop_detail_helper(struct vty
*vty
,
301 const struct route_entry
*re
,
302 const struct nexthop
*nexthop
,
306 char buf
[MPLS_LABEL_STRLEN
];
311 nexthop
->rparent
? " " : "");
313 vty_out(vty
, " %c%s",
314 re_status_output_char(re
, nexthop
, false),
315 nexthop
->rparent
? " " : "");
317 switch (nexthop
->type
) {
318 case NEXTHOP_TYPE_IPV4
:
319 case NEXTHOP_TYPE_IPV4_IFINDEX
:
320 vty_out(vty
, " %pI4",
321 &nexthop
->gate
.ipv4
);
322 if (nexthop
->ifindex
)
323 vty_out(vty
, ", via %s",
328 case NEXTHOP_TYPE_IPV6
:
329 case NEXTHOP_TYPE_IPV6_IFINDEX
:
331 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
333 if (nexthop
->ifindex
)
334 vty_out(vty
, ", via %s",
340 case NEXTHOP_TYPE_IFINDEX
:
341 vty_out(vty
, " directly connected, %s",
342 ifindex2ifname(nexthop
->ifindex
,
345 case NEXTHOP_TYPE_BLACKHOLE
:
346 vty_out(vty
, " unreachable");
347 switch (nexthop
->bh_type
) {
348 case BLACKHOLE_REJECT
:
349 vty_out(vty
, " (ICMP unreachable)");
351 case BLACKHOLE_ADMINPROHIB
:
353 " (ICMP admin-prohibited)");
356 vty_out(vty
, " (blackhole)");
358 case BLACKHOLE_UNSPEC
:
364 if (re
->vrf_id
!= nexthop
->vrf_id
) {
365 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
367 vty_out(vty
, "(vrf %s)", VRF_LOGNAME(vrf
));
370 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
371 vty_out(vty
, " (duplicate nexthop removed)");
373 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
374 vty_out(vty
, " inactive");
376 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
377 vty_out(vty
, " onlink");
379 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_LINKDOWN
))
380 vty_out(vty
, " linkdown");
382 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
383 vty_out(vty
, " (recursive)");
385 /* Source specified? */
386 switch (nexthop
->type
) {
387 case NEXTHOP_TYPE_IPV4
:
388 case NEXTHOP_TYPE_IPV4_IFINDEX
:
389 if (nexthop
->src
.ipv4
.s_addr
) {
390 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
,
391 addrstr
, sizeof(addrstr
)))
392 vty_out(vty
, ", src %s",
397 case NEXTHOP_TYPE_IPV6
:
398 case NEXTHOP_TYPE_IPV6_IFINDEX
:
399 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
401 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
,
402 addrstr
, sizeof(addrstr
)))
403 vty_out(vty
, ", src %s",
413 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
415 /* Label information */
416 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
417 vty_out(vty
, ", label %s",
418 mpls_label2str(nexthop
->nh_label
->num_labels
,
419 nexthop
->nh_label
->label
, buf
,
420 sizeof(buf
), 1 /*pretty*/));
424 vty_out(vty
, ", weight %u", nexthop
->weight
);
426 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
427 vty_out(vty
, ", backup %d", nexthop
->backup_idx
[0]);
429 for (i
= 1; i
< nexthop
->backup_num
; i
++)
430 vty_out(vty
, ",%d", nexthop
->backup_idx
[i
]);
434 static void zebra_show_ip_route_opaque(struct vty
*vty
, struct route_entry
*re
,
435 struct json_object
*json
)
437 struct bgp_zebra_opaque bzo
= {};
438 struct ospf_zebra_opaque ozo
= {};
444 case ZEBRA_ROUTE_SHARP
:
446 json_object_string_add(json
, "opaque",
447 (char *)re
->opaque
->data
);
449 vty_out(vty
, " Opaque Data: %s",
450 (char *)re
->opaque
->data
);
453 case ZEBRA_ROUTE_BGP
:
454 memcpy(&bzo
, re
->opaque
->data
, re
->opaque
->length
);
457 json_object_string_add(json
, "asPath", bzo
.aspath
);
458 json_object_string_add(json
, "communities",
460 json_object_string_add(json
, "largeCommunities",
462 json_object_string_add(json
, "selectionReason",
463 bzo
.selection_reason
);
465 vty_out(vty
, " AS-Path : %s\n", bzo
.aspath
);
467 if (bzo
.community
[0] != '\0')
468 vty_out(vty
, " Communities : %s\n",
471 if (bzo
.lcommunity
[0] != '\0')
472 vty_out(vty
, " Large-Communities: %s\n",
475 vty_out(vty
, " Selection reason : %s\n",
476 bzo
.selection_reason
);
479 case ZEBRA_ROUTE_OSPF
:
480 case ZEBRA_ROUTE_OSPF6
:
481 memcpy(&ozo
, re
->opaque
->data
, re
->opaque
->length
);
484 json_object_string_add(json
, "ospfPathType",
486 if (ozo
.area_id
[0] != '\0')
487 json_object_string_add(json
, "ospfAreaId",
489 if (ozo
.tag
[0] != '\0')
490 json_object_string_add(json
, "ospfTag",
493 vty_out(vty
, " OSPF path type : %s\n",
495 if (ozo
.area_id
[0] != '\0')
496 vty_out(vty
, " OSPF area ID : %s\n",
498 if (ozo
.tag
[0] != '\0')
499 vty_out(vty
, " OSPF tag : %s\n",
508 static void uptime2str(time_t uptime
, char *buf
, size_t bufsize
)
512 cur
= monotime(NULL
);
515 frrtime_to_interval(cur
, buf
, bufsize
);
518 /* New RIB. Detailed information for IPv4 route. */
519 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
520 int mcast
, bool use_fib
, bool show_ng
)
522 struct route_entry
*re
;
523 struct nexthop
*nexthop
;
524 char buf
[SRCDEST2STR_BUFFER
];
525 struct zebra_vrf
*zvrf
;
528 dest
= rib_dest_from_rnode(rn
);
530 RNODE_FOREACH_RE (rn
, re
) {
532 * If re not selected for forwarding, skip re
533 * for "show ip/ipv6 fib <prefix>"
535 if (use_fib
&& re
!= dest
->selected_fib
)
538 const char *mcast_info
= "";
540 struct rib_table_info
*info
=
541 srcdest_rnode_table_info(rn
);
542 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
543 ? " using Multicast RIB"
544 : " using Unicast RIB";
547 vty_out(vty
, "Routing entry for %s%s\n",
548 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
549 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
551 vty_out(vty
, "[%d]", re
->instance
);
553 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
556 vty_out(vty
, ", tag %u", re
->tag
);
557 #if defined(SUPPORT_REALMS)
558 if (re
->tag
> 0 && re
->tag
<= 255)
559 vty_out(vty
, "(realm)");
563 vty_out(vty
, ", mtu %u", re
->mtu
);
564 if (re
->vrf_id
!= VRF_DEFAULT
) {
565 zvrf
= vrf_info_lookup(re
->vrf_id
);
566 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
568 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
569 vty_out(vty
, ", best");
572 uptime2str(re
->uptime
, buf
, sizeof(buf
));
574 vty_out(vty
, " Last update %s ago\n", buf
);
577 vty_out(vty
, " Nexthop Group ID: %u\n", re
->nhe_id
);
578 if (re
->nhe_installed_id
!= 0
579 && re
->nhe_id
!= re
->nhe_installed_id
)
581 " Installed Nexthop Group ID: %u\n",
582 re
->nhe_installed_id
);
585 for (ALL_NEXTHOPS(re
->nhe
->nhg
, nexthop
)) {
586 /* Use helper to format each nexthop */
587 show_nexthop_detail_helper(vty
, re
, nexthop
,
588 false /*not backup*/);
591 /* Include backup(s), if present */
592 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
))
593 show_nh_backup_helper(vty
, re
, nexthop
);
595 zebra_show_ip_route_opaque(vty
, re
, NULL
);
602 * Helper for nexthop output, used in the 'show ip route' path
604 static void show_route_nexthop_helper(struct vty
*vty
,
605 const struct route_entry
*re
,
606 const struct nexthop
*nexthop
)
608 char buf
[MPLS_LABEL_STRLEN
];
611 switch (nexthop
->type
) {
612 case NEXTHOP_TYPE_IPV4
:
613 case NEXTHOP_TYPE_IPV4_IFINDEX
:
614 vty_out(vty
, " via %pI4", &nexthop
->gate
.ipv4
);
615 if (nexthop
->ifindex
)
617 ifindex2ifname(nexthop
->ifindex
,
620 case NEXTHOP_TYPE_IPV6
:
621 case NEXTHOP_TYPE_IPV6_IFINDEX
:
622 vty_out(vty
, " via %s",
623 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
625 if (nexthop
->ifindex
)
627 ifindex2ifname(nexthop
->ifindex
,
631 case NEXTHOP_TYPE_IFINDEX
:
632 vty_out(vty
, " is directly connected, %s",
633 ifindex2ifname(nexthop
->ifindex
,
636 case NEXTHOP_TYPE_BLACKHOLE
:
637 vty_out(vty
, " unreachable");
638 switch (nexthop
->bh_type
) {
639 case BLACKHOLE_REJECT
:
640 vty_out(vty
, " (ICMP unreachable)");
642 case BLACKHOLE_ADMINPROHIB
:
643 vty_out(vty
, " (ICMP admin-prohibited)");
646 vty_out(vty
, " (blackhole)");
648 case BLACKHOLE_UNSPEC
:
654 if ((re
== NULL
|| (nexthop
->vrf_id
!= re
->vrf_id
)))
655 vty_out(vty
, " (vrf %s)", vrf_id_to_name(nexthop
->vrf_id
));
657 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
658 vty_out(vty
, " inactive");
660 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
661 vty_out(vty
, " onlink");
663 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_LINKDOWN
))
664 vty_out(vty
, " linkdown");
666 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
667 vty_out(vty
, " (recursive)");
669 switch (nexthop
->type
) {
670 case NEXTHOP_TYPE_IPV4
:
671 case NEXTHOP_TYPE_IPV4_IFINDEX
:
672 if (nexthop
->src
.ipv4
.s_addr
) {
673 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
675 vty_out(vty
, ", src %s", buf
);
676 /* SR-TE information */
677 if (nexthop
->srte_color
)
678 vty_out(vty
, ", SR-TE color %u",
679 nexthop
->srte_color
);
682 case NEXTHOP_TYPE_IPV6
:
683 case NEXTHOP_TYPE_IPV6_IFINDEX
:
684 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
685 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
687 vty_out(vty
, ", src %s", buf
);
694 /* Label information */
695 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
696 vty_out(vty
, ", label %s",
697 mpls_label2str(nexthop
->nh_label
->num_labels
,
698 nexthop
->nh_label
->label
, buf
,
702 if (nexthop
->nh_srv6
) {
703 seg6local_context2str(buf
, sizeof(buf
),
704 &nexthop
->nh_srv6
->seg6local_ctx
,
705 nexthop
->nh_srv6
->seg6local_action
);
706 vty_out(vty
, ", seg6local %s %s", seg6local_action2str(
707 nexthop
->nh_srv6
->seg6local_action
), buf
);
709 inet_ntop(AF_INET6
, &nexthop
->nh_srv6
->seg6_segs
, buf
,
711 vty_out(vty
, ", seg6 %s", buf
);
715 vty_out(vty
, ", weight %u", nexthop
->weight
);
717 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
718 vty_out(vty
, ", backup %d", nexthop
->backup_idx
[0]);
720 for (i
= 1; i
< nexthop
->backup_num
; i
++)
721 vty_out(vty
, ",%d", nexthop
->backup_idx
[i
]);
726 * Render a nexthop into a json object; the caller allocates and owns
727 * the json object memory.
729 static void show_nexthop_json_helper(json_object
*json_nexthop
,
730 const struct nexthop
*nexthop
,
731 const struct route_entry
*re
)
733 char buf
[SRCDEST2STR_BUFFER
];
734 json_object
*json_labels
= NULL
;
735 json_object
*json_backups
= NULL
;
736 json_object
*json_seg6local
= NULL
;
737 json_object
*json_seg6
= NULL
;
740 json_object_int_add(json_nexthop
, "flags",
743 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
744 json_object_boolean_true_add(json_nexthop
,
747 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
748 json_object_boolean_true_add(json_nexthop
,
751 switch (nexthop
->type
) {
752 case NEXTHOP_TYPE_IPV4
:
753 case NEXTHOP_TYPE_IPV4_IFINDEX
:
754 json_object_string_addf(json_nexthop
, "ip", "%pI4",
755 &nexthop
->gate
.ipv4
);
756 json_object_string_add(json_nexthop
, "afi",
759 if (nexthop
->ifindex
) {
760 json_object_int_add(json_nexthop
,
763 json_object_string_add(
764 json_nexthop
, "interfaceName",
770 case NEXTHOP_TYPE_IPV6
:
771 case NEXTHOP_TYPE_IPV6_IFINDEX
:
772 json_object_string_addf(json_nexthop
, "ip", "%pI6",
773 &nexthop
->gate
.ipv6
);
774 json_object_string_add(json_nexthop
, "afi",
777 if (nexthop
->ifindex
) {
778 json_object_int_add(json_nexthop
,
781 json_object_string_add(
782 json_nexthop
, "interfaceName",
789 case NEXTHOP_TYPE_IFINDEX
:
790 json_object_boolean_true_add(
791 json_nexthop
, "directlyConnected");
792 json_object_int_add(json_nexthop
,
795 json_object_string_add(
796 json_nexthop
, "interfaceName",
797 ifindex2ifname(nexthop
->ifindex
,
800 case NEXTHOP_TYPE_BLACKHOLE
:
801 json_object_boolean_true_add(json_nexthop
,
803 switch (nexthop
->bh_type
) {
804 case BLACKHOLE_REJECT
:
805 json_object_boolean_true_add(
806 json_nexthop
, "reject");
808 case BLACKHOLE_ADMINPROHIB
:
809 json_object_boolean_true_add(
814 json_object_boolean_true_add(
815 json_nexthop
, "blackhole");
817 case BLACKHOLE_UNSPEC
:
823 /* This nexthop is a resolver for the parent nexthop.
824 * Set resolver flag for better clarity and delimiter
825 * in flat list of nexthops in json.
827 if (nexthop
->rparent
)
828 json_object_boolean_true_add(json_nexthop
, "resolver");
830 if (nexthop
->vrf_id
!= re
->vrf_id
)
831 json_object_string_add(json_nexthop
, "vrf",
832 vrf_id_to_name(nexthop
->vrf_id
));
834 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
835 json_object_boolean_true_add(json_nexthop
,
838 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
839 json_object_boolean_true_add(json_nexthop
,
842 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
843 json_object_boolean_true_add(json_nexthop
,
846 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_LINKDOWN
))
847 json_object_boolean_true_add(json_nexthop
, "linkDown");
849 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
850 json_object_boolean_true_add(json_nexthop
,
853 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
854 json_backups
= json_object_new_array();
855 for (i
= 0; i
< nexthop
->backup_num
; i
++) {
856 json_object_array_add(
858 json_object_new_int(nexthop
->backup_idx
[i
]));
861 json_object_object_add(json_nexthop
, "backupIndex",
865 switch (nexthop
->type
) {
866 case NEXTHOP_TYPE_IPV4
:
867 case NEXTHOP_TYPE_IPV4_IFINDEX
:
868 if (nexthop
->src
.ipv4
.s_addr
) {
869 if (inet_ntop(AF_INET
,
870 &nexthop
->src
.ipv4
, buf
,
872 json_object_string_add(
873 json_nexthop
, "source",
877 case NEXTHOP_TYPE_IPV6
:
878 case NEXTHOP_TYPE_IPV6_IFINDEX
:
879 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
881 if (inet_ntop(AF_INET6
,
882 &nexthop
->src
.ipv6
, buf
,
884 json_object_string_add(
885 json_nexthop
, "source",
893 if (nexthop
->nh_label
894 && nexthop
->nh_label
->num_labels
) {
895 json_labels
= json_object_new_array();
897 for (int label_index
= 0;
899 < nexthop
->nh_label
->num_labels
;
901 json_object_array_add(
904 nexthop
->nh_label
->label
907 json_object_object_add(json_nexthop
, "labels",
912 json_object_int_add(json_nexthop
, "weight",
915 if (nexthop
->srte_color
)
916 json_object_int_add(json_nexthop
, "srteColor",
917 nexthop
->srte_color
);
919 if (nexthop
->nh_srv6
) {
920 json_seg6local
= json_object_new_object();
921 json_object_string_add(
922 json_seg6local
, "action", seg6local_action2str(
923 nexthop
->nh_srv6
->seg6local_action
));
924 json_object_object_add(json_nexthop
, "seg6local",
927 json_seg6
= json_object_new_object();
928 inet_ntop(AF_INET6
, &nexthop
->nh_srv6
->seg6_segs
, buf
,
930 json_object_string_add(json_seg6
, "segs", buf
);
931 json_object_object_add(json_nexthop
, "seg6", json_seg6
);
935 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
936 struct route_entry
*re
, json_object
*json
,
937 bool is_fib
, bool show_ng
)
939 const struct nexthop
*nexthop
;
941 char buf
[SRCDEST2STR_BUFFER
];
942 json_object
*json_nexthops
= NULL
;
943 json_object
*json_nexthop
= NULL
;
944 json_object
*json_route
= NULL
;
945 const rib_dest_t
*dest
= rib_dest_from_rnode(rn
);
946 const struct nexthop_group
*nhg
;
947 char up_str
[MONOTIME_STRLEN
];
949 bool nhg_from_backup
= false;
951 uptime2str(re
->uptime
, up_str
, sizeof(up_str
));
953 /* If showing fib information, use the fib view of the
957 nhg
= rib_get_fib_nhg(re
);
959 nhg
= &(re
->nhe
->nhg
);
962 json_route
= json_object_new_object();
963 json_nexthops
= json_object_new_array();
965 json_object_string_add(json_route
, "prefix",
966 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
967 json_object_int_add(json_route
, "prefixLen", rn
->p
.prefixlen
);
968 json_object_string_add(json_route
, "protocol",
969 zebra_route_string(re
->type
));
972 json_object_int_add(json_route
, "instance",
975 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
976 json_object_string_add(json_route
, "vrfName",
977 vrf_id_to_name(re
->vrf_id
));
979 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
980 json_object_boolean_true_add(json_route
, "selected");
982 if (dest
->selected_fib
== re
)
983 json_object_boolean_true_add(json_route
,
986 json_object_int_add(json_route
, "distance",
988 json_object_int_add(json_route
, "metric", re
->metric
);
990 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
))
991 json_object_boolean_true_add(json_route
, "installed");
993 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_FAILED
))
994 json_object_boolean_true_add(json_route
, "failed");
996 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_QUEUED
))
997 json_object_boolean_true_add(json_route
, "queued");
999 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
))
1000 json_object_boolean_true_add(json_route
, "trapped");
1002 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
))
1003 json_object_boolean_true_add(json_route
, "offloaded");
1005 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOAD_FAILED
))
1006 json_object_boolean_false_add(json_route
, "offloaded");
1009 json_object_int_add(json_route
, "tag", re
->tag
);
1012 json_object_int_add(json_route
, "table", re
->table
);
1014 json_object_int_add(json_route
, "internalStatus",
1016 json_object_int_add(json_route
, "internalFlags",
1018 json_object_int_add(json_route
, "internalNextHopNum",
1019 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)));
1020 json_object_int_add(json_route
, "internalNextHopActiveNum",
1021 nexthop_group_active_nexthop_num(
1023 json_object_int_add(json_route
, "nexthopGroupId", re
->nhe_id
);
1025 if (re
->nhe_installed_id
!= 0)
1026 json_object_int_add(json_route
,
1027 "installedNexthopGroupId",
1028 re
->nhe_installed_id
);
1030 json_object_string_add(json_route
, "uptime", up_str
);
1032 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1033 json_nexthop
= json_object_new_object();
1034 show_nexthop_json_helper(json_nexthop
,
1037 json_object_array_add(json_nexthops
,
1041 json_object_object_add(json_route
, "nexthops", json_nexthops
);
1043 /* If there are backup nexthops, include them */
1045 nhg
= rib_get_fib_backup_nhg(re
);
1047 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1049 if (nhg
&& nhg
->nexthop
) {
1050 json_nexthops
= json_object_new_array();
1052 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1053 json_nexthop
= json_object_new_object();
1055 show_nexthop_json_helper(json_nexthop
,
1057 json_object_array_add(json_nexthops
,
1061 json_object_object_add(json_route
, "backupNexthops",
1064 zebra_show_ip_route_opaque(NULL
, re
, json_route
);
1066 json_object_array_add(json
, json_route
);
1070 /* Prefix information, and first nexthop. If we're showing 'fib',
1071 * and there are no installed primary nexthops, see if there are any
1072 * backup nexthops and start with those.
1074 if (is_fib
&& nhg
->nexthop
== NULL
) {
1075 nhg
= rib_get_fib_backup_nhg(re
);
1076 nhg_from_backup
= true;
1079 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
1081 len
+= vty_out(vty
, "[%d]", re
->instance
);
1082 if (nhg_from_backup
&& nhg
->nexthop
) {
1085 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
) ? '>' : ' ',
1086 re_status_output_char(re
, nhg
->nexthop
, is_fib
),
1087 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
1091 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
) ? '>' : ' ',
1092 re_status_output_char(re
, nhg
->nexthop
, is_fib
),
1093 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
1096 /* Distance and metric display. */
1097 if (((re
->type
== ZEBRA_ROUTE_CONNECT
) &&
1098 (re
->distance
|| re
->metric
)) ||
1099 (re
->type
!= ZEBRA_ROUTE_CONNECT
))
1100 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
1104 len
+= vty_out(vty
, " (%u)", re
->nhe_id
);
1106 /* Nexthop information. */
1107 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1110 } else if (nhg_from_backup
) {
1111 vty_out(vty
, " b%c%*c",
1112 re_status_output_char(re
, nexthop
, is_fib
),
1113 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1115 vty_out(vty
, " %c%*c",
1116 re_status_output_char(re
, nexthop
, is_fib
),
1117 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1120 show_route_nexthop_helper(vty
, re
, nexthop
);
1121 vty_out(vty
, ", %s\n", up_str
);
1124 /* If we only had backup nexthops, we're done */
1125 if (nhg_from_backup
)
1128 /* Check for backup nexthop info if present */
1130 nhg
= rib_get_fib_backup_nhg(re
);
1132 nhg
= zebra_nhg_get_backup_nhg(re
->nhe
);
1137 /* Print backup info */
1138 for (ALL_NEXTHOPS_PTR(nhg
, nexthop
)) {
1139 bool star_p
= false;
1142 star_p
= CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
);
1144 /* TODO -- it'd be nice to be able to include
1145 * the entire list of backups, *and* include the
1146 * real installation state.
1148 vty_out(vty
, " b%c %*c",
1149 (star_p
? '*' : ' '),
1150 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1151 show_route_nexthop_helper(vty
, re
, nexthop
);
1157 static void vty_show_ip_route_detail_json(struct vty
*vty
,
1158 struct route_node
*rn
, bool use_fib
)
1160 json_object
*json
= NULL
;
1161 json_object
*json_prefix
= NULL
;
1162 struct route_entry
*re
;
1166 dest
= rib_dest_from_rnode(rn
);
1168 json
= json_object_new_object();
1169 json_prefix
= json_object_new_array();
1171 RNODE_FOREACH_RE (rn
, re
) {
1173 * If re not selected for forwarding, skip re
1174 * for "show ip/ipv6 fib <prefix> json"
1176 if (use_fib
&& re
!= dest
->selected_fib
)
1178 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
, false);
1181 prefix2str(&rn
->p
, buf
, sizeof(buf
));
1182 json_object_object_add(json
, buf
, json_prefix
);
1183 vty_json(vty
, json
);
1186 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1187 struct route_table
*table
, afi_t afi
,
1188 bool use_fib
, route_tag_t tag
,
1189 const struct prefix
*longer_prefix_p
,
1190 bool supernets_only
, int type
,
1191 unsigned short ospf_instance_id
, bool use_json
,
1192 uint32_t tableid
, bool show_ng
,
1193 struct route_show_ctx
*ctx
)
1195 struct route_node
*rn
;
1196 struct route_entry
*re
;
1199 json_object
*json
= NULL
;
1200 json_object
*json_prefix
= NULL
;
1205 * ctx->multi indicates if we are dumping multiple tables or vrfs.
1207 * => display the common header at most once
1208 * => add newline at each call except first
1209 * => always display the VRF and table
1211 * => display the common header if at least one entry is found
1212 * => display the VRF and table if specific
1216 json
= json_object_new_object();
1218 /* Show all routes. */
1219 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
)) {
1220 dest
= rib_dest_from_rnode(rn
);
1222 RNODE_FOREACH_RE (rn
, re
) {
1223 if (use_fib
&& re
!= dest
->selected_fib
)
1226 if (tag
&& re
->tag
!= tag
)
1230 && !prefix_match(longer_prefix_p
, &rn
->p
))
1233 /* This can only be true when the afi is IPv4 */
1234 if (supernets_only
) {
1235 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1237 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1240 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1243 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1247 if (type
&& re
->type
!= type
)
1250 if (ospf_instance_id
1251 && (re
->type
!= ZEBRA_ROUTE_OSPF
1252 || re
->instance
!= ospf_instance_id
))
1257 json_prefix
= json_object_new_array();
1259 if (!ctx
->header_done
) {
1262 SHOW_ROUTE_V4_HEADER
);
1265 SHOW_ROUTE_V6_HEADER
);
1267 if (ctx
->multi
&& ctx
->header_done
)
1269 if (ctx
->multi
|| zvrf_id(zvrf
) != VRF_DEFAULT
1272 vty_out(vty
, "VRF %s:\n",
1276 "VRF %s table %u:\n",
1280 ctx
->header_done
= true;
1284 vty_show_ip_route(vty
, rn
, re
, json_prefix
, use_fib
,
1289 prefix2str(&rn
->p
, buf
, sizeof(buf
));
1290 json_object_object_add(json
, buf
, json_prefix
);
1296 vty_json(vty
, json
);
1299 static void do_show_ip_route_all(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1300 afi_t afi
, bool use_fib
, bool use_json
,
1302 const struct prefix
*longer_prefix_p
,
1303 bool supernets_only
, int type
,
1304 unsigned short ospf_instance_id
, bool show_ng
,
1305 struct route_show_ctx
*ctx
)
1307 struct zebra_router_table
*zrt
;
1308 struct rib_table_info
*info
;
1310 RB_FOREACH (zrt
, zebra_router_table_head
,
1312 info
= route_table_get_info(zrt
->table
);
1314 if (zvrf
!= info
->zvrf
)
1316 if (zrt
->afi
!= afi
||
1317 zrt
->safi
!= SAFI_UNICAST
)
1320 do_show_ip_route(vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
,
1321 use_fib
, use_json
, tag
, longer_prefix_p
,
1322 supernets_only
, type
, ospf_instance_id
,
1323 zrt
->tableid
, show_ng
, ctx
);
1327 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
1328 safi_t safi
, bool use_fib
, bool use_json
,
1330 const struct prefix
*longer_prefix_p
,
1331 bool supernets_only
, int type
,
1332 unsigned short ospf_instance_id
, uint32_t tableid
,
1333 bool show_ng
, struct route_show_ctx
*ctx
)
1335 struct route_table
*table
;
1336 struct zebra_vrf
*zvrf
= NULL
;
1338 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
1340 vty_out(vty
, "{}\n");
1342 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
1346 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
1348 vty_out(vty
, "{}\n");
1350 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
1355 table
= zebra_router_find_table(zvrf
, tableid
, afi
, SAFI_UNICAST
);
1357 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
1360 vty_out(vty
, "{}\n");
1364 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
1365 longer_prefix_p
, supernets_only
, type
,
1366 ospf_instance_id
, use_json
, tableid
, show_ng
, ctx
);
1373 "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] [mrib$mrib]",
1377 "IP nexthop tracking table\n"
1378 "IP import check tracking table\n"
1384 VRF_ALL_CMD_HELP_STR
1385 "Show Multicast (MRIB) NHT state\n")
1387 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1388 vrf_id_t vrf_id
= VRF_DEFAULT
;
1389 struct prefix prefix
, *p
= NULL
;
1390 safi_t safi
= mrib
? SAFI_MULTICAST
: SAFI_UNICAST
;
1394 struct zebra_vrf
*zvrf
;
1396 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1397 if ((zvrf
= vrf
->info
) != NULL
) {
1398 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1399 zebra_print_rnh_table(zvrf_id(zvrf
), afi
, safi
,
1405 VRF_GET_ID(vrf_id
, vrf_name
, false);
1407 memset(&prefix
, 0, sizeof(prefix
));
1409 p
= sockunion2hostprefix(addr
, &prefix
);
1414 zebra_print_rnh_table(vrf_id
, afi
, safi
, vty
, p
);
1418 DEFUN (ip_nht_default_route
,
1419 ip_nht_default_route_cmd
,
1420 "ip nht resolve-via-default",
1422 "Filter Next Hop tracking route resolution\n"
1423 "Resolve via default route\n")
1425 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
1430 if (zvrf
->zebra_rnh_ip_default_route
)
1433 zvrf
->zebra_rnh_ip_default_route
= true;
1435 zebra_evaluate_rnh(zvrf
, AFI_IP
, 0, NULL
, SAFI_UNICAST
);
1439 static void show_nexthop_group_out(struct vty
*vty
, struct nhg_hash_entry
*nhe
)
1441 struct nexthop
*nexthop
= NULL
;
1442 struct nhg_connected
*rb_node_dep
= NULL
;
1443 struct nexthop_group
*backup_nhg
;
1444 char up_str
[MONOTIME_STRLEN
];
1445 char time_left
[MONOTIME_STRLEN
];
1447 uptime2str(nhe
->uptime
, up_str
, sizeof(up_str
));
1449 vty_out(vty
, "ID: %u (%s)\n", nhe
->id
, zebra_route_string(nhe
->type
));
1450 vty_out(vty
, " RefCnt: %u", nhe
->refcnt
);
1451 if (thread_is_scheduled(nhe
->timer
))
1452 vty_out(vty
, " Time to Deletion: %s",
1453 thread_timer_to_hhmmss(time_left
, sizeof(time_left
),
1457 vty_out(vty
, " Uptime: %s\n", up_str
);
1458 vty_out(vty
, " VRF: %s\n", vrf_id_to_name(nhe
->vrf_id
));
1461 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_VALID
)) {
1462 vty_out(vty
, " Valid");
1463 if (CHECK_FLAG(nhe
->flags
, NEXTHOP_GROUP_INSTALLED
))
1464 vty_out(vty
, ", Installed");
1468 vty_out(vty
, " Interface Index: %d\n", nhe
->ifp
->ifindex
);
1470 if (!zebra_nhg_depends_is_empty(nhe
)) {
1471 vty_out(vty
, " Depends:");
1472 frr_each(nhg_connected_tree
, &nhe
->nhg_depends
, rb_node_dep
) {
1473 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1478 /* Output nexthops */
1479 for (ALL_NEXTHOPS(nhe
->nhg
, nexthop
)) {
1480 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1483 /* Make recursive nexthops a bit more clear */
1486 show_route_nexthop_helper(vty
, NULL
, nexthop
);
1488 if (nhe
->backup_info
== NULL
|| nhe
->backup_info
->nhe
== NULL
) {
1489 if (CHECK_FLAG(nexthop
->flags
,
1490 NEXTHOP_FLAG_HAS_BACKUP
))
1491 vty_out(vty
, " [backup %d]",
1492 nexthop
->backup_idx
[0]);
1498 /* TODO -- print more useful backup info */
1499 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_HAS_BACKUP
)) {
1502 vty_out(vty
, "[backup");
1503 for (i
= 0; i
< nexthop
->backup_num
; i
++)
1504 vty_out(vty
, " %d", nexthop
->backup_idx
[i
]);
1512 /* Output backup nexthops (if any) */
1513 backup_nhg
= zebra_nhg_get_backup_nhg(nhe
);
1515 vty_out(vty
, " Backups:\n");
1517 for (ALL_NEXTHOPS_PTR(backup_nhg
, nexthop
)) {
1518 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1521 /* Make recursive nexthops a bit more clear */
1524 show_route_nexthop_helper(vty
, NULL
, nexthop
);
1529 if (!zebra_nhg_dependents_is_empty(nhe
)) {
1530 vty_out(vty
, " Dependents:");
1531 frr_each(nhg_connected_tree
, &nhe
->nhg_dependents
,
1533 vty_out(vty
, " (%u)", rb_node_dep
->nhe
->id
);
1538 if (nhe
->nhg
.nhgr
.buckets
)
1540 " Buckets: %u Idle Timer: %u Unbalanced Timer: %u Unbalanced time: %" PRIu64
"\n",
1541 nhe
->nhg
.nhgr
.buckets
, nhe
->nhg
.nhgr
.idle_timer
,
1542 nhe
->nhg
.nhgr
.unbalanced_timer
,
1543 nhe
->nhg
.nhgr
.unbalanced_time
);
1546 static int show_nexthop_group_id_cmd_helper(struct vty
*vty
, uint32_t id
)
1548 struct nhg_hash_entry
*nhe
= NULL
;
1550 nhe
= zebra_nhg_lookup_id(id
);
1553 show_nexthop_group_out(vty
, nhe
);
1555 vty_out(vty
, "Nexthop Group ID: %u does not exist\n", id
);
1561 /* Helper function for iteration through the hash of nexthop-groups/nhe-s */
1563 struct nhe_show_context
{
1570 static int nhe_show_walker(struct hash_bucket
*bucket
, void *arg
)
1572 struct nhe_show_context
*ctx
= arg
;
1573 struct nhg_hash_entry
*nhe
;
1575 nhe
= bucket
->data
; /* We won't be offered NULL buckets */
1577 if (ctx
->afi
&& nhe
->afi
!= ctx
->afi
)
1580 if (ctx
->vrf_id
&& nhe
->vrf_id
!= ctx
->vrf_id
)
1583 if (ctx
->type
&& nhe
->type
!= ctx
->type
)
1586 show_nexthop_group_out(ctx
->vty
, nhe
);
1589 return HASHWALK_CONTINUE
;
1592 static void show_nexthop_group_cmd_helper(struct vty
*vty
,
1593 struct zebra_vrf
*zvrf
, afi_t afi
,
1596 struct nhe_show_context ctx
;
1600 ctx
.vrf_id
= zvrf
->vrf
->vrf_id
;
1603 hash_walk(zrouter
.nhgs_id
, nhe_show_walker
, &ctx
);
1606 static void if_nexthop_group_dump_vty(struct vty
*vty
, struct interface
*ifp
)
1608 struct zebra_if
*zebra_if
= NULL
;
1609 struct nhg_connected
*rb_node_dep
= NULL
;
1611 zebra_if
= ifp
->info
;
1613 if (!if_nhg_dependents_is_empty(ifp
)) {
1614 vty_out(vty
, "Interface %s:\n", ifp
->name
);
1616 frr_each(nhg_connected_tree
, &zebra_if
->nhg_dependents
,
1619 show_nexthop_group_out(vty
, rb_node_dep
->nhe
);
1624 DEFPY (show_interface_nexthop_group
,
1625 show_interface_nexthop_group_cmd
,
1626 "show interface [IFNAME$if_name] nexthop-group",
1628 "Interface status and configuration\n"
1630 "Show Nexthop Groups\n")
1632 struct vrf
*vrf
= NULL
;
1633 struct interface
*ifp
= NULL
;
1636 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1638 ifp
= if_lookup_by_name(if_name
, vrf
->vrf_id
);
1640 if_nexthop_group_dump_vty(vty
, ifp
);
1644 FOR_ALL_INTERFACES (vrf
, ifp
)
1645 if_nexthop_group_dump_vty(vty
, ifp
);
1651 vty_out(vty
, "%% Can't find interface %s\n", if_name
);
1658 DEFPY (show_nexthop_group
,
1659 show_nexthop_group_cmd
,
1660 "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>]>",
1662 "Show Nexthop Groups\n"
1664 "Nexthop Group ID\n"
1665 "Show Singleton Nexthop-Groups\n"
1668 "Kernel (not installed via the zebra RIB)\n"
1669 "Zebra (implicitly created by zebra)\n"
1670 "Border Gateway Protocol (BGP)\n"
1671 "Super Happy Advanced Routing Protocol (SHARP)\n"
1672 VRF_FULL_CMD_HELP_STR
)
1675 struct zebra_vrf
*zvrf
= NULL
;
1676 afi_t afi
= AFI_UNSPEC
;
1680 return show_nexthop_group_id_cmd_helper(vty
, id
);
1688 type
= proto_redistnum((afi
? afi
: AFI_IP
), type_str
);
1691 type
= ZEBRA_ROUTE_NHG
;
1695 if (!vrf_is_backend_netns() && (vrf_name
|| vrf_all
)) {
1697 "VRF subcommand does not make any sense in l3mdev based vrf's\n");
1704 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1705 struct zebra_vrf
*zvrf
;
1711 vty_out(vty
, "VRF: %s\n", vrf
->name
);
1712 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
, type
);
1719 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
1721 zvrf
= zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME
);
1724 vty_out(vty
, "%% VRF '%s' specified does not exist\n",
1729 show_nexthop_group_cmd_helper(vty
, zvrf
, afi
, type
);
1734 DEFPY_HIDDEN(nexthop_group_use_enable
,
1735 nexthop_group_use_enable_cmd
,
1736 "[no] zebra nexthop kernel enable",
1739 "Nexthop configuration \n"
1740 "Configure use of kernel nexthops\n"
1741 "Enable kernel nexthops\n")
1743 zebra_nhg_enable_kernel_nexthops(!no
);
1747 DEFPY_HIDDEN(proto_nexthop_group_only
, proto_nexthop_group_only_cmd
,
1748 "[no] zebra nexthop proto only",
1750 "Nexthop configuration\n"
1751 "Configure exclusive use of proto nexthops\n"
1752 "Only use proto nexthops\n")
1754 zebra_nhg_set_proto_nexthops_only(!no
);
1758 DEFPY_HIDDEN(backup_nexthop_recursive_use_enable
,
1759 backup_nexthop_recursive_use_enable_cmd
,
1760 "[no] zebra nexthop resolve-via-backup",
1763 "Nexthop configuration \n"
1764 "Configure use of backup nexthops in recursive resolution\n")
1766 zebra_nhg_set_recursive_use_backups(!no
);
1770 DEFUN (no_ip_nht_default_route
,
1771 no_ip_nht_default_route_cmd
,
1772 "no ip nht resolve-via-default",
1775 "Filter Next Hop tracking route resolution\n"
1776 "Resolve via default route\n")
1778 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
1783 if (!zvrf
->zebra_rnh_ip_default_route
)
1786 zvrf
->zebra_rnh_ip_default_route
= false;
1787 zebra_evaluate_rnh(zvrf
, AFI_IP
, 0, NULL
, SAFI_UNICAST
);
1791 DEFUN (ipv6_nht_default_route
,
1792 ipv6_nht_default_route_cmd
,
1793 "ipv6 nht resolve-via-default",
1795 "Filter Next Hop tracking route resolution\n"
1796 "Resolve via default route\n")
1798 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
1803 if (zvrf
->zebra_rnh_ipv6_default_route
)
1806 zvrf
->zebra_rnh_ipv6_default_route
= true;
1807 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 0, NULL
, SAFI_UNICAST
);
1811 DEFUN (no_ipv6_nht_default_route
,
1812 no_ipv6_nht_default_route_cmd
,
1813 "no ipv6 nht resolve-via-default",
1816 "Filter Next Hop tracking route resolution\n"
1817 "Resolve via default route\n")
1819 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
1824 if (!zvrf
->zebra_rnh_ipv6_default_route
)
1827 zvrf
->zebra_rnh_ipv6_default_route
= false;
1828 zebra_evaluate_rnh(zvrf
, AFI_IP6
, 0, NULL
, SAFI_UNICAST
);
1832 DEFPY_HIDDEN(rnh_hide_backups
, rnh_hide_backups_cmd
,
1833 "[no] ip nht hide-backup-events",
1836 "Nexthop-tracking configuration\n"
1837 "Hide notification about backup nexthops\n")
1839 rnh_set_hide_backups(!no
);
1847 ip$ipv4 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1848 [vrf <NAME$vrf_name|all$vrf_all>]\
1851 |A.B.C.D/M$prefix longer-prefixes\
1852 |supernets-only$supernets_only\
1855 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1856 |ospf$type_str (1-65535)$ospf_instance_id\
1858 |ipv6$ipv6 <fib$fib|route> [table <(1-4294967295)$table|all$table_all>]\
1859 [vrf <NAME$vrf_name|all$vrf_all>]\
1862 |X:X::X:X/M$prefix longer-prefixes\
1864 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1866 [<json$json|nexthop-group$ng>]",
1869 "IP forwarding table\n"
1870 "IP routing table\n"
1871 "Table to display\n"
1872 "The table number to display\n"
1874 VRF_FULL_CMD_HELP_STR
1875 "Show only routes with tag\n"
1877 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1878 "Show route matching the specified Network/Mask pair only\n"
1879 "Show supernet entries only\n"
1880 FRR_IP_REDIST_HELP_STR_ZEBRA
1881 "Open Shortest Path First (OSPFv2)\n"
1884 "IP forwarding table\n"
1885 "IP routing table\n"
1886 "Table to display\n"
1887 "The table number to display\n"
1889 VRF_FULL_CMD_HELP_STR
1890 "Show only routes with tag\n"
1893 "Show route matching the specified Network/Mask pair only\n"
1894 FRR_IP6_REDIST_HELP_STR_ZEBRA
1896 "Nexthop Group Information\n")
1898 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1901 struct zebra_vrf
*zvrf
;
1902 struct route_show_ctx ctx
= {
1903 .multi
= vrf_all
|| table_all
,
1906 if (!vrf_is_backend_netns()) {
1907 if ((vrf_all
|| vrf_name
) && (table
|| table_all
)) {
1909 vty_out(vty
, "{}\n");
1911 vty_out(vty
, "Linux vrf backend already points to table id\n");
1912 vty_out(vty
, "Either remove table parameter or vrf parameter\n");
1918 type
= proto_redistnum(afi
, type_str
);
1920 vty_out(vty
, "Unknown route type\n");
1926 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1927 if ((zvrf
= vrf
->info
) == NULL
1928 || (zvrf
->table
[afi
][SAFI_UNICAST
] == NULL
))
1932 do_show_ip_route_all(
1933 vty
, zvrf
, afi
, !!fib
, !!json
, tag
,
1934 prefix_str
? prefix
: NULL
,
1935 !!supernets_only
, type
,
1936 ospf_instance_id
, !!ng
, &ctx
);
1939 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
,
1941 prefix_str
? prefix
: NULL
,
1942 !!supernets_only
, type
,
1943 ospf_instance_id
, table
, !!ng
, &ctx
);
1946 vrf_id_t vrf_id
= VRF_DEFAULT
;
1949 VRF_GET_ID(vrf_id
, vrf_name
, !!json
);
1950 vrf
= vrf_lookup_by_id(vrf_id
);
1959 do_show_ip_route_all(vty
, zvrf
, afi
, !!fib
, !!json
, tag
,
1960 prefix_str
? prefix
: NULL
,
1961 !!supernets_only
, type
,
1962 ospf_instance_id
, !!ng
, &ctx
);
1964 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
,
1966 prefix_str
? prefix
: NULL
,
1967 !!supernets_only
, type
,
1968 ospf_instance_id
, table
, !!ng
, &ctx
);
1974 ALIAS_HIDDEN (show_route
,
1976 "show <ip$ipv4|ipv6$ipv6> ro",
1980 "IP routing table\n");
1983 DEFPY (show_route_detail
,
1984 show_route_detail_cmd
,
1987 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1992 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1998 [json$json] [nexthop-group$ng]",
2001 "IPv6 forwarding table\n"
2002 "IP routing table\n"
2003 VRF_FULL_CMD_HELP_STR
2004 "Network in the IP routing table to display\n"
2005 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
2007 "IPv6 forwarding table\n"
2008 "IPv6 routing table\n"
2009 VRF_FULL_CMD_HELP_STR
2013 "Nexthop Group Information\n")
2015 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
2016 struct route_table
*table
;
2018 struct route_node
*rn
;
2019 bool use_fib
= !!fib
;
2021 bool network_found
= false;
2022 bool show_ng
= !!ng
;
2025 prefix_str
= address_str
;
2026 if (str2prefix(prefix_str
, &p
) < 0) {
2027 vty_out(vty
, "%% Malformed address\n");
2033 struct zebra_vrf
*zvrf
;
2035 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2036 if ((zvrf
= vrf
->info
) == NULL
2037 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
2040 rn
= route_node_match(table
, &p
);
2043 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
2044 route_unlock_node(rn
);
2048 dest
= rib_dest_from_rnode(rn
);
2049 if (use_fib
&& !dest
->selected_fib
) {
2050 route_unlock_node(rn
);
2054 network_found
= true;
2056 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
2058 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
,
2061 route_unlock_node(rn
);
2064 if (!network_found
) {
2066 vty_out(vty
, "{}\n");
2070 "%% Network not in FIB\n");
2073 "%% Network not in RIB\n");
2078 vrf_id_t vrf_id
= VRF_DEFAULT
;
2081 VRF_GET_ID(vrf_id
, vrf_name
, false);
2083 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
2087 rn
= route_node_match(table
, &p
);
2089 dest
= rib_dest_from_rnode(rn
);
2091 if (!rn
|| (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) ||
2092 (use_fib
&& dest
&& !dest
->selected_fib
)) {
2094 vty_out(vty
, "{}\n");
2098 "%% Network not in FIB\n");
2101 "%% Network not in table\n");
2104 route_unlock_node(rn
);
2109 vty_show_ip_route_detail_json(vty
, rn
, use_fib
);
2111 vty_show_ip_route_detail(vty
, rn
, 0, use_fib
, show_ng
);
2113 route_unlock_node(rn
);
2119 DEFPY (show_route_summary
,
2120 show_route_summary_cmd
,
2121 "show <ip$ipv4|ipv6$ipv6> route [vrf <NAME$vrf_name|all$vrf_all>] \
2122 summary [table (1-4294967295)$table_id] [prefix$prefix] [json]",
2126 "IP routing table\n"
2127 VRF_FULL_CMD_HELP_STR
2128 "Summary of all routes\n"
2129 "Table to display summary for\n"
2130 "The table number\n"
2134 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
2135 struct route_table
*table
;
2136 bool uj
= use_json(argc
, argv
);
2140 struct zebra_vrf
*zvrf
;
2142 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2143 if ((zvrf
= vrf
->info
) == NULL
)
2147 table
= zebra_vrf_table(afi
, SAFI_UNICAST
,
2150 table
= zebra_vrf_lookup_table_with_table_id(
2151 afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
,
2158 vty_show_ip_route_summary_prefix(vty
, table
,
2161 vty_show_ip_route_summary(vty
, table
, uj
);
2164 vrf_id_t vrf_id
= VRF_DEFAULT
;
2167 VRF_GET_ID(vrf_id
, vrf_name
, false);
2170 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
2172 table
= zebra_vrf_lookup_table_with_table_id(
2173 afi
, SAFI_UNICAST
, vrf_id
, table_id
);
2178 vty_show_ip_route_summary_prefix(vty
, table
, uj
);
2180 vty_show_ip_route_summary(vty
, table
, uj
);
2186 DEFUN_HIDDEN (show_route_zebra_dump
,
2187 show_route_zebra_dump_cmd
,
2188 "show <ip|ipv6> zebra route dump [vrf VRFNAME]",
2198 struct route_table
*table
;
2199 const char *vrf_name
= NULL
;
2202 afi
= strmatch(argv
[1]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
2204 if (argv_find(argv
, argc
, "vrf", &idx
))
2205 vrf_name
= argv
[++idx
]->arg
;
2209 struct zebra_vrf
*zvrf
;
2211 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2214 || (zvrf
->table
[afi
][SAFI_UNICAST
] == NULL
))
2217 table
= zvrf
->table
[afi
][SAFI_UNICAST
];
2218 show_ip_route_dump_vty(vty
, table
);
2221 vrf_id_t vrf_id
= VRF_DEFAULT
;
2223 VRF_GET_ID(vrf_id
, vrf_name
, true);
2225 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
2229 show_ip_route_dump_vty(vty
, table
);
2235 static void show_ip_route_nht_dump(struct vty
*vty
, struct nexthop
*nexthop
,
2236 struct route_entry
*re
, unsigned int num
)
2239 char buf
[SRCDEST2STR_BUFFER
];
2241 vty_out(vty
, " Nexthop %u:\n", num
);
2242 vty_out(vty
, " type: %u\n", nexthop
->type
);
2243 vty_out(vty
, " flags: %u\n", nexthop
->flags
);
2244 switch (nexthop
->type
) {
2245 case NEXTHOP_TYPE_IPV4
:
2246 case NEXTHOP_TYPE_IPV4_IFINDEX
:
2247 vty_out(vty
, " ip address: %s\n",
2248 inet_ntop(AF_INET
, &nexthop
->gate
.ipv4
, buf
,
2250 vty_out(vty
, " afi: ipv4\n");
2252 if (nexthop
->ifindex
) {
2253 vty_out(vty
, " interface index: %d\n",
2255 vty_out(vty
, " interface name: %s\n",
2256 ifindex2ifname(nexthop
->ifindex
,
2260 if (nexthop
->src
.ipv4
.s_addr
2261 && (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
2263 vty_out(vty
, " source: %s\n", buf
);
2265 case NEXTHOP_TYPE_IPV6
:
2266 case NEXTHOP_TYPE_IPV6_IFINDEX
:
2267 vty_out(vty
, " ip: %s\n",
2268 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
2270 vty_out(vty
, " afi: ipv6\n");
2272 if (nexthop
->ifindex
) {
2273 vty_out(vty
, " interface index: %d\n",
2275 vty_out(vty
, " interface name: %s\n",
2276 ifindex2ifname(nexthop
->ifindex
,
2280 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
2281 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
2283 vty_out(vty
, " source: %s\n", buf
);
2286 case NEXTHOP_TYPE_IFINDEX
:
2288 " Nexthop is an interface (directly connected).\n");
2289 vty_out(vty
, " interface index: %d\n", nexthop
->ifindex
);
2290 vty_out(vty
, " interface name: %s\n",
2291 ifindex2ifname(nexthop
->ifindex
, nexthop
->vrf_id
));
2293 case NEXTHOP_TYPE_BLACKHOLE
:
2294 vty_out(vty
, " Nexthop type is blackhole.\n");
2296 switch (nexthop
->bh_type
) {
2297 case BLACKHOLE_REJECT
:
2298 vty_out(vty
, " Blackhole type: reject\n");
2300 case BLACKHOLE_ADMINPROHIB
:
2302 " Blackhole type: admin-prohibited\n");
2304 case BLACKHOLE_NULL
:
2305 vty_out(vty
, " Blackhole type: NULL0\n");
2307 case BLACKHOLE_UNSPEC
:
2314 static void show_ip_route_dump_vty(struct vty
*vty
, struct route_table
*table
)
2316 struct route_node
*rn
;
2317 struct route_entry
*re
;
2318 char buf
[SRCDEST2STR_BUFFER
];
2323 struct nexthop
*nexthop
= NULL
;
2324 int nexthop_num
= 0;
2326 vty_out(vty
, "\nIPv4/IPv6 Routing table dump\n");
2327 vty_out(vty
, "----------------------------\n");
2329 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
2330 RNODE_FOREACH_RE (rn
, re
) {
2331 vty_out(vty
, "Route: %s\n",
2332 srcdest_rnode2str(rn
, buf
, sizeof(buf
)));
2333 vty_out(vty
, " protocol: %s\n",
2334 zebra_route_string(re
->type
));
2335 vty_out(vty
, " instance: %u\n", re
->instance
);
2336 vty_out(vty
, " VRF ID: %u\n", re
->vrf_id
);
2337 vty_out(vty
, " VRF name: %s\n",
2338 vrf_id_to_name(re
->vrf_id
));
2339 vty_out(vty
, " flags: %u\n", re
->flags
);
2341 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
2342 vty_out(vty
, " distance: %u\n", re
->distance
);
2343 vty_out(vty
, " metric: %u\n", re
->metric
);
2346 vty_out(vty
, " tag: %u\n", re
->tag
);
2348 uptime
= monotime(&tv
);
2349 uptime
-= re
->uptime
;
2350 gmtime_r(&uptime
, &tm
);
2352 if (uptime
< ONE_DAY_SECOND
)
2353 snprintf(time
, sizeof(time
), "%02d:%02d:%02d",
2354 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
2355 else if (uptime
< ONE_WEEK_SECOND
)
2356 snprintf(time
, sizeof(time
), "%dd%02dh%02dm",
2357 tm
.tm_yday
, tm
.tm_hour
, tm
.tm_min
);
2359 snprintf(time
, sizeof(time
), "%02dw%dd%02dh",
2361 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7),
2364 vty_out(vty
, " status: %u\n", re
->status
);
2365 vty_out(vty
, " nexthop_num: %u\n",
2366 nexthop_group_nexthop_num(&(re
->nhe
->nhg
)));
2367 vty_out(vty
, " nexthop_active_num: %u\n",
2368 nexthop_group_active_nexthop_num(
2370 vty_out(vty
, " table: %u\n", re
->table
);
2371 vty_out(vty
, " uptime: %s\n", time
);
2373 for (ALL_NEXTHOPS_PTR(&(re
->nhe
->nhg
), nexthop
)) {
2375 show_ip_route_nht_dump(vty
, nexthop
, re
,
2385 static void vty_show_ip_route_summary(struct vty
*vty
,
2386 struct route_table
*table
, bool use_json
)
2388 struct route_node
*rn
;
2389 struct route_entry
*re
;
2390 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2391 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
2392 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2393 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2394 uint32_t offload_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2395 uint32_t trap_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2398 json_object
*json_route_summary
= NULL
;
2399 json_object
*json_route_routes
= NULL
;
2401 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
2402 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
2403 memset(&offload_cnt
, 0, sizeof(offload_cnt
));
2404 memset(&trap_cnt
, 0, sizeof(trap_cnt
));
2407 json_route_summary
= json_object_new_object();
2408 json_route_routes
= json_object_new_array();
2409 json_object_object_add(json_route_summary
, "routes",
2413 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2414 RNODE_FOREACH_RE (rn
, re
) {
2415 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
2416 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
2418 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2420 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2422 rib_cnt
[re
->type
]++;
2424 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
2425 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2428 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2430 fib_cnt
[re
->type
]++;
2433 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_TRAPPED
)) {
2435 trap_cnt
[ZEBRA_ROUTE_IBGP
]++;
2437 trap_cnt
[re
->type
]++;
2440 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_OFFLOADED
)) {
2442 offload_cnt
[ZEBRA_ROUTE_IBGP
]++;
2444 offload_cnt
[re
->type
]++;
2449 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2451 zvrf_name(((struct rib_table_info
*)
2452 route_table_get_info(table
))
2455 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
2456 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
2457 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
2458 if (i
== ZEBRA_ROUTE_BGP
) {
2460 json_object
*json_route_ebgp
=
2461 json_object_new_object();
2463 json_object_int_add(
2464 json_route_ebgp
, "fib",
2465 fib_cnt
[ZEBRA_ROUTE_BGP
]);
2466 json_object_int_add(
2467 json_route_ebgp
, "rib",
2468 rib_cnt
[ZEBRA_ROUTE_BGP
]);
2469 json_object_int_add(
2470 json_route_ebgp
, "fibOffLoaded",
2471 offload_cnt
[ZEBRA_ROUTE_BGP
]);
2472 json_object_int_add(
2473 json_route_ebgp
, "fibTrapped",
2474 trap_cnt
[ZEBRA_ROUTE_BGP
]);
2476 json_object_string_add(json_route_ebgp
,
2478 json_object_array_add(json_route_routes
,
2481 json_object
*json_route_ibgp
=
2482 json_object_new_object();
2484 json_object_int_add(
2485 json_route_ibgp
, "fib",
2486 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2487 json_object_int_add(
2488 json_route_ibgp
, "rib",
2489 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2490 json_object_int_add(
2491 json_route_ibgp
, "fibOffLoaded",
2492 offload_cnt
[ZEBRA_ROUTE_IBGP
]);
2493 json_object_int_add(
2494 json_route_ibgp
, "fibTrapped",
2495 trap_cnt
[ZEBRA_ROUTE_IBGP
]);
2496 json_object_string_add(json_route_ibgp
,
2498 json_object_array_add(json_route_routes
,
2501 vty_out(vty
, "%-20s %-20d %-20d \n",
2503 rib_cnt
[ZEBRA_ROUTE_BGP
],
2504 fib_cnt
[ZEBRA_ROUTE_BGP
]);
2505 vty_out(vty
, "%-20s %-20d %-20d \n",
2507 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2508 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2512 json_object
*json_route_type
=
2513 json_object_new_object();
2515 json_object_int_add(json_route_type
,
2517 json_object_int_add(json_route_type
,
2520 json_object_int_add(json_route_type
,
2523 json_object_int_add(json_route_type
,
2526 json_object_string_add(
2527 json_route_type
, "type",
2528 zebra_route_string(i
));
2529 json_object_array_add(json_route_routes
,
2532 vty_out(vty
, "%-20s %-20d %-20d \n",
2533 zebra_route_string(i
),
2534 rib_cnt
[i
], fib_cnt
[i
]);
2540 json_object_int_add(json_route_summary
, "routesTotal",
2541 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2542 json_object_int_add(json_route_summary
, "routesTotalFib",
2543 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2545 vty_json(vty
, json_route_summary
);
2547 vty_out(vty
, "------\n");
2548 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2549 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2555 * Implementation of the ip route summary prefix command.
2557 * This command prints the primary prefixes that have been installed by various
2558 * protocols on the box.
2561 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
2562 struct route_table
*table
,
2565 struct route_node
*rn
;
2566 struct route_entry
*re
;
2567 struct nexthop
*nexthop
;
2568 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
2569 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
2570 uint32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2571 uint32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
2574 json_object
*json_route_summary
= NULL
;
2575 json_object
*json_route_routes
= NULL
;
2577 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
2578 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
2581 json_route_summary
= json_object_new_object();
2582 json_route_routes
= json_object_new_array();
2583 json_object_object_add(json_route_summary
, "prefixRoutes",
2587 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2588 RNODE_FOREACH_RE (rn
, re
) {
2591 * In case of ECMP, count only once.
2594 if (CHECK_FLAG(re
->status
, ROUTE_ENTRY_INSTALLED
)) {
2595 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2596 fib_cnt
[re
->type
]++;
2598 for (nexthop
= re
->nhe
->nhg
.nexthop
; (!cnt
&& nexthop
);
2599 nexthop
= nexthop
->next
) {
2601 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
2602 rib_cnt
[re
->type
]++;
2603 if (re
->type
== ZEBRA_ROUTE_BGP
2604 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
2605 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2606 if (CHECK_FLAG(re
->status
,
2607 ROUTE_ENTRY_INSTALLED
))
2608 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
2614 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
2615 "Prefix Routes", "FIB",
2616 zvrf_name(((struct rib_table_info
*)
2617 route_table_get_info(table
))
2620 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
2621 if (rib_cnt
[i
] > 0) {
2622 if (i
== ZEBRA_ROUTE_BGP
) {
2624 json_object
*json_route_ebgp
=
2625 json_object_new_object();
2627 json_object_int_add(
2628 json_route_ebgp
, "fib",
2629 fib_cnt
[ZEBRA_ROUTE_BGP
]
2630 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2631 json_object_int_add(
2632 json_route_ebgp
, "rib",
2633 rib_cnt
[ZEBRA_ROUTE_BGP
]
2634 - rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2635 json_object_string_add(json_route_ebgp
,
2637 json_object_array_add(json_route_routes
,
2640 json_object
*json_route_ibgp
=
2641 json_object_new_object();
2643 json_object_int_add(
2644 json_route_ibgp
, "fib",
2645 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2646 json_object_int_add(
2647 json_route_ibgp
, "rib",
2648 rib_cnt
[ZEBRA_ROUTE_IBGP
]);
2649 json_object_string_add(json_route_ibgp
,
2651 json_object_array_add(json_route_routes
,
2654 vty_out(vty
, "%-20s %-20d %-20d \n",
2656 rib_cnt
[ZEBRA_ROUTE_BGP
]
2657 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
2658 fib_cnt
[ZEBRA_ROUTE_BGP
]
2659 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2660 vty_out(vty
, "%-20s %-20d %-20d \n",
2662 rib_cnt
[ZEBRA_ROUTE_IBGP
],
2663 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
2667 json_object
*json_route_type
=
2668 json_object_new_object();
2670 json_object_int_add(json_route_type
,
2672 json_object_int_add(json_route_type
,
2674 json_object_string_add(
2675 json_route_type
, "type",
2676 zebra_route_string(i
));
2677 json_object_array_add(json_route_routes
,
2680 vty_out(vty
, "%-20s %-20d %-20d \n",
2681 zebra_route_string(i
),
2682 rib_cnt
[i
], fib_cnt
[i
]);
2688 json_object_int_add(json_route_summary
, "prefixRoutesTotal",
2689 rib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2690 json_object_int_add(json_route_summary
, "prefixRoutesTotalFib",
2691 fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2693 vty_json(vty
, json_route_summary
);
2695 vty_out(vty
, "------\n");
2696 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
2697 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
2702 DEFUN (allow_external_route_update
,
2703 allow_external_route_update_cmd
,
2704 "allow-external-route-update",
2705 "Allow FRR routes to be overwritten by external processes\n")
2707 zrouter
.allow_delete
= true;
2712 DEFUN (no_allow_external_route_update
,
2713 no_allow_external_route_update_cmd
,
2714 "no allow-external-route-update",
2716 "Allow FRR routes to be overwritten by external processes\n")
2718 zrouter
.allow_delete
= false;
2731 struct zebra_vrf
*zvrf
;
2733 if (vrf_is_backend_netns())
2734 vty_out(vty
, "netns-based vrfs\n");
2736 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2737 if (!(zvrf
= vrf
->info
))
2739 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2742 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2743 if (zvrf_id(zvrf
) == VRF_UNKNOWN
|| !zvrf_is_active(zvrf
))
2744 vty_out(vty
, "inactive");
2745 else if (zvrf_ns_name(zvrf
))
2746 vty_out(vty
, "id %u netns %s", zvrf_id(zvrf
),
2747 zvrf_ns_name(zvrf
));
2749 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2751 if (vrf_is_user_cfged(vrf
))
2752 vty_out(vty
, " (configured)");
2759 DEFPY (evpn_mh_mac_holdtime
,
2760 evpn_mh_mac_holdtime_cmd
,
2761 "[no$no] evpn mh mac-holdtime (0-86400)$duration",
2766 "Duration in seconds\n")
2768 return zebra_evpn_mh_mac_holdtime_update(vty
, duration
,
2772 DEFPY (evpn_mh_neigh_holdtime
,
2773 evpn_mh_neigh_holdtime_cmd
,
2774 "[no$no] evpn mh neigh-holdtime (0-86400)$duration",
2778 "Neighbor entry hold time\n"
2779 "Duration in seconds\n")
2782 return zebra_evpn_mh_neigh_holdtime_update(vty
, duration
,
2786 DEFPY (evpn_mh_startup_delay
,
2787 evpn_mh_startup_delay_cmd
,
2788 "[no] evpn mh startup-delay(0-3600)$duration",
2793 "duration in seconds\n")
2796 return zebra_evpn_mh_startup_delay_update(vty
, duration
,
2800 DEFPY(evpn_mh_redirect_off
, evpn_mh_redirect_off_cmd
,
2801 "[no$no] evpn mh redirect-off",
2805 "ES bond redirect for fast-failover off\n")
2809 redirect_off
= no
? false : true;
2811 return zebra_evpn_mh_redirect_off(vty
, redirect_off
);
2814 DEFUN (default_vrf_vni_mapping
,
2815 default_vrf_vni_mapping_cmd
,
2816 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2817 "VNI corresponding to the DEFAULT VRF\n"
2819 "Prefix routes only \n")
2821 char xpath
[XPATH_MAXLEN
];
2822 struct zebra_vrf
*zvrf
= NULL
;
2825 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2832 snprintf(xpath
, sizeof(xpath
), FRR_VRF_KEY_XPATH
"/frr-zebra:zebra",
2834 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
2836 snprintf(xpath
, sizeof(xpath
),
2837 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/l3vni-id",
2839 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, argv
[1]->arg
);
2842 snprintf(xpath
, sizeof(xpath
),
2843 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/prefix-only",
2845 nb_cli_enqueue_change(vty
, xpath
, NB_OP_MODIFY
, "true");
2848 return nb_cli_apply_changes(vty
, NULL
);
2851 DEFUN (no_default_vrf_vni_mapping
,
2852 no_default_vrf_vni_mapping_cmd
,
2853 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2855 "VNI corresponding to DEFAULT VRF\n"
2857 "Prefix routes only \n")
2859 char xpath
[XPATH_MAXLEN
];
2861 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2862 struct zebra_vrf
*zvrf
= NULL
;
2864 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2871 if (zvrf
->l3vni
!= vni
) {
2872 vty_out(vty
, "VNI %d doesn't exist in VRF: %s \n", vni
,
2877 snprintf(xpath
, sizeof(xpath
),
2878 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/l3vni-id",
2880 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, argv
[2]->arg
);
2883 snprintf(xpath
, sizeof(xpath
),
2884 FRR_VRF_KEY_XPATH
"/frr-zebra:zebra/prefix-only",
2886 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, "true");
2889 snprintf(xpath
, sizeof(xpath
), FRR_VRF_KEY_XPATH
"/frr-zebra:zebra",
2891 nb_cli_enqueue_change(vty
, xpath
, NB_OP_DESTROY
, NULL
);
2893 return nb_cli_apply_changes(vty
, NULL
);
2896 DEFUN (vrf_vni_mapping
,
2897 vrf_vni_mapping_cmd
,
2898 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2899 "VNI corresponding to tenant VRF\n"
2901 "prefix-routes-only\n")
2905 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
2913 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra", NB_OP_CREATE
, NULL
);
2914 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/l3vni-id", NB_OP_MODIFY
,
2918 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/prefix-only",
2919 NB_OP_MODIFY
, "true");
2921 return nb_cli_apply_changes(vty
, NULL
);
2924 DEFUN (no_vrf_vni_mapping
,
2925 no_vrf_vni_mapping_cmd
,
2926 "no vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2928 "VNI corresponding to tenant VRF\n"
2930 "prefix-routes-only\n")
2934 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
2935 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2943 if (zvrf
->l3vni
!= vni
) {
2944 vty_out(vty
, "VNI %d doesn't exist in VRF: %s \n", vni
,
2949 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/l3vni-id", NB_OP_DESTROY
,
2953 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra/prefix-only",
2954 NB_OP_DESTROY
, "true");
2956 nb_cli_enqueue_change(vty
, "./frr-zebra:zebra", NB_OP_DESTROY
, NULL
);
2958 return nb_cli_apply_changes(vty
, NULL
);
2962 DEFUN (show_vrf_vni
,
2964 "show vrf vni [json]",
2971 struct zebra_vrf
*zvrf
;
2972 json_object
*json
= NULL
;
2973 json_object
*json_vrfs
= NULL
;
2974 bool uj
= use_json(argc
, argv
);
2977 json
= json_object_new_object();
2978 json_vrfs
= json_object_new_array();
2982 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
2983 "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2985 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2990 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2994 json_object_object_add(json
, "vrfs", json_vrfs
);
2995 vty_json(vty
, json
);
3001 DEFUN (show_evpn_global
,
3002 show_evpn_global_cmd
,
3008 bool uj
= use_json(argc
, argv
);
3010 zebra_vxlan_print_evpn(vty
, uj
);
3014 DEFPY(show_evpn_neigh
, show_neigh_cmd
, "show ip neigh",
3015 SHOW_STR IP_STR
"neighbors\n")
3018 zebra_neigh_show(vty
);
3023 DEFPY(show_evpn_l2_nh
,
3024 show_evpn_l2_nh_cmd
,
3025 "show evpn l2-nh [json$json]",
3033 zebra_evpn_l2_nh_show(vty
, uj
);
3040 "show evpn es [NAME$esi_str|detail$detail] [json$json]",
3043 "Ethernet Segment\n"
3045 "Detailed information\n"
3052 if (!str_to_esi(esi_str
, &esi
)) {
3053 vty_out(vty
, "%% Malformed ESI\n");
3056 zebra_evpn_es_show_esi(vty
, uj
, &esi
);
3059 zebra_evpn_es_show_detail(vty
, uj
);
3061 zebra_evpn_es_show(vty
, uj
);
3067 DEFPY(show_evpn_es_evi
,
3068 show_evpn_es_evi_cmd
,
3069 "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]",
3072 "Ethernet Segment per EVI\n"
3073 "VxLAN Network Identifier\n"
3075 "Detailed information\n"
3082 zebra_evpn_es_evi_show_vni(vty
, uj
, vni
, ud
);
3084 zebra_evpn_es_evi_show(vty
, uj
, ud
);
3089 DEFPY(show_evpn_access_vlan
,
3090 show_evpn_access_vlan_cmd
,
3091 "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]",
3096 "Detailed information\n"
3102 zebra_evpn_acc_vl_show_vid(vty
, uj
, vid
);
3105 zebra_evpn_acc_vl_show_detail(vty
, uj
);
3107 zebra_evpn_acc_vl_show(vty
, uj
);
3113 DEFUN (show_evpn_vni
,
3115 "show evpn vni [json]",
3118 "VxLAN Network Identifier\n"
3121 struct zebra_vrf
*zvrf
;
3122 bool uj
= use_json(argc
, argv
);
3124 zvrf
= zebra_vrf_get_evpn();
3125 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
3129 DEFUN (show_evpn_vni_detail
, show_evpn_vni_detail_cmd
,
3130 "show evpn vni detail [json]",
3133 "VxLAN Network Identifier\n"
3134 "Detailed Information On Each VNI\n"
3137 struct zebra_vrf
*zvrf
;
3138 bool uj
= use_json(argc
, argv
);
3140 zvrf
= zebra_vrf_get_evpn();
3141 zebra_vxlan_print_vnis_detail(vty
, zvrf
, uj
);
3145 DEFUN (show_evpn_vni_vni
,
3146 show_evpn_vni_vni_cmd
,
3147 "show evpn vni " CMD_VNI_RANGE
"[json]",
3150 "VxLAN Network Identifier\n"
3154 struct zebra_vrf
*zvrf
;
3156 bool uj
= use_json(argc
, argv
);
3158 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
3159 zvrf
= zebra_vrf_get_evpn();
3160 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
, NULL
);
3164 DEFUN (show_evpn_rmac_vni_mac
,
3165 show_evpn_rmac_vni_mac_cmd
,
3166 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
3173 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
3178 bool uj
= use_json(argc
, argv
);
3180 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3181 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
3182 vty_out(vty
, "%% Malformed MAC address\n");
3185 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
3189 DEFUN (show_evpn_rmac_vni
,
3190 show_evpn_rmac_vni_cmd
,
3191 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
3200 bool uj
= use_json(argc
, argv
);
3202 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3203 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
3208 DEFUN (show_evpn_rmac_vni_all
,
3209 show_evpn_rmac_vni_all_cmd
,
3210 "show evpn rmac vni all [json]",
3218 bool uj
= use_json(argc
, argv
);
3220 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
3225 DEFUN (show_evpn_nh_vni_ip
,
3226 show_evpn_nh_vni_ip_cmd
,
3227 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
3234 "Host address (ipv4 or ipv6)\n"
3239 bool uj
= use_json(argc
, argv
);
3241 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3242 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
3244 vty_out(vty
, "%% Malformed Neighbor address\n");
3247 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
3252 DEFUN (show_evpn_nh_vni
,
3253 show_evpn_nh_vni_cmd
,
3254 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
3263 bool uj
= use_json(argc
, argv
);
3265 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3266 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
3271 DEFUN (show_evpn_nh_vni_all
,
3272 show_evpn_nh_vni_all_cmd
,
3273 "show evpn next-hops vni all [json]",
3281 bool uj
= use_json(argc
, argv
);
3283 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
3288 DEFUN (show_evpn_mac_vni
,
3289 show_evpn_mac_vni_cmd
,
3290 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
3294 "VxLAN Network Identifier\n"
3298 struct zebra_vrf
*zvrf
;
3300 bool uj
= use_json(argc
, argv
);
3302 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3303 zvrf
= zebra_vrf_get_evpn();
3304 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
3308 DEFUN (show_evpn_mac_vni_all
,
3309 show_evpn_mac_vni_all_cmd
,
3310 "show evpn mac vni all [json]",
3314 "VxLAN Network Identifier\n"
3318 struct zebra_vrf
*zvrf
;
3319 bool uj
= use_json(argc
, argv
);
3321 zvrf
= zebra_vrf_get_evpn();
3322 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, false, uj
);
3326 DEFUN (show_evpn_mac_vni_all_detail
, show_evpn_mac_vni_all_detail_cmd
,
3327 "show evpn mac vni all detail [json]",
3331 "VxLAN Network Identifier\n"
3333 "Detailed Information On Each VNI MAC\n"
3336 struct zebra_vrf
*zvrf
;
3337 bool uj
= use_json(argc
, argv
);
3339 zvrf
= zebra_vrf_get_evpn();
3340 zebra_vxlan_print_macs_all_vni_detail(vty
, zvrf
, false, uj
);
3344 DEFUN (show_evpn_mac_vni_all_vtep
,
3345 show_evpn_mac_vni_all_vtep_cmd
,
3346 "show evpn mac vni all vtep A.B.C.D [json]",
3350 "VxLAN Network Identifier\n"
3353 "Remote VTEP IP address\n"
3356 struct zebra_vrf
*zvrf
;
3357 struct in_addr vtep_ip
;
3358 bool uj
= use_json(argc
, argv
);
3360 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3362 vty_out(vty
, "%% Malformed VTEP IP address\n");
3365 zvrf
= zebra_vrf_get_evpn();
3366 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
3372 DEFUN (show_evpn_mac_vni_mac
,
3373 show_evpn_mac_vni_mac_cmd
,
3374 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD [json]",
3378 "VxLAN Network Identifier\n"
3381 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3385 struct zebra_vrf
*zvrf
;
3388 bool uj
= use_json(argc
, argv
);
3390 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3391 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
3392 vty_out(vty
, "%% Malformed MAC address\n");
3395 zvrf
= zebra_vrf_get_evpn();
3396 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
, uj
);
3400 DEFUN (show_evpn_mac_vni_vtep
,
3401 show_evpn_mac_vni_vtep_cmd
,
3402 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
3406 "VxLAN Network Identifier\n"
3409 "Remote VTEP IP address\n"
3412 struct zebra_vrf
*zvrf
;
3414 struct in_addr vtep_ip
;
3415 bool uj
= use_json(argc
, argv
);
3417 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3418 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3420 vty_out(vty
, "%% Malformed VTEP IP address\n");
3424 zvrf
= zebra_vrf_get_evpn();
3425 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
3429 DEFPY (show_evpn_mac_vni_all_dad
,
3430 show_evpn_mac_vni_all_dad_cmd
,
3431 "show evpn mac vni all duplicate [json]",
3435 "VxLAN Network Identifier\n"
3437 "Duplicate address list\n"
3440 struct zebra_vrf
*zvrf
;
3441 bool uj
= use_json(argc
, argv
);
3443 zvrf
= zebra_vrf_get_evpn();
3444 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, true, uj
);
3449 DEFPY (show_evpn_mac_vni_dad
,
3450 show_evpn_mac_vni_dad_cmd
,
3451 "show evpn mac vni " CMD_VNI_RANGE
" duplicate [json]",
3455 "VxLAN Network Identifier\n"
3457 "Duplicate address list\n"
3460 struct zebra_vrf
*zvrf
;
3461 bool uj
= use_json(argc
, argv
);
3463 zvrf
= zebra_vrf_get_evpn();
3465 zebra_vxlan_print_macs_vni_dad(vty
, zvrf
, vni
, uj
);
3470 DEFPY (show_evpn_neigh_vni_dad
,
3471 show_evpn_neigh_vni_dad_cmd
,
3472 "show evpn arp-cache vni " CMD_VNI_RANGE
"duplicate [json]",
3475 "ARP and ND cache\n"
3476 "VxLAN Network Identifier\n"
3478 "Duplicate address list\n"
3481 struct zebra_vrf
*zvrf
;
3482 bool uj
= use_json(argc
, argv
);
3484 zvrf
= zebra_vrf_get_evpn();
3485 zebra_vxlan_print_neigh_vni_dad(vty
, zvrf
, vni
, uj
);
3489 DEFPY (show_evpn_neigh_vni_all_dad
,
3490 show_evpn_neigh_vni_all_dad_cmd
,
3491 "show evpn arp-cache vni all duplicate [json]",
3494 "ARP and ND cache\n"
3495 "VxLAN Network Identifier\n"
3497 "Duplicate address list\n"
3500 struct zebra_vrf
*zvrf
;
3501 bool uj
= use_json(argc
, argv
);
3503 zvrf
= zebra_vrf_get_evpn();
3504 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, true, uj
);
3509 DEFUN (show_evpn_neigh_vni
,
3510 show_evpn_neigh_vni_cmd
,
3511 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
3514 "ARP and ND cache\n"
3515 "VxLAN Network Identifier\n"
3519 struct zebra_vrf
*zvrf
;
3521 bool uj
= use_json(argc
, argv
);
3523 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3524 zvrf
= zebra_vrf_get_evpn();
3525 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
3529 DEFUN (show_evpn_neigh_vni_all
,
3530 show_evpn_neigh_vni_all_cmd
,
3531 "show evpn arp-cache vni all [json]",
3534 "ARP and ND cache\n"
3535 "VxLAN Network Identifier\n"
3539 struct zebra_vrf
*zvrf
;
3540 bool uj
= use_json(argc
, argv
);
3542 zvrf
= zebra_vrf_get_evpn();
3543 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, false, uj
);
3547 DEFUN (show_evpn_neigh_vni_all_detail
, show_evpn_neigh_vni_all_detail_cmd
,
3548 "show evpn arp-cache vni all detail [json]",
3551 "ARP and ND cache\n"
3552 "VxLAN Network Identifier\n"
3554 "Neighbor details for all vnis in detail\n" JSON_STR
)
3556 struct zebra_vrf
*zvrf
;
3557 bool uj
= use_json(argc
, argv
);
3559 zvrf
= zebra_vrf_get_evpn();
3560 zebra_vxlan_print_neigh_all_vni_detail(vty
, zvrf
, false, uj
);
3564 DEFUN (show_evpn_neigh_vni_neigh
,
3565 show_evpn_neigh_vni_neigh_cmd
,
3566 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
3569 "ARP and ND cache\n"
3570 "VxLAN Network Identifier\n"
3573 "Neighbor address (IPv4 or IPv6 address)\n"
3576 struct zebra_vrf
*zvrf
;
3579 bool uj
= use_json(argc
, argv
);
3581 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3582 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
3584 vty_out(vty
, "%% Malformed Neighbor address\n");
3587 zvrf
= zebra_vrf_get_evpn();
3588 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
3592 DEFUN (show_evpn_neigh_vni_vtep
,
3593 show_evpn_neigh_vni_vtep_cmd
,
3594 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
3597 "ARP and ND cache\n"
3598 "VxLAN Network Identifier\n"
3601 "Remote VTEP IP address\n"
3604 struct zebra_vrf
*zvrf
;
3606 struct in_addr vtep_ip
;
3607 bool uj
= use_json(argc
, argv
);
3609 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3610 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3612 vty_out(vty
, "%% Malformed VTEP IP address\n");
3616 zvrf
= zebra_vrf_get_evpn();
3617 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
3621 /* policy routing contexts */
3622 DEFUN (show_pbr_ipset
,
3624 "show pbr ipset [WORD]",
3626 "Policy-Based Routing\n"
3627 "IPset Context information\n"
3628 "IPset Name information\n")
3632 found
= argv_find(argv
, argc
, "WORD", &idx
);
3634 zebra_pbr_show_ipset_list(vty
, NULL
);
3636 zebra_pbr_show_ipset_list(vty
, argv
[idx
]->arg
);
3640 /* policy routing contexts */
3641 DEFUN (show_pbr_iptable
,
3642 show_pbr_iptable_cmd
,
3643 "show pbr iptable [WORD]",
3645 "Policy-Based Routing\n"
3646 "IPtable Context information\n"
3647 "IPtable Name information\n")
3652 found
= argv_find(argv
, argc
, "WORD", &idx
);
3654 zebra_pbr_show_iptable(vty
, NULL
);
3656 zebra_pbr_show_iptable(vty
, argv
[idx
]->arg
);
3660 /* policy routing contexts */
3661 DEFPY (show_pbr_rule
,
3665 "Policy-Based Routing\n"
3668 zebra_pbr_show_rule(vty
);
3672 DEFPY (pbr_nexthop_resolve
,
3673 pbr_nexthop_resolve_cmd
,
3674 "[no$no] pbr nexthop-resolve",
3676 "Policy Based Routing\n"
3677 "Resolve nexthop for dataplane programming\n")
3679 zebra_pbr_expand_action_update(!no
);
3683 DEFPY (clear_evpn_dup_addr
,
3684 clear_evpn_dup_addr_cmd
,
3685 "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>]>",
3688 "Duplicate address \n"
3689 "VxLAN Network Identifier\n"
3693 "MAC address (e.g., 00:e0:ec:20:12:62)\n"
3698 struct ipaddr host_ip
= {.ipa_type
= IPADDR_NONE
};
3699 int ret
= CMD_SUCCESS
;
3701 struct yang_data
*yang_dup
= NULL
, *yang_dup_ip
= NULL
,
3702 *yang_dup_mac
= NULL
;
3707 yang_dup
= yang_data_new(
3708 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice",
3711 yang_dup
= yang_data_new_uint32(
3712 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id",
3714 if (!is_zero_mac(&mac
->eth_addr
)) {
3715 yang_dup_mac
= yang_data_new_mac(
3716 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr",
3719 listnode_add(input
, yang_dup_mac
);
3721 if (sockunion_family(ip
) == AF_INET
) {
3722 host_ip
.ipa_type
= IPADDR_V4
;
3723 host_ip
.ipaddr_v4
.s_addr
= sockunion2ip(ip
);
3725 host_ip
.ipa_type
= IPADDR_V6
;
3726 memcpy(&host_ip
.ipaddr_v6
, &ip
->sin6
.sin6_addr
,
3727 sizeof(struct in6_addr
));
3730 yang_dup_ip
= yang_data_new_ip(
3731 "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr",
3735 listnode_add(input
, yang_dup_ip
);
3740 listnode_add(input
, yang_dup
);
3741 ret
= nb_cli_rpc(vty
, "/frr-zebra:clear-evpn-dup-addr", input
,
3745 list_delete(&input
);
3750 DEFPY_HIDDEN (evpn_accept_bgp_seq
,
3751 evpn_accept_bgp_seq_cmd
,
3752 "evpn accept-bgp-seq",
3754 "Accept all sequence numbers from BGP\n")
3756 zebra_vxlan_set_accept_bgp_seq(true);
3760 DEFPY_HIDDEN (no_evpn_accept_bgp_seq
,
3761 no_evpn_accept_bgp_seq_cmd
,
3762 "no evpn accept-bgp-seq",
3765 "Accept all sequence numbers from BGP\n")
3767 zebra_vxlan_set_accept_bgp_seq(false);
3771 /* Static ip route configuration write function. */
3772 static int zebra_ip_config(struct vty
*vty
)
3776 write
+= zebra_import_table_config(vty
, VRF_DEFAULT
);
3781 DEFUN (ip_zebra_import_table_distance
,
3782 ip_zebra_import_table_distance_cmd
,
3783 "ip import-table (1-252) [distance (1-255)] [route-map RMAP_NAME]",
3785 "import routes from non-main kernel table\n"
3786 "kernel routing table id\n"
3787 "Distance for imported routes\n"
3788 "Default distance value\n"
3789 "route-map for filtering\n"
3792 uint32_t table_id
= 0;
3794 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
3795 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
3797 strmatch(argv
[argc
- 2]->text
, "route-map")
3798 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
3802 if (argc
== 7 || (argc
== 5 && !rmap
))
3803 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
3805 if (!is_zebra_valid_kernel_table(table_id
)) {
3807 "Invalid routing table ID, %d. Must be in range 1-252\n",
3810 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3814 if (is_zebra_main_routing_table(table_id
)) {
3816 "Invalid routing table ID, %d. Must be non-default table\n",
3819 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3823 ret
= zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
,
3826 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3831 DEFUN_HIDDEN (zebra_packet_process
,
3832 zebra_packet_process_cmd
,
3833 "zebra zapi-packets (1-10000)",
3836 "Number of packets to process before relinquishing thread\n")
3838 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3840 atomic_store_explicit(&zrouter
.packets_to_process
, packets
,
3841 memory_order_relaxed
);
3846 DEFUN_HIDDEN (no_zebra_packet_process
,
3847 no_zebra_packet_process_cmd
,
3848 "no zebra zapi-packets [(1-10000)]",
3852 "Number of packets to process before relinquishing thread\n")
3854 atomic_store_explicit(&zrouter
.packets_to_process
,
3855 ZEBRA_ZAPI_PACKETS_TO_PROCESS
,
3856 memory_order_relaxed
);
3861 DEFUN_HIDDEN (zebra_workqueue_timer
,
3862 zebra_workqueue_timer_cmd
,
3863 "zebra work-queue (0-10000)",
3866 "Time in milliseconds\n")
3868 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3869 zrouter
.ribq
->spec
.hold
= timer
;
3874 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3875 no_zebra_workqueue_timer_cmd
,
3876 "no zebra work-queue [(0-10000)]",
3880 "Time in milliseconds\n")
3882 zrouter
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3887 DEFUN (no_ip_zebra_import_table
,
3888 no_ip_zebra_import_table_cmd
,
3889 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3892 "import routes from non-main kernel table\n"
3893 "kernel routing table id\n"
3894 "Distance for imported routes\n"
3895 "Default distance value\n"
3896 "route-map for filtering\n"
3899 uint32_t table_id
= 0;
3900 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3902 if (!is_zebra_valid_kernel_table(table_id
)) {
3904 "Invalid routing table ID. Must be in range 1-252\n");
3908 if (is_zebra_main_routing_table(table_id
)) {
3910 "Invalid routing table ID, %d. Must be non-default table\n",
3915 if (!is_zebra_import_table_enabled(AFI_IP
, VRF_DEFAULT
, table_id
))
3918 return (zebra_import_table(AFI_IP
, VRF_DEFAULT
, table_id
, 0, NULL
, 0));
3921 DEFPY (zebra_nexthop_group_keep
,
3922 zebra_nexthop_group_keep_cmd
,
3923 "[no] zebra nexthop-group keep (1-3600)",
3927 "How long to keep\n"
3928 "Time in seconds from 1-3600\n")
3931 zrouter
.nhg_keep
= ZEBRA_DEFAULT_NHG_KEEP_TIMER
;
3933 zrouter
.nhg_keep
= keep
;
3938 static int config_write_protocol(struct vty
*vty
)
3940 if (zrouter
.allow_delete
)
3941 vty_out(vty
, "allow-external-route-update\n");
3943 if (zrouter
.nhg_keep
!= ZEBRA_DEFAULT_NHG_KEEP_TIMER
)
3944 vty_out(vty
, "zebra nexthop-group keep %u\n", zrouter
.nhg_keep
);
3946 if (zrouter
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3947 vty_out(vty
, "zebra work-queue %u\n", zrouter
.ribq
->spec
.hold
);
3949 if (zrouter
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3950 vty_out(vty
, "zebra zapi-packets %u\n",
3951 zrouter
.packets_to_process
);
3953 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3955 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3956 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3957 ipv4_multicast_mode
== MCAST_URIB_ONLY
3959 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3961 : ipv4_multicast_mode
3962 == MCAST_MIX_MRIB_FIRST
3964 : ipv4_multicast_mode
3965 == MCAST_MIX_DISTANCE
3969 /* Include dataplane info */
3970 dplane_config_write_helper(vty
);
3972 zebra_evpn_mh_config_write(vty
);
3974 zebra_pbr_config_write(vty
);
3976 if (!zebra_vxlan_get_accept_bgp_seq())
3977 vty_out(vty
, "no evpn accept-bgp-seq\n");
3979 /* Include nexthop-group config */
3980 if (!zebra_nhg_kernel_nexthops_enabled())
3981 vty_out(vty
, "no zebra nexthop kernel enable\n");
3983 if (zebra_nhg_proto_nexthops_only())
3984 vty_out(vty
, "zebra nexthop proto only\n");
3986 if (!zebra_nhg_recursive_use_backups())
3987 vty_out(vty
, "no zebra nexthop resolve-via-backup\n");
3989 if (rnh_get_hide_backups())
3990 vty_out(vty
, "ip nht hide-backup-events\n");
3993 /* Include netlink info */
3994 netlink_config_write_helper(vty
);
3995 #endif /* HAVE_NETLINK */
4007 struct ttable
*table
= ttable_new(&ttable_styles
[TTSTYLE_BLANK
]);
4010 ttable_rowseps(table
, 0, BOTTOM
, true, '-');
4011 ttable_add_row(table
, "OS|%s(%s)", cmd_system_get(), cmd_release_get());
4012 ttable_add_row(table
, "ECMP Maximum|%d", zrouter
.multipath_num
);
4013 ttable_add_row(table
, "v4 Forwarding|%s", ipforward() ? "On" : "Off");
4014 ttable_add_row(table
, "v6 Forwarding|%s",
4015 ipforward_ipv6() ? "On" : "Off");
4016 ttable_add_row(table
, "MPLS|%s", mpls_enabled
? "On" : "Off");
4017 ttable_add_row(table
, "EVPN|%s", is_evpn_enabled() ? "On" : "Off");
4018 ttable_add_row(table
, "Kernel socket buffer size|%d", rcvbufsize
);
4022 if (!vrf_is_backend_netns())
4023 ttable_add_row(table
, "VRF|l3mdev Available");
4025 ttable_add_row(table
, "VRF|Namespaces");
4027 ttable_add_row(table
, "VRF|Not Available");
4030 ttable_add_row(table
, "ASIC offload|%s",
4031 zrouter
.asic_offloaded
? "Used" : "Unavailable");
4033 ttable_add_row(table
, "RA|%s",
4034 rtadv_compiled_in() ? "Compiled in" : "Not Compiled in");
4035 ttable_add_row(table
, "RFC 5549|%s",
4036 rtadv_get_interfaces_configured_from_bgp()
4038 : "BGP is not using");
4040 ttable_add_row(table
, "Kernel NHG|%s",
4041 zrouter
.supports_nhgs
? "Available" : "Unavailable");
4043 ttable_add_row(table
, "Allow Non FRR route deletion|%s",
4044 zrouter
.allow_delete
? "Yes" : "No");
4045 ttable_add_row(table
, "v4 All LinkDown Routes|%s",
4046 zrouter
.all_linkdownv4
? "On" : "Off");
4047 ttable_add_row(table
, "v4 Default LinkDown Routes|%s",
4048 zrouter
.default_linkdownv4
? "On" : "Off");
4049 ttable_add_row(table
, "v6 All LinkDown Routes|%s",
4050 zrouter
.all_linkdownv6
? "On" : "Off");
4051 ttable_add_row(table
, "v6 Default LinkDown Routes|%s",
4052 zrouter
.default_linkdownv6
? "On" : "Off");
4054 ttable_add_row(table
, "v4 All MC Forwarding|%s",
4055 zrouter
.all_mc_forwardingv4
? "On" : "Off");
4056 ttable_add_row(table
, "v4 Default MC Forwarding|%s",
4057 zrouter
.default_mc_forwardingv4
? "On" : "Off");
4058 ttable_add_row(table
, "v6 All MC Forwarding|%s",
4059 zrouter
.all_mc_forwardingv6
? "On" : "Off");
4060 ttable_add_row(table
, "v6 Default MC Forwarding|%s",
4061 zrouter
.default_mc_forwardingv6
? "On" : "Off");
4063 out
= ttable_dump(table
, "\n");
4064 vty_out(vty
, "%s\n", out
);
4065 XFREE(MTYPE_TMP
, out
);
4069 " Route Route Neighbor LSP LSP\n");
4071 "VRF Installs Removals Updates Installs Removals\n");
4073 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
4074 struct zebra_vrf
*zvrf
= vrf
->info
;
4076 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
" %10" PRIu64
"\n",
4077 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
4078 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
4079 zvrf
->lsp_removals
);
4085 DEFUN (ip_forwarding
,
4089 "Turn on IP forwarding\n")
4095 ret
= ipforward_on();
4098 vty_out(vty
, "Can't turn on IP forwarding\n");
4099 return CMD_WARNING_CONFIG_FAILED
;
4105 DEFUN (no_ip_forwarding
,
4106 no_ip_forwarding_cmd
,
4110 "Turn off IP forwarding\n")
4116 ret
= ipforward_off();
4119 vty_out(vty
, "Can't turn off IP forwarding\n");
4120 return CMD_WARNING_CONFIG_FAILED
;
4126 /* Only display ip forwarding is enabled or not. */
4127 DEFUN (show_ip_forwarding
,
4128 show_ip_forwarding_cmd
,
4129 "show ip forwarding",
4132 "IP forwarding status\n")
4139 vty_out(vty
, "IP forwarding is off\n");
4141 vty_out(vty
, "IP forwarding is on\n");
4145 /* Only display ipv6 forwarding is enabled or not. */
4146 DEFUN (show_ipv6_forwarding
,
4147 show_ipv6_forwarding_cmd
,
4148 "show ipv6 forwarding",
4150 "IPv6 information\n"
4151 "Forwarding status\n")
4155 ret
= ipforward_ipv6();
4159 vty_out(vty
, "ipv6 forwarding is unknown\n");
4162 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
4165 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
4168 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
4174 DEFUN (ipv6_forwarding
,
4175 ipv6_forwarding_cmd
,
4178 "Turn on IPv6 forwarding\n")
4182 ret
= ipforward_ipv6();
4184 ret
= ipforward_ipv6_on();
4187 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
4188 return CMD_WARNING_CONFIG_FAILED
;
4194 DEFUN (no_ipv6_forwarding
,
4195 no_ipv6_forwarding_cmd
,
4196 "no ipv6 forwarding",
4199 "Turn off IPv6 forwarding\n")
4203 ret
= ipforward_ipv6();
4205 ret
= ipforward_ipv6_off();
4208 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
4209 return CMD_WARNING_CONFIG_FAILED
;
4215 /* Display dataplane info */
4216 DEFUN (show_dataplane
,
4218 "show zebra dplane [detailed]",
4221 "Zebra dataplane information\n"
4222 "Detailed output\n")
4225 bool detailed
= false;
4227 if (argv_find(argv
, argc
, "detailed", &idx
))
4230 return dplane_show_helper(vty
, detailed
);
4233 /* Display dataplane providers info */
4234 DEFUN (show_dataplane_providers
,
4235 show_dataplane_providers_cmd
,
4236 "show zebra dplane providers [detailed]",
4239 "Zebra dataplane information\n"
4240 "Zebra dataplane provider information\n"
4241 "Detailed output\n")
4244 bool detailed
= false;
4246 if (argv_find(argv
, argc
, "detailed", &idx
))
4249 return dplane_show_provs_helper(vty
, detailed
);
4252 /* Configure dataplane incoming queue limit */
4253 DEFUN (zebra_dplane_queue_limit
,
4254 zebra_dplane_queue_limit_cmd
,
4255 "zebra dplane limit (0-10000)",
4258 "Limit incoming queued updates\n"
4259 "Number of queued updates\n")
4263 limit
= strtoul(argv
[3]->arg
, NULL
, 10);
4265 dplane_set_in_queue_limit(limit
, true);
4270 /* Reset dataplane queue limit to default value */
4271 DEFUN (no_zebra_dplane_queue_limit
,
4272 no_zebra_dplane_queue_limit_cmd
,
4273 "no zebra dplane limit [(0-10000)]",
4277 "Limit incoming queued updates\n"
4278 "Number of queued updates\n")
4280 dplane_set_in_queue_limit(0, false);
4285 DEFUN (zebra_show_routing_tables_summary
,
4286 zebra_show_routing_tables_summary_cmd
,
4287 "show zebra router table summary",
4290 "The Zebra Router Information\n"
4291 "Table Information about this Zebra Router\n"
4292 "Summary Information\n")
4294 zebra_router_show_table_summary(vty
);
4299 /* Table configuration write function. */
4300 static int config_write_table(struct vty
*vty
)
4305 /* IPForwarding configuration write function. */
4306 static int config_write_forwarding(struct vty
*vty
)
4309 vty_out(vty
, "no ip forwarding\n");
4310 if (!ipforward_ipv6())
4311 vty_out(vty
, "no ipv6 forwarding\n");
4312 vty_out(vty
, "!\n");
4316 DEFUN_HIDDEN (show_frr
,
4322 vty_out(vty
, "........ .. . .. . ..... ...77:................................................\n");
4323 vty_out(vty
, ".............................7777:..............................................\n");
4324 vty_out(vty
, ".............................777777,............................................\n");
4325 vty_out(vty
, "... .........................77777777,..........................................\n");
4326 vty_out(vty
, "............................=7777777777:........................................\n");
4327 vty_out(vty
, "........................:7777777777777777,......................................\n");
4328 vty_out(vty
, ".................... ~7777777777777?~,..........................................\n");
4329 vty_out(vty
, "...................I7777777777+.................................................\n");
4330 vty_out(vty
, "................,777777777?............ .......................................\n");
4331 vty_out(vty
, "..............:77777777?..........~?77777.......................................\n");
4332 vty_out(vty
, ".............77777777~........=7777777777.......................................\n");
4333 vty_out(vty
, ".......... +7777777,.......?7777777777777.......................................\n");
4334 vty_out(vty
, "..........7777777~......:7777777777777777......77?,.............................\n");
4335 vty_out(vty
, "........:777777?......+777777777777777777......777777I,.........................\n");
4336 vty_out(vty
, ".......?777777,.....+77777777777777777777......777777777?.......................\n");
4337 vty_out(vty
, "......?777777......7777777777777777777777......,?777777777?.....................\n");
4338 vty_out(vty
, ".....?77777?.....=7777777777777777777I~............,I7777777~...................\n");
4339 vty_out(vty
, "....+77777+.....I77777777777777777:...................+777777I..................\n");
4340 vty_out(vty
, "...~77777+.....7777777777777777=........................?777777...... .......\n");
4341 vty_out(vty
, "...77777I.....I77777777777777~.........:?................,777777.....I777.......\n");
4342 vty_out(vty
, "..777777.....I7777777777777I .......?7777..................777777.....777?......\n");
4343 vty_out(vty
, ".~77777,....=7777777777777:......,7777777..................,77777+....+777......\n");
4344 vty_out(vty
, ".77777I.....7777777777777,......777777777.......ONNNN.......=77777.....777~.....\n");
4345 vty_out(vty
, ",77777.....I777777777777,.....:7777777777......DNNNNNN.......77777+ ...7777.....\n");
4346 vty_out(vty
, "I7777I.....777777777777=.....~77777777777......NNNNNNN~......=7777I....=777.....\n");
4347 vty_out(vty
, "77777:....=777777777777.....,777777777777......$NNNNND ......:77777....:777.....\n");
4348 vty_out(vty
, "77777. ...777777777777~.....7777777777777........7DZ,........:77777.....777.....\n");
4349 vty_out(vty
, "????? . ..777777777777.....,7777777777777....................:77777I....777.....\n");
4350 vty_out(vty
, "....... ..777777777777.....+7777777777777....................=7777777+...?7.....\n");
4351 vty_out(vty
, "..........77777777777I.....I7777777777777....................7777777777:........\n");
4352 vty_out(vty
, "..........77777777777I.....?7777777777777...................~777777777777.......\n");
4353 vty_out(vty
, "..........777777777777.....~7777777777777..................,77777777777777+.....\n");
4354 vty_out(vty
, "..........777777777777......7777777777777..................77777777777777777,...\n");
4355 vty_out(vty
, "..... ....?77777777777I.....~777777777777................,777777.....,:+77777I..\n");
4356 vty_out(vty
, "........ .:777777777777,.....?77777777777...............?777777..............,:=\n");
4357 vty_out(vty
, ".......... 7777777777777..... ?7777777777.............=7777777.....~777I........\n");
4358 vty_out(vty
, "...........:777777777777I......~777777777...........I7777777~.....+777I.........\n");
4359 vty_out(vty
, "..... ......7777777777777I.......I7777777.......+777777777I......7777I..........\n");
4360 vty_out(vty
, ".............77777777777777........?77777......777777777?......=7777=...........\n");
4361 vty_out(vty
, ".............,77777777777777+.........~77......777777I,......:77777.............\n");
4362 vty_out(vty
, "..............~777777777777777~................777777......:77777=..............\n");
4363 vty_out(vty
, "...............:7777777777777777?..............:777777,.....=77=................\n");
4364 vty_out(vty
, "................,777777777777777777?,...........,777777:.....,..................\n");
4365 vty_out(vty
, "........... ......I777777777777777777777I.........777777~.......................\n");
4366 vty_out(vty
, "...................,777777777777777777777..........777777+......................\n");
4367 vty_out(vty
, ".....................+7777777777777777777...........777777?.....................\n");
4368 vty_out(vty
, ".......................=77777777777777777............777777I....................\n");
4369 vty_out(vty
, ".........................:777777777777777.............I77777I...................\n");
4370 vty_out(vty
, "............................~777777777777..............+777777..................\n");
4371 vty_out(vty
, "................................~77777777...............=777777.................\n");
4372 vty_out(vty
, ".....................................:=?I................~777777................\n");
4373 vty_out(vty
, "..........................................................:777777,..............\n");
4374 vty_out(vty
, ".... ... ... . . .... ....... ....... ....................:777777..............\n");
4380 DEFUN_HIDDEN(zebra_kernel_netlink_batch_tx_buf
,
4381 zebra_kernel_netlink_batch_tx_buf_cmd
,
4382 "zebra kernel netlink batch-tx-buf (1-1048576) (1-1048576)",
4384 "Zebra kernel interface\n"
4385 "Set Netlink parameters\n"
4386 "Set batch buffer size and send threshold\n"
4387 "Size of the buffer\n"
4390 uint32_t bufsize
= 0, threshold
= 0;
4392 bufsize
= strtoul(argv
[4]->arg
, NULL
, 10);
4393 threshold
= strtoul(argv
[5]->arg
, NULL
, 10);
4395 netlink_set_batch_buffer_size(bufsize
, threshold
, true);
4400 DEFUN_HIDDEN(no_zebra_kernel_netlink_batch_tx_buf
,
4401 no_zebra_kernel_netlink_batch_tx_buf_cmd
,
4402 "no zebra kernel netlink batch-tx-buf [(0-1048576)] [(0-1048576)]",
4404 "Zebra kernel interface\n"
4405 "Set Netlink parameters\n"
4406 "Set batch buffer size and send threshold\n"
4407 "Size of the buffer\n"
4410 netlink_set_batch_buffer_size(0, 0, false);
4415 DEFPY (zebra_protodown_bit
,
4416 zebra_protodown_bit_cmd
,
4417 "zebra protodown reason-bit (0-31)$bit",
4419 "Protodown Configuration\n"
4420 "Reason Bit used in the kernel for application\n"
4421 "Reason Bit range\n")
4423 if_netlink_set_frr_protodown_r_bit(bit
);
4427 DEFPY (no_zebra_protodown_bit
,
4428 no_zebra_protodown_bit_cmd
,
4429 "no zebra protodown reason-bit [(0-31)$bit]",
4432 "Protodown Configuration\n"
4433 "Reason Bit used in the kernel for setting protodown\n"
4434 "Reason Bit Range\n")
4436 if_netlink_unset_frr_protodown_r_bit();
4440 #endif /* HAVE_NETLINK */
4442 DEFUN(ip_table_range
, ip_table_range_cmd
,
4443 "[no] ip table range (1-4294967295) (1-4294967295)",
4445 "table configuration\n"
4446 "Configure table range\n"
4447 "Start Routing Table\n"
4448 "End Routing Table\n")
4450 ZEBRA_DECLVAR_CONTEXT_VRF(vrf
, zvrf
);
4455 if (zvrf_id(zvrf
) != VRF_DEFAULT
&& !vrf_is_backend_netns()) {
4457 "VRF subcommand does not make any sense in l3mdev based vrf's\n");
4461 if (strmatch(argv
[0]->text
, "no"))
4462 return table_manager_range(vty
, false, zvrf
, NULL
, NULL
);
4464 return table_manager_range(vty
, true, zvrf
, argv
[3]->arg
, argv
[4]->arg
);
4467 #ifdef HAVE_SCRIPTING
4469 DEFUN(zebra_on_rib_process_script
, zebra_on_rib_process_script_cmd
,
4470 "zebra on-rib-process script SCRIPT",
4472 "on_rib_process_dplane_results hook call\n"
4474 "Script name (same as filename in /etc/frr/scripts/, without .lua)\n")
4477 if (frrscript_names_set_script_name(ZEBRA_ON_RIB_PROCESS_HOOK_CALL
,
4480 vty_out(vty
, "Successfully added script %s for hook call %s\n",
4481 argv
[3]->arg
, ZEBRA_ON_RIB_PROCESS_HOOK_CALL
);
4483 vty_out(vty
, "Failed to add script %s for hook call %s\n",
4484 argv
[3]->arg
, ZEBRA_ON_RIB_PROCESS_HOOK_CALL
);
4489 #endif /* HAVE_SCRIPTING */
4491 /* IP node for static routes. */
4492 static int zebra_ip_config(struct vty
*vty
);
4493 static struct cmd_node ip_node
= {
4494 .name
= "static ip",
4497 .config_write
= zebra_ip_config
,
4499 static int config_write_protocol(struct vty
*vty
);
4500 static struct cmd_node protocol_node
= {
4502 .node
= PROTOCOL_NODE
,
4504 .config_write
= config_write_protocol
,
4506 /* table node for routing tables. */
4507 static int config_write_table(struct vty
*vty
);
4508 static struct cmd_node table_node
= {
4512 .config_write
= config_write_table
,
4514 static int config_write_forwarding(struct vty
*vty
);
4515 static struct cmd_node forwarding_node
= {
4516 .name
= "forwarding",
4517 .node
= FORWARDING_NODE
,
4519 .config_write
= config_write_forwarding
,
4523 void zebra_vty_init(void)
4525 /* Install configuration write function. */
4526 install_node(&table_node
);
4527 install_node(&forwarding_node
);
4529 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
4530 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
4531 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
4532 install_element(ENABLE_NODE
, &show_zebra_cmd
);
4534 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
4535 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
4536 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
4539 zebra_route_map_init();
4541 install_node(&ip_node
);
4542 install_node(&protocol_node
);
4544 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
4545 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
4547 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
4548 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
4550 install_element(CONFIG_NODE
, &zebra_nexthop_group_keep_cmd
);
4551 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
4552 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
4553 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
4554 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
4555 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
4556 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
4557 install_element(CONFIG_NODE
, &nexthop_group_use_enable_cmd
);
4558 install_element(CONFIG_NODE
, &proto_nexthop_group_only_cmd
);
4559 install_element(CONFIG_NODE
, &backup_nexthop_recursive_use_enable_cmd
);
4561 install_element(VIEW_NODE
, &show_nexthop_group_cmd
);
4562 install_element(VIEW_NODE
, &show_interface_nexthop_group_cmd
);
4564 install_element(VIEW_NODE
, &show_vrf_cmd
);
4565 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
4566 install_element(VIEW_NODE
, &show_route_cmd
);
4567 install_element(VIEW_NODE
, &show_ro_cmd
);
4568 install_element(VIEW_NODE
, &show_route_detail_cmd
);
4569 install_element(VIEW_NODE
, &show_route_summary_cmd
);
4570 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
4572 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
4573 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
4575 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
4576 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
4577 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
4578 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
4579 install_element(VRF_NODE
, &ip_nht_default_route_cmd
);
4580 install_element(VRF_NODE
, &no_ip_nht_default_route_cmd
);
4581 install_element(VRF_NODE
, &ipv6_nht_default_route_cmd
);
4582 install_element(VRF_NODE
, &no_ipv6_nht_default_route_cmd
);
4583 install_element(CONFIG_NODE
, &rnh_hide_backups_cmd
);
4585 install_element(VIEW_NODE
, &show_frr_cmd
);
4586 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
4587 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
4588 install_element(VIEW_NODE
, &show_evpn_vni_detail_cmd
);
4589 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
4590 install_element(VIEW_NODE
, &show_evpn_l2_nh_cmd
);
4591 install_element(VIEW_NODE
, &show_evpn_es_cmd
);
4592 install_element(VIEW_NODE
, &show_evpn_es_evi_cmd
);
4593 install_element(VIEW_NODE
, &show_evpn_access_vlan_cmd
);
4594 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
4595 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
4596 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
4597 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
4598 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
4599 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
4600 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
4601 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
4602 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_detail_cmd
);
4603 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
4604 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
4605 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
4606 install_element(VIEW_NODE
, &show_evpn_mac_vni_dad_cmd
);
4607 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_dad_cmd
);
4608 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
4609 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
4610 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_detail_cmd
);
4611 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
4612 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
4613 install_element(VIEW_NODE
, &show_evpn_neigh_vni_dad_cmd
);
4614 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_dad_cmd
);
4615 install_element(ENABLE_NODE
, &clear_evpn_dup_addr_cmd
);
4616 install_element(CONFIG_NODE
, &evpn_accept_bgp_seq_cmd
);
4617 install_element(CONFIG_NODE
, &no_evpn_accept_bgp_seq_cmd
);
4619 install_element(VIEW_NODE
, &show_neigh_cmd
);
4621 install_element(VIEW_NODE
, &show_pbr_ipset_cmd
);
4622 install_element(VIEW_NODE
, &show_pbr_iptable_cmd
);
4623 install_element(VIEW_NODE
, &show_pbr_rule_cmd
);
4624 install_element(CONFIG_NODE
, &pbr_nexthop_resolve_cmd
);
4625 install_element(VIEW_NODE
, &show_route_zebra_dump_cmd
);
4627 install_element(CONFIG_NODE
, &evpn_mh_mac_holdtime_cmd
);
4628 install_element(CONFIG_NODE
, &evpn_mh_neigh_holdtime_cmd
);
4629 install_element(CONFIG_NODE
, &evpn_mh_startup_delay_cmd
);
4630 install_element(CONFIG_NODE
, &evpn_mh_redirect_off_cmd
);
4631 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
4632 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
4633 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
4634 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);
4636 install_element(VIEW_NODE
, &show_dataplane_cmd
);
4637 install_element(VIEW_NODE
, &show_dataplane_providers_cmd
);
4638 install_element(CONFIG_NODE
, &zebra_dplane_queue_limit_cmd
);
4639 install_element(CONFIG_NODE
, &no_zebra_dplane_queue_limit_cmd
);
4641 install_element(CONFIG_NODE
, &ip_table_range_cmd
);
4642 install_element(VRF_NODE
, &ip_table_range_cmd
);
4645 install_element(CONFIG_NODE
, &zebra_kernel_netlink_batch_tx_buf_cmd
);
4646 install_element(CONFIG_NODE
, &no_zebra_kernel_netlink_batch_tx_buf_cmd
);
4647 install_element(CONFIG_NODE
, &zebra_protodown_bit_cmd
);
4648 install_element(CONFIG_NODE
, &no_zebra_protodown_bit_cmd
);
4649 #endif /* HAVE_NETLINK */
4651 #ifdef HAVE_SCRIPTING
4652 install_element(CONFIG_NODE
, &zebra_on_rib_process_script_cmd
);
4653 #endif /* HAVE_SCRIPTING */
4655 install_element(VIEW_NODE
, &zebra_show_routing_tables_summary_cmd
);