2 * Copyright (C) 2002 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "zebra_memory.h"
34 #include "srcdest_table.h"
37 #include "zebra/zserv.h"
38 #include "zebra/zebra_vrf.h"
39 #include "zebra/zebra_mpls.h"
40 #include "zebra/zebra_rnh.h"
41 #include "zebra/redistribute.h"
42 #include "zebra/zebra_routemap.h"
43 #include "zebra/zebra_static.h"
45 #include "zebra/zebra_vxlan.h"
46 #ifndef VTYSH_EXTRACT_PL
47 #include "zebra/zebra_vty_clippy.c"
49 #include "zebra/zserv.h"
50 #include "zebra/router-id.h"
51 #include "zebra/ipforward.h"
52 #include "zebra/zebra_vxlan_private.h"
54 extern int allow_delete
;
56 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
57 safi_t safi
, bool use_fib
, u_char use_json
,
59 const struct prefix
*longer_prefix_p
,
60 bool supernets_only
, int type
,
61 u_short ospf_instance_id
);
62 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
64 static void vty_show_ip_route_summary(struct vty
*vty
,
65 struct route_table
*table
);
66 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
67 struct route_table
*table
);
70 * special macro to allow us to get the correct zebra_vrf
72 #define ZEBRA_DECLVAR_CONTEXT(A, B) \
73 struct vrf *A = VTY_GET_CONTEXT(vrf); \
74 struct zebra_vrf *B = \
75 (vrf) ? vrf->info : NULL; \
77 /* VNI range as per RFC 7432 */
78 #define CMD_VNI_RANGE "(1-16777215)"
80 /* General function for static route. */
81 static int zebra_static_route_leak(struct vty
*vty
,
82 struct zebra_vrf
*zvrf
,
83 struct zebra_vrf
*nh_zvrf
,
84 afi_t afi
, safi_t safi
,
85 const char *negate
, const char *dest_str
,
86 const char *mask_str
, const char *src_str
,
87 const char *gate_str
, const char *ifname
,
88 const char *flag_str
, const char *tag_str
,
89 const char *distance_str
,
90 const char *label_str
)
95 struct prefix_ipv6
*src_p
= NULL
;
97 union g_addr
*gatep
= NULL
;
99 enum static_blackhole_type bh_type
= 0;
102 struct static_nh_label snh_label
;
104 ret
= str2prefix(dest_str
, &p
);
106 vty_out(vty
, "%% Malformed address\n");
107 return CMD_WARNING_CONFIG_FAILED
;
112 /* Cisco like mask notation. */
114 ret
= inet_aton(mask_str
, &mask
);
116 vty_out(vty
, "%% Malformed address\n");
117 return CMD_WARNING_CONFIG_FAILED
;
119 p
.prefixlen
= ip_masklen(mask
);
123 /* srcdest routing */
125 ret
= str2prefix(src_str
, &src
);
126 if (ret
<= 0 || src
.family
!= AF_INET6
) {
127 vty_out(vty
, "%% Malformed source address\n");
128 return CMD_WARNING_CONFIG_FAILED
;
130 src_p
= (struct prefix_ipv6
*)&src
;
137 /* Apply mask for given prefix. */
140 /* Administrative distance. */
142 distance
= atoi(distance_str
);
144 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
148 tag
= strtoul(tag_str
, NULL
, 10);
151 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
155 "%% MPLS not turned on in kernel, ignoring command\n");
156 return CMD_WARNING_CONFIG_FAILED
;
158 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
163 vty_out(vty
, "%% Malformed label(s)\n");
167 "%% Cannot use reserved label(s) (%d-%d)\n",
168 MPLS_LABEL_RESERVED_MIN
,
169 MPLS_LABEL_RESERVED_MAX
);
173 "%% Too many labels. Enter %d or fewer\n",
177 return CMD_WARNING_CONFIG_FAILED
;
181 /* Null0 static route. */
182 if (ifname
!= NULL
) {
183 if (strncasecmp(ifname
, "Null0", strlen(ifname
)) == 0 ||
184 strncasecmp(ifname
, "reject", strlen(ifname
)) == 0 ||
185 strncasecmp(ifname
, "blackhole", strlen(ifname
)) == 0) {
186 vty_out(vty
, "%% Nexthop interface cannot be Null0, reject or blackhole\n");
187 return CMD_WARNING_CONFIG_FAILED
;
193 switch (flag_str
[0]) {
195 bh_type
= STATIC_BLACKHOLE_REJECT
;
198 bh_type
= STATIC_BLACKHOLE_DROP
;
201 bh_type
= STATIC_BLACKHOLE_NULL
;
204 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
205 return CMD_WARNING_CONFIG_FAILED
;
210 if (inet_pton(afi2family(afi
), gate_str
, &gate
) != 1) {
211 vty_out(vty
, "%% Malformed nexthop address %s\n",
213 return CMD_WARNING_CONFIG_FAILED
;
218 if (gate_str
== NULL
&& ifname
== NULL
)
219 type
= STATIC_BLACKHOLE
;
220 else if (gate_str
&& ifname
) {
222 type
= STATIC_IPV4_GATEWAY_IFNAME
;
224 type
= STATIC_IPV6_GATEWAY_IFNAME
;
226 type
= STATIC_IFNAME
;
229 type
= STATIC_IPV4_GATEWAY
;
231 type
= STATIC_IPV6_GATEWAY
;
235 static_add_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
236 bh_type
, tag
, distance
, zvrf
, nh_zvrf
,
238 /* Mark as having FRR configuration */
239 vrf_set_user_cfged(zvrf
->vrf
);
241 static_delete_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
242 tag
, distance
, zvrf
, &snh_label
);
243 /* If no other FRR config for this VRF, mark accordingly. */
244 if (!zebra_vrf_has_config(zvrf
))
245 vrf_reset_user_cfged(zvrf
->vrf
);
251 static int zebra_static_route(struct vty
*vty
, afi_t afi
, safi_t safi
,
252 const char *negate
, const char *dest_str
,
253 const char *mask_str
, const char *src_str
,
254 const char *gate_str
, const char *ifname
,
255 const char *flag_str
, const char *tag_str
,
256 const char *distance_str
, const char *vrf_name
,
257 const char *label_str
)
259 struct zebra_vrf
*zvrf
;
263 zvrf
= zebra_vrf_lookup_by_name(vrf_name
);
265 /* When trying to delete, the VRF must exist. */
266 if (negate
&& !zvrf
) {
267 vty_out(vty
, "%% vrf %s is not defined\n", vrf_name
);
268 return CMD_WARNING_CONFIG_FAILED
;
271 /* When trying to create, create the VRF if it doesn't exist.
272 * Note: The VRF isn't active until we hear about it from the kernel.
275 vrf
= vrf_get(VRF_UNKNOWN
, vrf_name
);
277 vty_out(vty
, "%% Could not create vrf %s\n", vrf_name
);
278 return CMD_WARNING_CONFIG_FAILED
;
282 vty_out(vty
, "%% Could not create vrf-info %s\n",
284 return CMD_WARNING_CONFIG_FAILED
;
286 /* Mark as having FRR configuration */
287 vrf_set_user_cfged(vrf
);
289 return zebra_static_route_leak(vty
, zvrf
, zvrf
, afi
, safi
,
290 negate
, dest_str
, mask_str
, src_str
,
291 gate_str
, ifname
, flag_str
, tag_str
,
292 distance_str
, label_str
);
296 /* Static unicast routes for multicast RPF lookup. */
297 DEFPY (ip_mroute_dist
,
299 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
302 "Configure static unicast route into MRIB for multicast RPF lookup\n"
303 "IP destination prefix (e.g. 10.0.0.0/8)\n"
305 "Nexthop interface name\n"
308 return zebra_static_route(vty
, AFI_IP
, SAFI_MULTICAST
, no
, prefix_str
,
309 NULL
, NULL
, gate_str
, ifname
, NULL
, NULL
,
310 distance_str
, NULL
, NULL
);
313 DEFUN (ip_multicast_mode
,
314 ip_multicast_mode_cmd
,
315 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
317 "Multicast options\n"
318 "RPF lookup behavior\n"
319 "Lookup in unicast RIB only\n"
320 "Lookup in multicast RIB only\n"
321 "Try multicast RIB first, fall back to unicast RIB\n"
322 "Lookup both, use entry with lower distance\n"
323 "Lookup both, use entry with longer prefix\n")
325 char *mode
= argv
[3]->text
;
327 if (strmatch(mode
, "urib-only"))
328 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
329 else if (strmatch(mode
, "mrib-only"))
330 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
331 else if (strmatch(mode
, "mrib-then-urib"))
332 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
333 else if (strmatch(mode
, "lower-distance"))
334 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
335 else if (strmatch(mode
, "longer-prefix"))
336 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
338 vty_out(vty
, "Invalid mode specified\n");
339 return CMD_WARNING_CONFIG_FAILED
;
345 DEFUN (no_ip_multicast_mode
,
346 no_ip_multicast_mode_cmd
,
347 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
350 "Multicast options\n"
351 "RPF lookup behavior\n"
352 "Lookup in unicast RIB only\n"
353 "Lookup in multicast RIB only\n"
354 "Try multicast RIB first, fall back to unicast RIB\n"
355 "Lookup both, use entry with lower distance\n"
356 "Lookup both, use entry with longer prefix\n")
358 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
365 "show ip rpf [json]",
368 "Display RPF information for multicast source\n"
371 int uj
= use_json(argc
, argv
);
372 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
373 false, uj
, 0, NULL
, false, 0, 0);
376 DEFUN (show_ip_rpf_addr
,
377 show_ip_rpf_addr_cmd
,
378 "show ip rpf A.B.C.D",
381 "Display RPF information for multicast source\n"
382 "IP multicast source address (e.g. 10.0.0.0)\n")
386 struct route_node
*rn
;
387 struct route_entry
*re
;
390 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
392 vty_out(vty
, "%% Malformed address\n");
396 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
399 vty_show_ip_route_detail(vty
, rn
, 1);
401 vty_out(vty
, "%% No match for RPF lookup\n");
406 /* Static route configuration. */
407 DEFPY(ip_route_blackhole
,
408 ip_route_blackhole_cmd
,
410 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
411 <reject|blackhole>$flag \
419 "Establish static routes\n"
420 "IP destination prefix (e.g. 10.0.0.0/8)\n"
421 "IP destination prefix\n"
422 "IP destination prefix mask\n"
423 "Emit an ICMP unreachable when matched\n"
424 "Silently discard pkts when matched\n"
425 "Set tag for this route\n"
427 "Distance value for this route\n"
431 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
432 mask_str
, NULL
, NULL
, NULL
, flag
,
433 tag_str
, distance_str
, vrf
, label
);
436 DEFPY(ip_route_blackhole_vrf
,
437 ip_route_blackhole_vrf_cmd
,
439 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
440 <reject|blackhole>$flag \
447 "Establish static routes\n"
448 "IP destination prefix (e.g. 10.0.0.0/8)\n"
449 "IP destination prefix\n"
450 "IP destination prefix mask\n"
451 "Emit an ICMP unreachable when matched\n"
452 "Silently discard pkts when matched\n"
453 "Set tag for this route\n"
455 "Distance value for this route\n"
458 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
459 struct zebra_vrf
*zvrf
= vrf
->info
;
462 * Coverity is complaining that prefix could
463 * be dereferenced, but we know that prefix will
464 * valid. Add an assert to make it happy
467 return zebra_static_route_leak(vty
, zvrf
, zvrf
,
468 AFI_IP
, SAFI_UNICAST
, no
, prefix
,
469 mask_str
, NULL
, NULL
, NULL
, flag
,
470 tag_str
, distance_str
, label
);
473 DEFPY(ip_route_address_interface
,
474 ip_route_address_interface_cmd
,
476 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
487 "Establish static routes\n"
488 "IP destination prefix (e.g. 10.0.0.0/8)\n"
489 "IP destination prefix\n"
490 "IP destination prefix mask\n"
491 "IP gateway address\n"
492 "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
494 "Set tag for this route\n"
496 "Distance value for this route\n"
501 struct zebra_vrf
*zvrf
;
502 struct zebra_vrf
*nh_zvrf
;
504 const char *flag
= NULL
;
505 if (ifname
&& !strncasecmp(ifname
, "Null0", 5)) {
510 zvrf
= zebra_vrf_lookup_by_name(vrf
);
512 vty_out(vty
, "%% vrf %s is not defined\n",
514 return CMD_WARNING_CONFIG_FAILED
;
518 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
523 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
525 return CMD_WARNING_CONFIG_FAILED
;
528 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
529 AFI_IP
, SAFI_UNICAST
, no
, prefix
,
530 mask_str
, NULL
, gate_str
, ifname
, flag
,
531 tag_str
, distance_str
, label
);
534 DEFPY(ip_route_address_interface_vrf
,
535 ip_route_address_interface_vrf_cmd
,
537 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
547 "Establish static routes\n"
548 "IP destination prefix (e.g. 10.0.0.0/8)\n"
549 "IP destination prefix\n"
550 "IP destination prefix mask\n"
551 "IP gateway address\n"
552 "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
554 "Set tag for this route\n"
556 "Distance value for this route\n"
560 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
561 const char *flag
= NULL
;
562 struct zebra_vrf
*zvrf
= vrf
->info
;
563 struct zebra_vrf
*nh_zvrf
;
565 if (ifname
&& !strncasecmp(ifname
, "Null0", 5)) {
571 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
576 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
578 return CMD_WARNING_CONFIG_FAILED
;
581 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
582 AFI_IP
, SAFI_UNICAST
, no
, prefix
,
583 mask_str
, NULL
, gate_str
, ifname
, flag
,
584 tag_str
, distance_str
, label
);
590 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
591 <A.B.C.D$gate|INTERFACE$ifname> \
600 "Establish static routes\n"
601 "IP destination prefix (e.g. 10.0.0.0/8)\n"
602 "IP destination prefix\n"
603 "IP destination prefix mask\n"
604 "IP gateway address\n"
605 "IP gateway interface name\n"
606 "Set tag for this route\n"
608 "Distance value for this route\n"
613 struct zebra_vrf
*zvrf
;
614 struct zebra_vrf
*nh_zvrf
;
615 const char *flag
= NULL
;
617 if (ifname
&& !strncasecmp(ifname
, "Null0", 5)) {
622 zvrf
= zebra_vrf_lookup_by_name(vrf
);
624 vty_out(vty
, "%% vrf %s is not defined\n",
626 return CMD_WARNING_CONFIG_FAILED
;
630 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
635 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
637 return CMD_WARNING_CONFIG_FAILED
;
641 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
642 AFI_IP
, SAFI_UNICAST
, no
, prefix
,
643 mask_str
, NULL
, gate_str
, ifname
, flag
,
644 tag_str
, distance_str
, label
);
650 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
651 <A.B.C.D$gate|INTERFACE$ifname> \
659 "Establish static routes\n"
660 "IP destination prefix (e.g. 10.0.0.0/8)\n"
661 "IP destination prefix\n"
662 "IP destination prefix mask\n"
663 "IP gateway address\n"
664 "IP gateway interface name\n"
665 "Set tag for this route\n"
667 "Distance value for this route\n"
671 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
672 struct zebra_vrf
*zvrf
= vrf
->info
;
673 struct zebra_vrf
*nh_zvrf
;
675 const char *flag
= NULL
;
676 if (ifname
&& !strncasecmp(ifname
, "Null0", 5)) {
682 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
687 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
689 return CMD_WARNING_CONFIG_FAILED
;
692 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
693 AFI_IP
, SAFI_UNICAST
, no
, prefix
,
694 mask_str
, NULL
, gate_str
, ifname
, flag
,
695 tag_str
, distance_str
, label
);
698 /* New RIB. Detailed information for IPv4 route. */
699 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
702 struct route_entry
*re
;
703 struct nexthop
*nexthop
;
704 char buf
[SRCDEST2STR_BUFFER
];
705 struct zebra_vrf
*zvrf
;
707 RNODE_FOREACH_RE (rn
, re
) {
708 const char *mcast_info
= "";
710 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
711 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
712 ? " using Multicast RIB"
713 : " using Unicast RIB";
716 vty_out(vty
, "Routing entry for %s%s\n",
717 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
718 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
720 vty_out(vty
, "[%d]", re
->instance
);
722 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
725 vty_out(vty
, ", tag %u", re
->tag
);
726 #if defined(SUPPORT_REALMS)
727 if (re
->tag
> 0 && re
->tag
<= 255)
728 vty_out(vty
, "(realm)");
732 vty_out(vty
, ", mtu %u", re
->mtu
);
733 if (re
->vrf_id
!= VRF_DEFAULT
) {
734 zvrf
= vrf_info_lookup(re
->vrf_id
);
735 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
737 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
738 vty_out(vty
, ", best");
745 uptime
-= re
->uptime
;
746 tm
= gmtime(&uptime
);
748 vty_out(vty
, " Last update ");
750 if (uptime
< ONE_DAY_SECOND
)
751 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
752 tm
->tm_min
, tm
->tm_sec
);
753 else if (uptime
< ONE_WEEK_SECOND
)
754 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
755 tm
->tm_hour
, tm
->tm_min
);
757 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
758 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
760 vty_out(vty
, " ago\n");
762 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
765 vty_out(vty
, " %c%s",
766 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
767 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
770 nexthop
->rparent
? " " : "");
772 switch (nexthop
->type
) {
773 case NEXTHOP_TYPE_IPV4
:
774 case NEXTHOP_TYPE_IPV4_IFINDEX
:
776 inet_ntoa(nexthop
->gate
.ipv4
));
777 if (nexthop
->ifindex
)
778 vty_out(vty
, ", via %s",
783 case NEXTHOP_TYPE_IPV6
:
784 case NEXTHOP_TYPE_IPV6_IFINDEX
:
786 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
788 if (nexthop
->ifindex
)
789 vty_out(vty
, ", via %s",
794 case NEXTHOP_TYPE_IFINDEX
:
795 vty_out(vty
, " directly connected, %s",
796 ifindex2ifname(nexthop
->ifindex
,
799 case NEXTHOP_TYPE_BLACKHOLE
:
800 vty_out(vty
, " unreachable");
801 switch (nexthop
->bh_type
) {
802 case BLACKHOLE_REJECT
:
803 vty_out(vty
, " (ICMP unreachable)");
805 case BLACKHOLE_ADMINPROHIB
:
807 " (ICMP admin-prohibited)");
810 vty_out(vty
, " (blackhole)");
812 case BLACKHOLE_UNSPEC
:
820 if (re
->vrf_id
!= nexthop
->vrf_id
) {
822 vrf_lookup_by_id(nexthop
->vrf_id
);
824 vty_out(vty
, "(vrf %s)", vrf
->name
);
827 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
828 vty_out(vty
, " (duplicate nexthop removed)");
830 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
831 vty_out(vty
, " inactive");
833 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
834 vty_out(vty
, " onlink");
836 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
837 vty_out(vty
, " (recursive)");
839 switch (nexthop
->type
) {
840 case NEXTHOP_TYPE_IPV4
:
841 case NEXTHOP_TYPE_IPV4_IFINDEX
:
842 if (nexthop
->src
.ipv4
.s_addr
) {
843 if (inet_ntop(AF_INET
,
845 addrstr
, sizeof addrstr
))
846 vty_out(vty
, ", src %s",
850 case NEXTHOP_TYPE_IPV6
:
851 case NEXTHOP_TYPE_IPV6_IFINDEX
:
852 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
854 if (inet_ntop(AF_INET6
,
856 addrstr
, sizeof addrstr
))
857 vty_out(vty
, ", src %s",
866 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
868 /* Label information */
869 if (nexthop
->nh_label
870 && nexthop
->nh_label
->num_labels
) {
871 vty_out(vty
, ", label %s",
873 nexthop
->nh_label
->num_labels
,
874 nexthop
->nh_label
->label
, buf
,
884 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
885 struct route_entry
*re
, json_object
*json
)
887 struct nexthop
*nexthop
;
889 char buf
[SRCDEST2STR_BUFFER
];
890 json_object
*json_nexthops
= NULL
;
891 json_object
*json_nexthop
= NULL
;
892 json_object
*json_route
= NULL
;
893 json_object
*json_labels
= NULL
;
898 uptime
-= re
->uptime
;
899 tm
= gmtime(&uptime
);
902 json_route
= json_object_new_object();
903 json_nexthops
= json_object_new_array();
905 json_object_string_add(json_route
, "prefix",
906 srcdest_rnode2str(rn
, buf
, sizeof buf
));
907 json_object_string_add(json_route
, "protocol",
908 zebra_route_string(re
->type
));
911 json_object_int_add(json_route
, "instance",
915 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
917 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
918 json_object_boolean_true_add(json_route
, "selected");
920 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
921 json_object_int_add(json_route
, "distance",
923 json_object_int_add(json_route
, "metric", re
->metric
);
926 if (uptime
< ONE_DAY_SECOND
)
927 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
928 tm
->tm_min
, tm
->tm_sec
);
929 else if (uptime
< ONE_WEEK_SECOND
)
930 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
931 tm
->tm_hour
, tm
->tm_min
);
933 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
934 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
937 json_object_string_add(json_route
, "uptime", buf
);
939 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
940 json_nexthop
= json_object_new_object();
942 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
943 json_object_boolean_true_add(json_nexthop
,
946 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
947 json_object_boolean_true_add(json_nexthop
,
950 switch (nexthop
->type
) {
951 case NEXTHOP_TYPE_IPV4
:
952 case NEXTHOP_TYPE_IPV4_IFINDEX
:
953 json_object_string_add(
955 inet_ntoa(nexthop
->gate
.ipv4
));
956 json_object_string_add(json_nexthop
, "afi",
959 if (nexthop
->ifindex
) {
960 json_object_int_add(json_nexthop
,
963 json_object_string_add(
964 json_nexthop
, "interfaceName",
970 case NEXTHOP_TYPE_IPV6
:
971 case NEXTHOP_TYPE_IPV6_IFINDEX
:
972 json_object_string_add(
974 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
976 json_object_string_add(json_nexthop
, "afi",
979 if (nexthop
->ifindex
) {
980 json_object_int_add(json_nexthop
,
983 json_object_string_add(
984 json_nexthop
, "interfaceName",
991 case NEXTHOP_TYPE_IFINDEX
:
992 json_object_boolean_true_add(
993 json_nexthop
, "directlyConnected");
994 json_object_int_add(json_nexthop
,
997 json_object_string_add(
998 json_nexthop
, "interfaceName",
999 ifindex2ifname(nexthop
->ifindex
,
1002 case NEXTHOP_TYPE_BLACKHOLE
:
1003 json_object_boolean_true_add(json_nexthop
,
1005 switch (nexthop
->bh_type
) {
1006 case BLACKHOLE_REJECT
:
1007 json_object_boolean_true_add(
1008 json_nexthop
, "reject");
1010 case BLACKHOLE_ADMINPROHIB
:
1011 json_object_boolean_true_add(
1013 "admin-prohibited");
1015 case BLACKHOLE_NULL
:
1016 json_object_boolean_true_add(
1017 json_nexthop
, "blackhole");
1019 case BLACKHOLE_UNSPEC
:
1027 if (nexthop
->vrf_id
!= re
->vrf_id
) {
1029 vrf_lookup_by_id(nexthop
->vrf_id
);
1031 json_object_string_add(json_nexthop
,
1035 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
1036 json_object_boolean_true_add(json_nexthop
,
1039 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1040 json_object_boolean_true_add(json_nexthop
,
1043 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1044 json_object_boolean_true_add(json_nexthop
,
1047 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1048 json_object_boolean_true_add(json_nexthop
,
1051 switch (nexthop
->type
) {
1052 case NEXTHOP_TYPE_IPV4
:
1053 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1054 if (nexthop
->src
.ipv4
.s_addr
) {
1055 if (inet_ntop(AF_INET
,
1056 &nexthop
->src
.ipv4
, buf
,
1058 json_object_string_add(
1059 json_nexthop
, "source",
1063 case NEXTHOP_TYPE_IPV6
:
1064 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1065 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
1067 if (inet_ntop(AF_INET6
,
1068 &nexthop
->src
.ipv6
, buf
,
1070 json_object_string_add(
1071 json_nexthop
, "source",
1079 if (nexthop
->nh_label
1080 && nexthop
->nh_label
->num_labels
) {
1081 json_labels
= json_object_new_array();
1083 for (int label_index
= 0;
1085 < nexthop
->nh_label
->num_labels
;
1087 json_object_array_add(
1089 json_object_new_int(
1090 nexthop
->nh_label
->label
1093 json_object_object_add(json_nexthop
, "labels",
1097 json_object_array_add(json_nexthops
, json_nexthop
);
1100 json_object_object_add(json_route
, "nexthops", json_nexthops
);
1101 json_object_array_add(json
, json_route
);
1105 /* Nexthop information. */
1106 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
1107 if (nexthop
== re
->nexthop
) {
1108 /* Prefix information. */
1109 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
1111 len
+= vty_out(vty
, "[%d]", re
->instance
);
1114 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
1117 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
1120 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1122 /* Distance and metric display. */
1123 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
1124 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
1127 vty_out(vty
, " %c%*c",
1128 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
1129 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
1132 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1135 switch (nexthop
->type
) {
1136 case NEXTHOP_TYPE_IPV4
:
1137 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1138 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
1139 if (nexthop
->ifindex
)
1140 vty_out(vty
, ", %s",
1141 ifindex2ifname(nexthop
->ifindex
,
1144 case NEXTHOP_TYPE_IPV6
:
1145 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1146 vty_out(vty
, " via %s",
1147 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1149 if (nexthop
->ifindex
)
1150 vty_out(vty
, ", %s",
1151 ifindex2ifname(nexthop
->ifindex
,
1155 case NEXTHOP_TYPE_IFINDEX
:
1156 vty_out(vty
, " is directly connected, %s",
1157 ifindex2ifname(nexthop
->ifindex
,
1160 case NEXTHOP_TYPE_BLACKHOLE
:
1161 vty_out(vty
, " unreachable");
1162 switch (nexthop
->bh_type
) {
1163 case BLACKHOLE_REJECT
:
1164 vty_out(vty
, " (ICMP unreachable)");
1166 case BLACKHOLE_ADMINPROHIB
:
1167 vty_out(vty
, " (ICMP admin-prohibited)");
1169 case BLACKHOLE_NULL
:
1170 vty_out(vty
, " (blackhole)");
1172 case BLACKHOLE_UNSPEC
:
1180 if (nexthop
->vrf_id
!= re
->vrf_id
) {
1181 struct vrf
*vrf
= vrf_lookup_by_id(nexthop
->vrf_id
);
1183 vty_out(vty
, "(vrf %s)", vrf
->name
);
1186 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1187 vty_out(vty
, " inactive");
1189 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1190 vty_out(vty
, " onlink");
1192 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1193 vty_out(vty
, " (recursive)");
1195 switch (nexthop
->type
) {
1196 case NEXTHOP_TYPE_IPV4
:
1197 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1198 if (nexthop
->src
.ipv4
.s_addr
) {
1199 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1201 vty_out(vty
, ", src %s", buf
);
1204 case NEXTHOP_TYPE_IPV6
:
1205 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1206 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1207 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1209 vty_out(vty
, ", src %s", buf
);
1216 /* Label information */
1217 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1218 vty_out(vty
, ", label %s",
1219 mpls_label2str(nexthop
->nh_label
->num_labels
,
1220 nexthop
->nh_label
->label
, buf
,
1224 if (uptime
< ONE_DAY_SECOND
)
1225 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
1226 tm
->tm_min
, tm
->tm_sec
);
1227 else if (uptime
< ONE_WEEK_SECOND
)
1228 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
1229 tm
->tm_hour
, tm
->tm_min
);
1231 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
1232 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
1238 static void do_show_route_helper(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1239 struct route_table
*table
, afi_t afi
,
1240 bool use_fib
, route_tag_t tag
,
1241 const struct prefix
*longer_prefix_p
,
1242 bool supernets_only
, int type
,
1243 u_short ospf_instance_id
, u_char use_json
)
1245 struct route_node
*rn
;
1246 struct route_entry
*re
;
1249 json_object
*json
= NULL
;
1250 json_object
*json_prefix
= NULL
;
1255 json
= json_object_new_object();
1257 /* Show all routes. */
1258 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
1259 dest
= rib_dest_from_rnode(rn
);
1261 RNODE_FOREACH_RE (rn
, re
) {
1263 && re
!= dest
->selected_fib
)
1266 if (tag
&& re
->tag
!= tag
)
1270 && !prefix_match(longer_prefix_p
, &rn
->p
))
1273 /* This can only be true when the afi is IPv4 */
1274 if (supernets_only
) {
1275 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1277 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1280 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1283 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1287 if (type
&& re
->type
!= type
)
1290 if (ospf_instance_id
1291 && (re
->type
!= ZEBRA_ROUTE_OSPF
1292 || re
->instance
!= ospf_instance_id
))
1297 json_prefix
= json_object_new_array();
1302 SHOW_ROUTE_V4_HEADER
);
1305 SHOW_ROUTE_V6_HEADER
);
1307 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
1308 vty_out(vty
, "\nVRF %s:\n",
1315 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
1319 prefix2str(&rn
->p
, buf
, sizeof buf
);
1320 json_object_object_add(json
, buf
, json_prefix
);
1326 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1327 json
, JSON_C_TO_STRING_PRETTY
));
1328 json_object_free(json
);
1332 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
1333 safi_t safi
, bool use_fib
, u_char use_json
,
1335 const struct prefix
*longer_prefix_p
,
1336 bool supernets_only
, int type
,
1337 u_short ospf_instance_id
)
1339 struct route_table
*table
;
1340 struct zebra_vrf
*zvrf
= NULL
;
1342 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
1344 vty_out(vty
, "{}\n");
1346 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
1350 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
1352 vty_out(vty
, "{}\n");
1354 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
1358 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
1361 vty_out(vty
, "{}\n");
1365 do_show_route_helper(vty
, zvrf
, table
, afi
, use_fib
, tag
,
1366 longer_prefix_p
, supernets_only
, type
,
1367 ospf_instance_id
, use_json
);
1372 DEFPY (show_route_table
,
1373 show_route_table_cmd
,
1374 "show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
1378 "IP routing table\n"
1379 "Table to display\n"
1380 "The table number to display, if available\n"
1383 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1384 struct zebra_vrf
*zvrf
= zebra_vrf_lookup_by_id(VRF_DEFAULT
);
1385 struct route_table
*t
;
1387 t
= zebra_ns_find_table(zvrf
->zns
, table
, afi
);
1389 do_show_route_helper(vty
, zvrf
, t
, afi
, false, 0, false, false,
1397 "show ip nht [vrf NAME]",
1400 "IP nexthop tracking table\n"
1404 vrf_id_t vrf_id
= VRF_DEFAULT
;
1407 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1409 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1414 DEFUN (show_ip_nht_vrf_all
,
1415 show_ip_nht_vrf_all_cmd
,
1416 "show ip nht vrf all",
1419 "IP nexthop tracking table\n"
1420 VRF_ALL_CMD_HELP_STR
)
1423 struct zebra_vrf
*zvrf
;
1425 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1426 if ((zvrf
= vrf
->info
) != NULL
) {
1427 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1428 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1435 DEFUN (show_ipv6_nht
,
1437 "show ipv6 nht [vrf NAME]",
1440 "IPv6 nexthop tracking table\n"
1444 vrf_id_t vrf_id
= VRF_DEFAULT
;
1447 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1449 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1454 DEFUN (show_ipv6_nht_vrf_all
,
1455 show_ipv6_nht_vrf_all_cmd
,
1456 "show ipv6 nht vrf all",
1459 "IPv6 nexthop tracking table\n"
1460 VRF_ALL_CMD_HELP_STR
)
1463 struct zebra_vrf
*zvrf
;
1465 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1466 if ((zvrf
= vrf
->info
) != NULL
) {
1467 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1468 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1475 DEFUN (ip_nht_default_route
,
1476 ip_nht_default_route_cmd
,
1477 "ip nht resolve-via-default",
1479 "Filter Next Hop tracking route resolution\n"
1480 "Resolve via default route\n")
1482 if (zebra_rnh_ip_default_route
)
1485 zebra_rnh_ip_default_route
= 1;
1486 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1490 DEFUN (no_ip_nht_default_route
,
1491 no_ip_nht_default_route_cmd
,
1492 "no ip nht resolve-via-default",
1495 "Filter Next Hop tracking route resolution\n"
1496 "Resolve via default route\n")
1498 if (!zebra_rnh_ip_default_route
)
1501 zebra_rnh_ip_default_route
= 0;
1502 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1506 DEFUN (ipv6_nht_default_route
,
1507 ipv6_nht_default_route_cmd
,
1508 "ipv6 nht resolve-via-default",
1510 "Filter Next Hop tracking route resolution\n"
1511 "Resolve via default route\n")
1513 if (zebra_rnh_ipv6_default_route
)
1516 zebra_rnh_ipv6_default_route
= 1;
1517 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1521 DEFUN (no_ipv6_nht_default_route
,
1522 no_ipv6_nht_default_route_cmd
,
1523 "no ipv6 nht resolve-via-default",
1526 "Filter Next Hop tracking route resolution\n"
1527 "Resolve via default route\n")
1529 if (!zebra_rnh_ipv6_default_route
)
1532 zebra_rnh_ipv6_default_route
= 0;
1533 zebra_evaluate_rnh(VRF_DEFAULT
, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1541 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1544 |A.B.C.D/M$prefix longer-prefixes\
1545 |supernets-only$supernets_only\
1548 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1549 |ospf$type_str (1-65535)$ospf_instance_id\
1551 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1554 |X:X::X:X/M$prefix longer-prefixes\
1556 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1561 "IP forwarding table\n"
1562 "IP routing table\n"
1563 VRF_FULL_CMD_HELP_STR
1564 "Show only routes with tag\n"
1566 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1567 "Show route matching the specified Network/Mask pair only\n"
1568 "Show supernet entries only\n"
1569 FRR_IP_REDIST_HELP_STR_ZEBRA
1570 "Open Shortest Path First (OSPFv2)\n"
1573 "IP forwarding table\n"
1574 "IP routing table\n"
1575 VRF_FULL_CMD_HELP_STR
1576 "Show only routes with tag\n"
1579 "Show route matching the specified Network/Mask pair only\n"
1580 FRR_IP6_REDIST_HELP_STR_ZEBRA
1583 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1588 type
= proto_redistnum(afi
, type_str
);
1590 vty_out(vty
, "Unknown route type\n");
1596 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1597 struct zebra_vrf
*zvrf
;
1598 struct route_table
*table
;
1600 if ((zvrf
= vrf
->info
) == NULL
1601 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1605 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1606 !!json
, tag
, prefix_str
? prefix
: NULL
,
1607 !!supernets_only
, type
, ospf_instance_id
);
1610 vrf_id_t vrf_id
= VRF_DEFAULT
;
1613 VRF_GET_ID(vrf_id
, vrf_name
);
1614 vrf
= vrf_lookup_by_id(vrf_id
);
1615 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1616 !!json
, tag
, prefix_str
? prefix
: NULL
,
1617 !!supernets_only
, type
, ospf_instance_id
);
1623 DEFPY (show_route_detail
,
1624 show_route_detail_cmd
,
1627 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1632 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1640 "IP routing table\n"
1641 VRF_FULL_CMD_HELP_STR
1642 "Network in the IP routing table to display\n"
1643 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1645 "IP routing table\n"
1646 VRF_FULL_CMD_HELP_STR
1650 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1651 struct route_table
*table
;
1653 struct route_node
*rn
;
1656 prefix_str
= address_str
;
1657 if (str2prefix(prefix_str
, &p
) < 0) {
1658 vty_out(vty
, "%% Malformed address\n");
1664 struct zebra_vrf
*zvrf
;
1666 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
1667 if ((zvrf
= vrf
->info
) == NULL
1668 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1671 rn
= route_node_match(table
, &p
);
1674 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1675 route_unlock_node(rn
);
1679 vty_show_ip_route_detail(vty
, rn
, 0);
1681 route_unlock_node(rn
);
1684 vrf_id_t vrf_id
= VRF_DEFAULT
;
1687 VRF_GET_ID(vrf_id
, vrf_name
);
1689 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1693 rn
= route_node_match(table
, &p
);
1695 vty_out(vty
, "%% Network not in table\n");
1698 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1699 vty_out(vty
, "%% Network not in table\n");
1700 route_unlock_node(rn
);
1704 vty_show_ip_route_detail(vty
, rn
, 0);
1706 route_unlock_node(rn
);
1712 DEFPY (show_route_summary
,
1713 show_route_summary_cmd
,
1716 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1717 summary [prefix$prefix]\
1718 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1719 summary [prefix$prefix]\
1723 "IP routing table\n"
1724 VRF_FULL_CMD_HELP_STR
1725 "Summary of all routes\n"
1728 "IP routing table\n"
1729 VRF_FULL_CMD_HELP_STR
1730 "Summary of all routes\n"
1733 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1734 struct route_table
*table
;
1738 struct zebra_vrf
*zvrf
;
1740 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
1741 if ((zvrf
= vrf
->info
) == NULL
1742 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1746 vty_show_ip_route_summary_prefix(vty
, table
);
1748 vty_show_ip_route_summary(vty
, table
);
1751 vrf_id_t vrf_id
= VRF_DEFAULT
;
1754 VRF_GET_ID(vrf_id
, vrf_name
);
1756 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1761 vty_show_ip_route_summary_prefix(vty
, table
);
1763 vty_show_ip_route_summary(vty
, table
);
1769 static void vty_show_ip_route_summary(struct vty
*vty
,
1770 struct route_table
*table
)
1772 struct route_node
*rn
;
1773 struct route_entry
*re
;
1774 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1775 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1776 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1777 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1781 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1782 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1783 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1784 RNODE_FOREACH_RE (rn
, re
) {
1785 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1786 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1788 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1790 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1792 rib_cnt
[re
->type
]++;
1794 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1795 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1798 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1800 fib_cnt
[re
->type
]++;
1804 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1805 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1807 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1808 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1809 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1810 if (i
== ZEBRA_ROUTE_BGP
) {
1811 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1812 rib_cnt
[ZEBRA_ROUTE_BGP
],
1813 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1814 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1815 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1816 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1818 vty_out(vty
, "%-20s %-20d %-20d \n",
1819 zebra_route_string(i
), rib_cnt
[i
],
1824 vty_out(vty
, "------\n");
1825 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1826 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1831 * Implementation of the ip route summary prefix command.
1833 * This command prints the primary prefixes that have been installed by various
1834 * protocols on the box.
1837 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1838 struct route_table
*table
)
1840 struct route_node
*rn
;
1841 struct route_entry
*re
;
1842 struct nexthop
*nexthop
;
1843 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1844 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1845 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1846 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1850 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1851 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1852 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1853 RNODE_FOREACH_RE (rn
, re
) {
1856 * In case of ECMP, count only once.
1859 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1860 nexthop
= nexthop
->next
) {
1862 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1863 rib_cnt
[re
->type
]++;
1864 if (CHECK_FLAG(nexthop
->flags
,
1865 NEXTHOP_FLAG_FIB
)) {
1866 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1867 fib_cnt
[re
->type
]++;
1869 if (re
->type
== ZEBRA_ROUTE_BGP
1870 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1871 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1872 if (CHECK_FLAG(nexthop
->flags
,
1874 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1879 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1880 "Prefix Routes", "FIB",
1881 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1883 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1884 if (rib_cnt
[i
] > 0) {
1885 if (i
== ZEBRA_ROUTE_BGP
) {
1886 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1887 rib_cnt
[ZEBRA_ROUTE_BGP
]
1888 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1889 fib_cnt
[ZEBRA_ROUTE_BGP
]
1890 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1891 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1892 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1893 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1895 vty_out(vty
, "%-20s %-20d %-20d \n",
1896 zebra_route_string(i
), rib_cnt
[i
],
1901 vty_out(vty
, "------\n");
1902 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1903 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1907 /* Write static route configuration. */
1908 int static_config(struct vty
*vty
, struct zebra_vrf
*zvrf
,
1909 afi_t afi
, safi_t safi
, const char *cmd
)
1912 struct route_node
*rn
;
1913 struct static_route
*si
;
1914 struct route_table
*stable
;
1915 char buf
[SRCDEST2STR_BUFFER
];
1918 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1921 sprintf(spacing
, "%s%s",
1922 (zvrf
->vrf
->vrf_id
== VRF_DEFAULT
) ? "" : " ",
1925 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1926 for (si
= rn
->info
; si
; si
= si
->next
) {
1927 vty_out(vty
, "%s %s", spacing
,
1928 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1931 case STATIC_IPV4_GATEWAY
:
1933 inet_ntoa(si
->addr
.ipv4
));
1935 case STATIC_IPV6_GATEWAY
:
1938 &si
->addr
.ipv6
, buf
,
1942 vty_out(vty
, " %s", si
->ifname
);
1944 case STATIC_BLACKHOLE
:
1945 switch (si
->bh_type
) {
1946 case STATIC_BLACKHOLE_DROP
:
1947 vty_out(vty
, " blackhole");
1949 case STATIC_BLACKHOLE_NULL
:
1950 vty_out(vty
, " Null0");
1952 case STATIC_BLACKHOLE_REJECT
:
1953 vty_out(vty
, " reject");
1957 case STATIC_IPV4_GATEWAY_IFNAME
:
1958 vty_out(vty
, " %s %s",
1960 &si
->addr
.ipv4
, buf
,
1964 case STATIC_IPV6_GATEWAY_IFNAME
:
1965 vty_out(vty
, " %s %s",
1967 &si
->addr
.ipv6
, buf
,
1974 vty_out(vty
, " tag %" ROUTE_TAG_PRI
,
1978 != ZEBRA_STATIC_DISTANCE_DEFAULT
)
1979 vty_out(vty
, " %d", si
->distance
);
1981 if (si
->nh_vrf_id
!= si
->vrf_id
) {
1984 vrf
= vrf_lookup_by_id(si
->nh_vrf_id
);
1985 vty_out(vty
, " nexthop-vrf %s",
1986 (vrf
) ? vrf
->name
: "Unknown");
1989 /* Label information */
1990 if (si
->snh_label
.num_labels
)
1991 vty_out(vty
, " label %s",
1992 mpls_label2str(si
->snh_label
.num_labels
,
1993 si
->snh_label
.label
,
1994 buf
, sizeof buf
, 0));
2003 DEFPY(ipv6_route_blackhole
,
2004 ipv6_route_blackhole_cmd
,
2005 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2006 <Null0|reject|blackhole>$flag \
2008 tag (1-4294967295) \
2015 "Establish static routes\n"
2016 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2017 "IPv6 source-dest route\n"
2018 "IPv6 source prefix\n"
2020 "Emit an ICMP unreachable when matched\n"
2021 "Silently discard pkts when matched\n"
2022 "Set tag for this route\n"
2024 "Distance value for this prefix\n"
2028 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
2029 NULL
, from_str
, NULL
, NULL
, flag
,
2030 tag_str
, distance_str
, vrf
, label
);
2033 DEFPY(ipv6_route_blackhole_vrf
,
2034 ipv6_route_blackhole_vrf_cmd
,
2035 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2036 <Null0|reject|blackhole>$flag \
2038 tag (1-4294967295) \
2044 "Establish static routes\n"
2045 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2046 "IPv6 source-dest route\n"
2047 "IPv6 source prefix\n"
2049 "Emit an ICMP unreachable when matched\n"
2050 "Silently discard pkts when matched\n"
2051 "Set tag for this route\n"
2053 "Distance value for this prefix\n"
2056 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
2057 struct zebra_vrf
*zvrf
= vrf
->info
;
2060 * Coverity is complaining that prefix could
2061 * be dereferenced, but we know that prefix will
2062 * valid. Add an assert to make it happy
2065 return zebra_static_route_leak(vty
, zvrf
, zvrf
,
2066 AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
2067 NULL
, from_str
, NULL
, NULL
, flag
,
2068 tag_str
, distance_str
, label
);
2071 DEFPY(ipv6_route_address_interface
,
2072 ipv6_route_address_interface_cmd
,
2073 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2077 tag (1-4294967295) \
2085 "Establish static routes\n"
2086 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2087 "IPv6 source-dest route\n"
2088 "IPv6 source prefix\n"
2089 "IPv6 gateway address\n"
2090 "IPv6 gateway interface name\n"
2091 "Set tag for this route\n"
2093 "Distance value for this prefix\n"
2098 struct zebra_vrf
*zvrf
;
2099 struct zebra_vrf
*nh_zvrf
;
2101 zvrf
= zebra_vrf_lookup_by_name(vrf
);
2103 vty_out(vty
, "%% vrf %s is not defined\n",
2105 return CMD_WARNING_CONFIG_FAILED
;
2109 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
2114 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
2116 return CMD_WARNING_CONFIG_FAILED
;
2119 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
2120 AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
2121 NULL
, from_str
, gate_str
, ifname
, NULL
,
2122 tag_str
, distance_str
, label
);
2125 DEFPY(ipv6_route_address_interface_vrf
,
2126 ipv6_route_address_interface_vrf_cmd
,
2127 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2131 tag (1-4294967295) \
2138 "Establish static routes\n"
2139 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2140 "IPv6 source-dest route\n"
2141 "IPv6 source prefix\n"
2142 "IPv6 gateway address\n"
2143 "IPv6 gateway interface name\n"
2144 "Set tag for this route\n"
2146 "Distance value for this prefix\n"
2150 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
2151 struct zebra_vrf
*zvrf
= vrf
->info
;
2152 struct zebra_vrf
*nh_zvrf
;
2155 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
2160 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
2162 return CMD_WARNING_CONFIG_FAILED
;
2165 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
2166 AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
2167 NULL
, from_str
, gate_str
, ifname
, NULL
,
2168 tag_str
, distance_str
, label
);
2173 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2174 <X:X::X:X$gate|INTERFACE$ifname> \
2176 tag (1-4294967295) \
2184 "Establish static routes\n"
2185 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2186 "IPv6 source-dest route\n"
2187 "IPv6 source prefix\n"
2188 "IPv6 gateway address\n"
2189 "IPv6 gateway interface name\n"
2190 "Set tag for this route\n"
2192 "Distance value for this prefix\n"
2197 struct zebra_vrf
*zvrf
;
2198 struct zebra_vrf
*nh_zvrf
;
2200 zvrf
= zebra_vrf_lookup_by_name(vrf
);
2202 vty_out(vty
, "%% vrf %s is not defined\n",
2204 return CMD_WARNING_CONFIG_FAILED
;
2208 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
2213 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
2215 return CMD_WARNING_CONFIG_FAILED
;
2218 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
2219 AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
2220 NULL
, from_str
, gate_str
, ifname
, NULL
,
2221 tag_str
, distance_str
, label
);
2224 DEFPY(ipv6_route_vrf
,
2226 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
2227 <X:X::X:X$gate|INTERFACE$ifname> \
2229 tag (1-4294967295) \
2236 "Establish static routes\n"
2237 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2238 "IPv6 source-dest route\n"
2239 "IPv6 source prefix\n"
2240 "IPv6 gateway address\n"
2241 "IPv6 gateway interface name\n"
2242 "Set tag for this route\n"
2244 "Distance value for this prefix\n"
2248 VTY_DECLVAR_CONTEXT(vrf
, vrf
);
2249 struct zebra_vrf
*zvrf
= vrf
->info
;
2250 struct zebra_vrf
*nh_zvrf
;
2253 nh_zvrf
= zebra_vrf_lookup_by_name(nexthop_vrf
);
2258 vty_out(vty
, "%% nexthop vrf %s is not defined\n",
2260 return CMD_WARNING_CONFIG_FAILED
;
2263 return zebra_static_route_leak(vty
, zvrf
, nh_zvrf
,
2264 AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
2265 NULL
, from_str
, gate_str
, ifname
, NULL
,
2266 tag_str
, distance_str
, label
);
2270 * Show IPv6 mroute command.Used to dump
2271 * the Multicast routing table.
2273 DEFUN (show_ipv6_mroute
,
2274 show_ipv6_mroute_cmd
,
2275 "show ipv6 mroute [vrf NAME]",
2278 "IPv6 Multicast routing table\n"
2281 struct route_table
*table
;
2282 struct route_node
*rn
;
2283 struct route_entry
*re
;
2285 vrf_id_t vrf_id
= VRF_DEFAULT
;
2288 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2290 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2294 /* Show all IPv6 route. */
2295 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2296 RNODE_FOREACH_RE (rn
, re
) {
2298 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2301 vty_show_ip_route(vty
, rn
, re
, NULL
);
2306 DEFUN (show_ipv6_mroute_vrf_all
,
2307 show_ipv6_mroute_vrf_all_cmd
,
2308 "show ipv6 mroute vrf all",
2311 "IPv6 Multicast routing table\n"
2312 VRF_ALL_CMD_HELP_STR
)
2314 struct route_table
*table
;
2315 struct route_node
*rn
;
2316 struct route_entry
*re
;
2318 struct zebra_vrf
*zvrf
;
2321 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2322 if ((zvrf
= vrf
->info
) == NULL
2323 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2326 /* Show all IPv6 route. */
2327 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2328 RNODE_FOREACH_RE (rn
, re
) {
2330 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2333 vty_show_ip_route(vty
, rn
, re
, NULL
);
2339 DEFUN (allow_external_route_update
,
2340 allow_external_route_update_cmd
,
2341 "allow-external-route-update",
2342 "Allow FRR routes to be overwritten by external processes\n")
2349 DEFUN (no_allow_external_route_update
,
2350 no_allow_external_route_update_cmd
,
2351 "no allow-external-route-update",
2353 "Allow FRR routes to be overwritten by external processes\n")
2368 struct zebra_vrf
*zvrf
;
2370 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2371 if (!(zvrf
= vrf
->info
))
2373 if (zvrf_id(zvrf
) == VRF_DEFAULT
)
2376 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2377 if (zvrf_id(zvrf
) == VRF_UNKNOWN
2378 || !zvrf_is_active(zvrf
))
2379 vty_out(vty
, "inactive");
2380 else if (zvrf_ns_name(zvrf
))
2381 vty_out(vty
, "id %u netns %s",
2382 zvrf_id(zvrf
), zvrf_ns_name(zvrf
));
2384 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2386 if (vrf_is_user_cfged(vrf
))
2387 vty_out(vty
, " (configured)");
2394 DEFUN (default_vrf_vni_mapping
,
2395 default_vrf_vni_mapping_cmd
,
2396 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2397 "VNI corresponding to the DEFAULT VRF\n"
2399 "Prefix routes only \n")
2402 char err
[ERR_STR_SZ
];
2403 struct zebra_vrf
*zvrf
= NULL
;
2404 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2407 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2414 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2417 vty_out(vty
, "%s\n", err
);
2424 DEFUN (no_default_vrf_vni_mapping
,
2425 no_default_vrf_vni_mapping_cmd
,
2426 "no vni " CMD_VNI_RANGE
,
2428 "VNI corresponding to DEFAULT VRF\n"
2432 char err
[ERR_STR_SZ
];
2433 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2434 struct zebra_vrf
*zvrf
= NULL
;
2436 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2440 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2442 vty_out(vty
, "%s\n", err
);
2449 DEFUN (vrf_vni_mapping
,
2450 vrf_vni_mapping_cmd
,
2451 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2452 "VNI corresponding to tenant VRF\n"
2454 "prefix-routes-only\n")
2459 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2460 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2461 char err
[ERR_STR_SZ
];
2469 /* Mark as having FRR configuration */
2470 vrf_set_user_cfged(vrf
);
2471 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2474 vty_out(vty
, "%s\n", err
);
2481 DEFUN (no_vrf_vni_mapping
,
2482 no_vrf_vni_mapping_cmd
,
2483 "no vni " CMD_VNI_RANGE
,
2485 "VNI corresponding to tenant VRF\n"
2489 char err
[ERR_STR_SZ
];
2490 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2492 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2497 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2499 vty_out(vty
, "%s\n", err
);
2503 /* If no other FRR config for this VRF, mark accordingly. */
2504 if (!zebra_vrf_has_config(zvrf
))
2505 vrf_reset_user_cfged(vrf
);
2511 DEFUN (show_vrf_vni
,
2513 "show vrf vni [json]",
2520 struct zebra_vrf
*zvrf
;
2521 json_object
*json
= NULL
;
2522 json_object
*json_vrfs
= NULL
;
2523 u_char uj
= use_json(argc
, argv
);
2526 json
= json_object_new_object();
2527 json_vrfs
= json_object_new_array();
2531 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n",
2532 "VRF", "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2534 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
2539 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2543 json_object_object_add(json
, "vrfs", json_vrfs
);
2544 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2545 json
, JSON_C_TO_STRING_PRETTY
));
2546 json_object_free(json
);
2552 DEFUN (show_evpn_global
,
2553 show_evpn_global_cmd
,
2559 u_char uj
= use_json(argc
, argv
);
2561 zebra_vxlan_print_evpn(vty
, uj
);
2565 DEFUN (show_evpn_vni
,
2567 "show evpn vni [json]",
2570 "VxLAN information\n"
2573 struct zebra_vrf
*zvrf
;
2574 u_char uj
= use_json(argc
, argv
);
2576 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2577 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2581 DEFUN (show_evpn_vni_vni
,
2582 show_evpn_vni_vni_cmd
,
2583 "show evpn vni " CMD_VNI_RANGE
"[json]",
2586 "VxLAN Network Identifier\n"
2590 struct zebra_vrf
*zvrf
;
2592 u_char uj
= use_json(argc
, argv
);
2594 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2595 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2596 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2600 DEFUN (show_evpn_rmac_vni_mac
,
2601 show_evpn_rmac_vni_mac_cmd
,
2602 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2609 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2614 u_char uj
= use_json(argc
, argv
);
2616 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2617 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2618 vty_out(vty
, "%% Malformed MAC address\n");
2621 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2625 DEFUN (show_evpn_rmac_vni
,
2626 show_evpn_rmac_vni_cmd
,
2627 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2636 u_char uj
= use_json(argc
, argv
);
2638 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2639 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2644 DEFUN (show_evpn_rmac_vni_all
,
2645 show_evpn_rmac_vni_all_cmd
,
2646 "show evpn rmac vni all [json]",
2654 u_char uj
= use_json(argc
, argv
);
2656 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2661 DEFUN (show_evpn_nh_vni_ip
,
2662 show_evpn_nh_vni_ip_cmd
,
2663 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2670 "Host address (ipv4 or ipv6)\n"
2675 u_char uj
= use_json(argc
, argv
);
2677 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2678 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2680 vty_out(vty
, "%% Malformed Neighbor address\n");
2683 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2688 DEFUN (show_evpn_nh_vni
,
2689 show_evpn_nh_vni_cmd
,
2690 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2699 u_char uj
= use_json(argc
, argv
);
2701 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2702 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2707 DEFUN (show_evpn_nh_vni_all
,
2708 show_evpn_nh_vni_all_cmd
,
2709 "show evpn next-hops vni all [json]",
2717 u_char uj
= use_json(argc
, argv
);
2719 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2724 DEFUN (show_evpn_mac_vni
,
2725 show_evpn_mac_vni_cmd
,
2726 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2730 "VxLAN Network Identifier\n"
2734 struct zebra_vrf
*zvrf
;
2736 u_char uj
= use_json(argc
, argv
);
2738 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2739 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2740 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2744 DEFUN (show_evpn_mac_vni_all
,
2745 show_evpn_mac_vni_all_cmd
,
2746 "show evpn mac vni all [json]",
2750 "VxLAN Network Identifier\n"
2754 struct zebra_vrf
*zvrf
;
2755 u_char uj
= use_json(argc
, argv
);
2757 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2758 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
2762 DEFUN (show_evpn_mac_vni_all_vtep
,
2763 show_evpn_mac_vni_all_vtep_cmd
,
2764 "show evpn mac vni all vtep A.B.C.D [json]",
2768 "VxLAN Network Identifier\n"
2771 "Remote VTEP IP address\n"
2774 struct zebra_vrf
*zvrf
;
2775 struct in_addr vtep_ip
;
2776 u_char uj
= use_json(argc
, argv
);
2778 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2780 vty_out(vty
, "%% Malformed VTEP IP address\n");
2783 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2784 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2790 DEFUN (show_evpn_mac_vni_mac
,
2791 show_evpn_mac_vni_mac_cmd
,
2792 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2796 "VxLAN Network Identifier\n"
2799 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2801 struct zebra_vrf
*zvrf
;
2805 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2806 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2807 vty_out(vty
, "%% Malformed MAC address");
2810 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2811 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2815 DEFUN (show_evpn_mac_vni_vtep
,
2816 show_evpn_mac_vni_vtep_cmd
,
2817 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2821 "VxLAN Network Identifier\n"
2824 "Remote VTEP IP address\n"
2827 struct zebra_vrf
*zvrf
;
2829 struct in_addr vtep_ip
;
2830 u_char uj
= use_json(argc
, argv
);
2832 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2833 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2835 vty_out(vty
, "%% Malformed VTEP IP address\n");
2839 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2840 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2844 DEFUN (show_evpn_neigh_vni
,
2845 show_evpn_neigh_vni_cmd
,
2846 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2849 "ARP and ND cache\n"
2850 "VxLAN Network Identifier\n"
2854 struct zebra_vrf
*zvrf
;
2856 u_char uj
= use_json(argc
, argv
);
2858 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2859 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2860 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2864 DEFUN (show_evpn_neigh_vni_all
,
2865 show_evpn_neigh_vni_all_cmd
,
2866 "show evpn arp-cache vni all [json]",
2869 "ARP and ND cache\n"
2870 "VxLAN Network Identifier\n"
2874 struct zebra_vrf
*zvrf
;
2875 u_char uj
= use_json(argc
, argv
);
2877 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2878 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2882 DEFUN (show_evpn_neigh_vni_neigh
,
2883 show_evpn_neigh_vni_neigh_cmd
,
2884 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2887 "ARP and ND cache\n"
2888 "VxLAN Network Identifier\n"
2891 "Neighbor address (IPv4 or IPv6 address)\n"
2894 struct zebra_vrf
*zvrf
;
2897 u_char uj
= use_json(argc
, argv
);
2899 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2900 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2902 vty_out(vty
, "%% Malformed Neighbor address\n");
2905 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2906 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2910 DEFUN (show_evpn_neigh_vni_vtep
,
2911 show_evpn_neigh_vni_vtep_cmd
,
2912 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2915 "ARP and ND cache\n"
2916 "VxLAN Network Identifier\n"
2919 "Remote VTEP IP address\n"
2922 struct zebra_vrf
*zvrf
;
2924 struct in_addr vtep_ip
;
2925 u_char uj
= use_json(argc
, argv
);
2927 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2928 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2930 vty_out(vty
, "%% Malformed VTEP IP address\n");
2934 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2935 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2939 /* Static ip route configuration write function. */
2940 static int zebra_ip_config(struct vty
*vty
)
2944 write
+= zebra_import_table_config(vty
);
2949 DEFUN (ip_zebra_import_table_distance
,
2950 ip_zebra_import_table_distance_cmd
,
2951 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2953 "import routes from non-main kernel table\n"
2954 "kernel routing table id\n"
2955 "Distance for imported routes\n"
2956 "Default distance value\n"
2957 "route-map for filtering\n"
2960 u_int32_t table_id
= 0;
2962 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2963 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2965 strmatch(argv
[argc
- 2]->text
, "route-map")
2966 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2970 if (argc
== 7 || (argc
== 5 && !rmap
))
2971 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2973 if (!is_zebra_valid_kernel_table(table_id
)) {
2975 "Invalid routing table ID, %d. Must be in range 1-252\n",
2978 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2982 if (is_zebra_main_routing_table(table_id
)) {
2984 "Invalid routing table ID, %d. Must be non-default table\n",
2987 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2991 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2993 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2998 DEFUN_HIDDEN (zebra_packet_process
,
2999 zebra_packet_process_cmd
,
3000 "zebra zapi-packets (1-10000)",
3003 "Number of packets to process before relinquishing thread\n")
3005 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3007 zebrad
.packets_to_process
= packets
;
3012 DEFUN_HIDDEN (no_zebra_packet_process
,
3013 no_zebra_packet_process_cmd
,
3014 "no zebra zapi-packets [(1-10000)]",
3018 "Number of packets to process before relinquishing thread\n")
3020 zebrad
.packets_to_process
= ZEBRA_ZAPI_PACKETS_TO_PROCESS
;
3025 DEFUN_HIDDEN (zebra_workqueue_timer
,
3026 zebra_workqueue_timer_cmd
,
3027 "zebra work-queue (0-10000)",
3030 "Time in milliseconds\n")
3032 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3033 zebrad
.ribq
->spec
.hold
= timer
;
3038 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3039 no_zebra_workqueue_timer_cmd
,
3040 "no zebra work-queue [(0-10000)]",
3044 "Time in milliseconds\n")
3046 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3051 DEFUN (no_ip_zebra_import_table
,
3052 no_ip_zebra_import_table_cmd
,
3053 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3056 "import routes from non-main kernel table\n"
3057 "kernel routing table id\n"
3058 "Distance for imported routes\n"
3059 "Default distance value\n"
3060 "route-map for filtering\n"
3063 u_int32_t table_id
= 0;
3064 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3066 if (!is_zebra_valid_kernel_table(table_id
)) {
3068 "Invalid routing table ID. Must be in range 1-252\n");
3072 if (is_zebra_main_routing_table(table_id
)) {
3074 "Invalid routing table ID, %d. Must be non-default table\n",
3079 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
3082 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
3085 static int config_write_protocol(struct vty
*vty
)
3088 vty_out(vty
, "allow-external-route-update\n");
3090 if (zebra_rnh_ip_default_route
)
3091 vty_out(vty
, "ip nht resolve-via-default\n");
3093 if (zebra_rnh_ipv6_default_route
)
3094 vty_out(vty
, "ipv6 nht resolve-via-default\n");
3096 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3097 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
3099 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3101 "zebra zapi-packets %u\n", zebrad
.packets_to_process
);
3103 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3105 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3106 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3107 ipv4_multicast_mode
== MCAST_URIB_ONLY
3109 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3111 : ipv4_multicast_mode
3112 == MCAST_MIX_MRIB_FIRST
3114 : ipv4_multicast_mode
3115 == MCAST_MIX_DISTANCE
3119 zebra_routemap_config_write_protocol(vty
);
3125 /* Display default rtm_table for all clients. */
3130 "default routing table to use for all clients\n")
3132 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
3136 DEFUN (config_table
,
3139 "Configure target kernel routing table\n"
3142 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
3146 DEFUN (no_config_table
,
3147 no_config_table_cmd
,
3148 "no table [TABLENO]",
3150 "Configure target kernel routing table\n"
3153 zebrad
.rtm_table_default
= 0;
3167 " Route Route Neighbor LSP LSP\n");
3169 "VRF Installs Removals Updates Installs Removals\n");
3171 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
3172 struct zebra_vrf
*zvrf
= vrf
->info
;
3174 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
3175 " %10" PRIu64
" %10" PRIu64
"\n",
3176 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3177 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3178 zvrf
->lsp_removals
);
3184 DEFUN (ip_forwarding
,
3188 "Turn on IP forwarding\n")
3194 ret
= ipforward_on();
3197 vty_out(vty
, "Can't turn on IP forwarding\n");
3198 return CMD_WARNING_CONFIG_FAILED
;
3204 DEFUN (no_ip_forwarding
,
3205 no_ip_forwarding_cmd
,
3209 "Turn off IP forwarding\n")
3215 ret
= ipforward_off();
3218 vty_out(vty
, "Can't turn off IP forwarding\n");
3219 return CMD_WARNING_CONFIG_FAILED
;
3225 /* Only display ip forwarding is enabled or not. */
3226 DEFUN (show_ip_forwarding
,
3227 show_ip_forwarding_cmd
,
3228 "show ip forwarding",
3231 "IP forwarding status\n")
3238 vty_out(vty
, "IP forwarding is off\n");
3240 vty_out(vty
, "IP forwarding is on\n");
3244 /* Only display ipv6 forwarding is enabled or not. */
3245 DEFUN (show_ipv6_forwarding
,
3246 show_ipv6_forwarding_cmd
,
3247 "show ipv6 forwarding",
3249 "IPv6 information\n"
3250 "Forwarding status\n")
3254 ret
= ipforward_ipv6();
3258 vty_out(vty
, "ipv6 forwarding is unknown\n");
3261 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3264 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3267 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3273 DEFUN (ipv6_forwarding
,
3274 ipv6_forwarding_cmd
,
3277 "Turn on IPv6 forwarding\n")
3281 ret
= ipforward_ipv6();
3283 ret
= ipforward_ipv6_on();
3286 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3287 return CMD_WARNING_CONFIG_FAILED
;
3293 DEFUN (no_ipv6_forwarding
,
3294 no_ipv6_forwarding_cmd
,
3295 "no ipv6 forwarding",
3298 "Turn off IPv6 forwarding\n")
3302 ret
= ipforward_ipv6();
3304 ret
= ipforward_ipv6_off();
3307 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3308 return CMD_WARNING_CONFIG_FAILED
;
3314 /* Table configuration write function. */
3315 static int config_write_table(struct vty
*vty
)
3317 if (zebrad
.rtm_table_default
)
3318 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
3322 /* IPForwarding configuration write function. */
3323 static int config_write_forwarding(struct vty
*vty
)
3325 /* FIXME: Find better place for that. */
3326 router_id_write(vty
);
3329 vty_out(vty
, "no ip forwarding\n");
3330 if (!ipforward_ipv6())
3331 vty_out(vty
, "no ipv6 forwarding\n");
3332 vty_out(vty
, "!\n");
3336 /* IP node for static routes. */
3337 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3338 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3339 /* table node for routing tables. */
3340 static struct cmd_node table_node
= {TABLE_NODE
,
3341 "", /* This node has no interface. */
3343 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3344 "", /* This node has no interface. */
3348 void zebra_vty_init(void)
3350 /* Install configuration write function. */
3351 install_node(&table_node
, config_write_table
);
3352 install_node(&forwarding_node
, config_write_forwarding
);
3354 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3355 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3356 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3357 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3360 install_element(VIEW_NODE
, &show_table_cmd
);
3361 install_element(CONFIG_NODE
, &config_table_cmd
);
3362 install_element(CONFIG_NODE
, &no_config_table_cmd
);
3363 #endif /* HAVE_NETLINK */
3365 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3366 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3367 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3370 zebra_route_map_init();
3372 install_node(&ip_node
, zebra_ip_config
);
3373 install_node(&protocol_node
, config_write_protocol
);
3375 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3376 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3377 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
3378 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3379 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3380 install_element(CONFIG_NODE
, &ip_route_blackhole_cmd
);
3381 install_element(VRF_NODE
, &ip_route_blackhole_vrf_cmd
);
3382 install_element(CONFIG_NODE
, &ip_route_address_interface_cmd
);
3383 install_element(VRF_NODE
, &ip_route_address_interface_vrf_cmd
);
3384 install_element(CONFIG_NODE
, &ip_route_cmd
);
3385 install_element(VRF_NODE
, &ip_route_vrf_cmd
);
3386 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3387 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3388 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3389 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3390 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3391 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3393 install_element(VIEW_NODE
, &show_vrf_cmd
);
3394 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3395 install_element(VIEW_NODE
, &show_route_cmd
);
3396 install_element(VIEW_NODE
, &show_route_table_cmd
);
3397 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3398 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3399 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3400 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
3401 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
3402 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
3404 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3405 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3407 install_element(CONFIG_NODE
, &ipv6_route_blackhole_cmd
);
3408 install_element(VRF_NODE
, &ipv6_route_blackhole_vrf_cmd
);
3409 install_element(CONFIG_NODE
, &ipv6_route_address_interface_cmd
);
3410 install_element(VRF_NODE
, &ipv6_route_address_interface_vrf_cmd
);
3411 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
3412 install_element(VRF_NODE
, &ipv6_route_vrf_cmd
);
3413 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3414 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3415 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3416 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3417 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3419 /* Commands for VRF */
3420 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3422 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3423 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3424 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3425 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3426 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3427 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3428 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3429 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3430 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3431 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3432 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3433 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3434 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3435 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3436 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3437 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3438 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3439 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3441 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3442 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3443 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3444 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);