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 vty_out(vty
, "inactive");
2380 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2382 if (vrf_is_user_cfged(vrf
))
2383 vty_out(vty
, " (configured)");
2390 DEFUN (default_vrf_vni_mapping
,
2391 default_vrf_vni_mapping_cmd
,
2392 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2393 "VNI corresponding to the DEFAULT VRF\n"
2395 "Prefix routes only \n")
2398 char err
[ERR_STR_SZ
];
2399 struct zebra_vrf
*zvrf
= NULL
;
2400 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2403 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2410 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2413 vty_out(vty
, "%s\n", err
);
2420 DEFUN (no_default_vrf_vni_mapping
,
2421 no_default_vrf_vni_mapping_cmd
,
2422 "no vni " CMD_VNI_RANGE
,
2424 "VNI corresponding to DEFAULT VRF\n"
2428 char err
[ERR_STR_SZ
];
2429 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2430 struct zebra_vrf
*zvrf
= NULL
;
2432 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2436 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2438 vty_out(vty
, "%s\n", err
);
2445 DEFUN (vrf_vni_mapping
,
2446 vrf_vni_mapping_cmd
,
2447 "vni " CMD_VNI_RANGE
"[prefix-routes-only]",
2448 "VNI corresponding to tenant VRF\n"
2450 "prefix-routes-only\n")
2455 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2456 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
2457 char err
[ERR_STR_SZ
];
2465 /* Mark as having FRR configuration */
2466 vrf_set_user_cfged(vrf
);
2467 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
,
2470 vty_out(vty
, "%s\n", err
);
2477 DEFUN (no_vrf_vni_mapping
,
2478 no_vrf_vni_mapping_cmd
,
2479 "no vni " CMD_VNI_RANGE
,
2481 "VNI corresponding to tenant VRF\n"
2485 char err
[ERR_STR_SZ
];
2486 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
2488 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
2493 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0, 0);
2495 vty_out(vty
, "%s\n", err
);
2499 /* If no other FRR config for this VRF, mark accordingly. */
2500 if (!zebra_vrf_has_config(zvrf
))
2501 vrf_reset_user_cfged(vrf
);
2507 DEFUN (show_vrf_vni
,
2509 "show vrf vni [json]",
2516 struct zebra_vrf
*zvrf
;
2517 json_object
*json
= NULL
;
2518 json_object
*json_vrfs
= NULL
;
2519 u_char uj
= use_json(argc
, argv
);
2522 json
= json_object_new_object();
2523 json_vrfs
= json_object_new_array();
2527 vty_out(vty
, "%-37s %-10s %-20s %-20s %-5s %-18s\n",
2528 "VRF", "VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
2530 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
2535 zebra_vxlan_print_vrf_vni(vty
, zvrf
, json_vrfs
);
2539 json_object_object_add(json
, "vrfs", json_vrfs
);
2540 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2541 json
, JSON_C_TO_STRING_PRETTY
));
2542 json_object_free(json
);
2548 DEFUN (show_evpn_global
,
2549 show_evpn_global_cmd
,
2555 u_char uj
= use_json(argc
, argv
);
2557 zebra_vxlan_print_evpn(vty
, uj
);
2561 DEFUN (show_evpn_vni
,
2563 "show evpn vni [json]",
2566 "VxLAN information\n"
2569 struct zebra_vrf
*zvrf
;
2570 u_char uj
= use_json(argc
, argv
);
2572 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2573 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2577 DEFUN (show_evpn_vni_vni
,
2578 show_evpn_vni_vni_cmd
,
2579 "show evpn vni " CMD_VNI_RANGE
"[json]",
2582 "VxLAN Network Identifier\n"
2586 struct zebra_vrf
*zvrf
;
2588 u_char uj
= use_json(argc
, argv
);
2590 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2591 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2592 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2596 DEFUN (show_evpn_rmac_vni_mac
,
2597 show_evpn_rmac_vni_mac_cmd
,
2598 "show evpn rmac vni " CMD_VNI_RANGE
" mac WORD [json]",
2605 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2610 u_char uj
= use_json(argc
, argv
);
2612 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2613 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2614 vty_out(vty
, "%% Malformed MAC address\n");
2617 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2621 DEFUN (show_evpn_rmac_vni
,
2622 show_evpn_rmac_vni_cmd
,
2623 "show evpn rmac vni " CMD_VNI_RANGE
"[json]",
2632 u_char uj
= use_json(argc
, argv
);
2634 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2635 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2640 DEFUN (show_evpn_rmac_vni_all
,
2641 show_evpn_rmac_vni_all_cmd
,
2642 "show evpn rmac vni all [json]",
2650 u_char uj
= use_json(argc
, argv
);
2652 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2657 DEFUN (show_evpn_nh_vni_ip
,
2658 show_evpn_nh_vni_ip_cmd
,
2659 "show evpn next-hops vni " CMD_VNI_RANGE
" ip WORD [json]",
2666 "Host address (ipv4 or ipv6)\n"
2671 u_char uj
= use_json(argc
, argv
);
2673 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2674 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2676 vty_out(vty
, "%% Malformed Neighbor address\n");
2679 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2684 DEFUN (show_evpn_nh_vni
,
2685 show_evpn_nh_vni_cmd
,
2686 "show evpn next-hops vni " CMD_VNI_RANGE
"[json]",
2695 u_char uj
= use_json(argc
, argv
);
2697 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2698 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2703 DEFUN (show_evpn_nh_vni_all
,
2704 show_evpn_nh_vni_all_cmd
,
2705 "show evpn next-hops vni all [json]",
2713 u_char uj
= use_json(argc
, argv
);
2715 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2720 DEFUN (show_evpn_mac_vni
,
2721 show_evpn_mac_vni_cmd
,
2722 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2726 "VxLAN Network Identifier\n"
2730 struct zebra_vrf
*zvrf
;
2732 u_char uj
= use_json(argc
, argv
);
2734 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2735 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2736 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2740 DEFUN (show_evpn_mac_vni_all
,
2741 show_evpn_mac_vni_all_cmd
,
2742 "show evpn mac vni all [json]",
2746 "VxLAN Network Identifier\n"
2750 struct zebra_vrf
*zvrf
;
2751 u_char uj
= use_json(argc
, argv
);
2753 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2754 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
2758 DEFUN (show_evpn_mac_vni_all_vtep
,
2759 show_evpn_mac_vni_all_vtep_cmd
,
2760 "show evpn mac vni all vtep A.B.C.D [json]",
2764 "VxLAN Network Identifier\n"
2767 "Remote VTEP IP address\n"
2770 struct zebra_vrf
*zvrf
;
2771 struct in_addr vtep_ip
;
2772 u_char uj
= use_json(argc
, argv
);
2774 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2776 vty_out(vty
, "%% Malformed VTEP IP address\n");
2779 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2780 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2786 DEFUN (show_evpn_mac_vni_mac
,
2787 show_evpn_mac_vni_mac_cmd
,
2788 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2792 "VxLAN Network Identifier\n"
2795 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2797 struct zebra_vrf
*zvrf
;
2801 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2802 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2803 vty_out(vty
, "%% Malformed MAC address");
2806 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2807 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2811 DEFUN (show_evpn_mac_vni_vtep
,
2812 show_evpn_mac_vni_vtep_cmd
,
2813 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2817 "VxLAN Network Identifier\n"
2820 "Remote VTEP IP address\n"
2823 struct zebra_vrf
*zvrf
;
2825 struct in_addr vtep_ip
;
2826 u_char uj
= use_json(argc
, argv
);
2828 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2829 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2831 vty_out(vty
, "%% Malformed VTEP IP address\n");
2835 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2836 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2840 DEFUN (show_evpn_neigh_vni
,
2841 show_evpn_neigh_vni_cmd
,
2842 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2845 "ARP and ND cache\n"
2846 "VxLAN Network Identifier\n"
2850 struct zebra_vrf
*zvrf
;
2852 u_char uj
= use_json(argc
, argv
);
2854 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2855 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2856 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2860 DEFUN (show_evpn_neigh_vni_all
,
2861 show_evpn_neigh_vni_all_cmd
,
2862 "show evpn arp-cache vni all [json]",
2865 "ARP and ND cache\n"
2866 "VxLAN Network Identifier\n"
2870 struct zebra_vrf
*zvrf
;
2871 u_char uj
= use_json(argc
, argv
);
2873 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2874 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2878 DEFUN (show_evpn_neigh_vni_neigh
,
2879 show_evpn_neigh_vni_neigh_cmd
,
2880 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2883 "ARP and ND cache\n"
2884 "VxLAN Network Identifier\n"
2887 "Neighbor address (IPv4 or IPv6 address)\n"
2890 struct zebra_vrf
*zvrf
;
2893 u_char uj
= use_json(argc
, argv
);
2895 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2896 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2898 vty_out(vty
, "%% Malformed Neighbor address\n");
2901 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2902 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2906 DEFUN (show_evpn_neigh_vni_vtep
,
2907 show_evpn_neigh_vni_vtep_cmd
,
2908 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2911 "ARP and ND cache\n"
2912 "VxLAN Network Identifier\n"
2915 "Remote VTEP IP address\n"
2918 struct zebra_vrf
*zvrf
;
2920 struct in_addr vtep_ip
;
2921 u_char uj
= use_json(argc
, argv
);
2923 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2924 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2926 vty_out(vty
, "%% Malformed VTEP IP address\n");
2930 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2931 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2935 /* Static ip route configuration write function. */
2936 static int zebra_ip_config(struct vty
*vty
)
2940 write
+= zebra_import_table_config(vty
);
2945 DEFUN (ip_zebra_import_table_distance
,
2946 ip_zebra_import_table_distance_cmd
,
2947 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2949 "import routes from non-main kernel table\n"
2950 "kernel routing table id\n"
2951 "Distance for imported routes\n"
2952 "Default distance value\n"
2953 "route-map for filtering\n"
2956 u_int32_t table_id
= 0;
2958 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2959 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2961 strmatch(argv
[argc
- 2]->text
, "route-map")
2962 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2966 if (argc
== 7 || (argc
== 5 && !rmap
))
2967 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2969 if (!is_zebra_valid_kernel_table(table_id
)) {
2971 "Invalid routing table ID, %d. Must be in range 1-252\n",
2974 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2978 if (is_zebra_main_routing_table(table_id
)) {
2980 "Invalid routing table ID, %d. Must be non-default table\n",
2983 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2987 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2989 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2994 DEFUN_HIDDEN (zebra_packet_process
,
2995 zebra_packet_process_cmd
,
2996 "zebra zapi-packets (1-10000)",
2999 "Number of packets to process before relinquishing thread\n")
3001 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
3003 zebrad
.packets_to_process
= packets
;
3008 DEFUN_HIDDEN (no_zebra_packet_process
,
3009 no_zebra_packet_process_cmd
,
3010 "no zebra zapi-packets [(1-10000)]",
3014 "Number of packets to process before relinquishing thread\n")
3016 zebrad
.packets_to_process
= ZEBRA_ZAPI_PACKETS_TO_PROCESS
;
3021 DEFUN_HIDDEN (zebra_workqueue_timer
,
3022 zebra_workqueue_timer_cmd
,
3023 "zebra work-queue (0-10000)",
3026 "Time in milliseconds\n")
3028 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
3029 zebrad
.ribq
->spec
.hold
= timer
;
3034 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
3035 no_zebra_workqueue_timer_cmd
,
3036 "no zebra work-queue [(0-10000)]",
3040 "Time in milliseconds\n")
3042 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
3047 DEFUN (no_ip_zebra_import_table
,
3048 no_ip_zebra_import_table_cmd
,
3049 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3052 "import routes from non-main kernel table\n"
3053 "kernel routing table id\n"
3054 "Distance for imported routes\n"
3055 "Default distance value\n"
3056 "route-map for filtering\n"
3059 u_int32_t table_id
= 0;
3060 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3062 if (!is_zebra_valid_kernel_table(table_id
)) {
3064 "Invalid routing table ID. Must be in range 1-252\n");
3068 if (is_zebra_main_routing_table(table_id
)) {
3070 "Invalid routing table ID, %d. Must be non-default table\n",
3075 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
3078 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
3081 static int config_write_protocol(struct vty
*vty
)
3084 vty_out(vty
, "allow-external-route-update\n");
3086 if (zebra_rnh_ip_default_route
)
3087 vty_out(vty
, "ip nht resolve-via-default\n");
3089 if (zebra_rnh_ipv6_default_route
)
3090 vty_out(vty
, "ipv6 nht resolve-via-default\n");
3092 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
3093 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
3095 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
3097 "zebra zapi-packets %u\n", zebrad
.packets_to_process
);
3099 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3101 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3102 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3103 ipv4_multicast_mode
== MCAST_URIB_ONLY
3105 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3107 : ipv4_multicast_mode
3108 == MCAST_MIX_MRIB_FIRST
3110 : ipv4_multicast_mode
3111 == MCAST_MIX_DISTANCE
3115 zebra_routemap_config_write_protocol(vty
);
3121 /* Display default rtm_table for all clients. */
3126 "default routing table to use for all clients\n")
3128 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
3132 DEFUN (config_table
,
3135 "Configure target kernel routing table\n"
3138 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
3142 DEFUN (no_config_table
,
3143 no_config_table_cmd
,
3144 "no table [TABLENO]",
3146 "Configure target kernel routing table\n"
3149 zebrad
.rtm_table_default
= 0;
3163 " Route Route Neighbor LSP LSP\n");
3165 "VRF Installs Removals Updates Installs Removals\n");
3167 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
3168 struct zebra_vrf
*zvrf
= vrf
->info
;
3170 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
3171 " %10" PRIu64
" %10" PRIu64
"\n",
3172 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
3173 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
3174 zvrf
->lsp_removals
);
3180 DEFUN (ip_forwarding
,
3184 "Turn on IP forwarding\n")
3190 ret
= ipforward_on();
3193 vty_out(vty
, "Can't turn on IP forwarding\n");
3194 return CMD_WARNING_CONFIG_FAILED
;
3200 DEFUN (no_ip_forwarding
,
3201 no_ip_forwarding_cmd
,
3205 "Turn off IP forwarding\n")
3211 ret
= ipforward_off();
3214 vty_out(vty
, "Can't turn off IP forwarding\n");
3215 return CMD_WARNING_CONFIG_FAILED
;
3221 /* Only display ip forwarding is enabled or not. */
3222 DEFUN (show_ip_forwarding
,
3223 show_ip_forwarding_cmd
,
3224 "show ip forwarding",
3227 "IP forwarding status\n")
3234 vty_out(vty
, "IP forwarding is off\n");
3236 vty_out(vty
, "IP forwarding is on\n");
3240 /* Only display ipv6 forwarding is enabled or not. */
3241 DEFUN (show_ipv6_forwarding
,
3242 show_ipv6_forwarding_cmd
,
3243 "show ipv6 forwarding",
3245 "IPv6 information\n"
3246 "Forwarding status\n")
3250 ret
= ipforward_ipv6();
3254 vty_out(vty
, "ipv6 forwarding is unknown\n");
3257 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3260 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
3263 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
3269 DEFUN (ipv6_forwarding
,
3270 ipv6_forwarding_cmd
,
3273 "Turn on IPv6 forwarding\n")
3277 ret
= ipforward_ipv6();
3279 ret
= ipforward_ipv6_on();
3282 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
3283 return CMD_WARNING_CONFIG_FAILED
;
3289 DEFUN (no_ipv6_forwarding
,
3290 no_ipv6_forwarding_cmd
,
3291 "no ipv6 forwarding",
3294 "Turn off IPv6 forwarding\n")
3298 ret
= ipforward_ipv6();
3300 ret
= ipforward_ipv6_off();
3303 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
3304 return CMD_WARNING_CONFIG_FAILED
;
3310 /* Table configuration write function. */
3311 static int config_write_table(struct vty
*vty
)
3313 if (zebrad
.rtm_table_default
)
3314 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
3318 /* IPForwarding configuration write function. */
3319 static int config_write_forwarding(struct vty
*vty
)
3321 /* FIXME: Find better place for that. */
3322 router_id_write(vty
);
3325 vty_out(vty
, "no ip forwarding\n");
3326 if (!ipforward_ipv6())
3327 vty_out(vty
, "no ipv6 forwarding\n");
3328 vty_out(vty
, "!\n");
3332 /* IP node for static routes. */
3333 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3334 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3335 /* table node for routing tables. */
3336 static struct cmd_node table_node
= {TABLE_NODE
,
3337 "", /* This node has no interface. */
3339 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
3340 "", /* This node has no interface. */
3344 void zebra_vty_init(void)
3346 /* Install configuration write function. */
3347 install_node(&table_node
, config_write_table
);
3348 install_node(&forwarding_node
, config_write_forwarding
);
3350 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
3351 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
3352 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
3353 install_element(ENABLE_NODE
, &show_zebra_cmd
);
3356 install_element(VIEW_NODE
, &show_table_cmd
);
3357 install_element(CONFIG_NODE
, &config_table_cmd
);
3358 install_element(CONFIG_NODE
, &no_config_table_cmd
);
3359 #endif /* HAVE_NETLINK */
3361 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
3362 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
3363 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
3366 zebra_route_map_init();
3368 install_node(&ip_node
, zebra_ip_config
);
3369 install_node(&protocol_node
, config_write_protocol
);
3371 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3372 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3373 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
3374 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3375 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3376 install_element(CONFIG_NODE
, &ip_route_blackhole_cmd
);
3377 install_element(VRF_NODE
, &ip_route_blackhole_vrf_cmd
);
3378 install_element(CONFIG_NODE
, &ip_route_address_interface_cmd
);
3379 install_element(VRF_NODE
, &ip_route_address_interface_vrf_cmd
);
3380 install_element(CONFIG_NODE
, &ip_route_cmd
);
3381 install_element(VRF_NODE
, &ip_route_vrf_cmd
);
3382 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3383 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3384 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
3385 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
3386 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
3387 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
3389 install_element(VIEW_NODE
, &show_vrf_cmd
);
3390 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
3391 install_element(VIEW_NODE
, &show_route_cmd
);
3392 install_element(VIEW_NODE
, &show_route_table_cmd
);
3393 install_element(VIEW_NODE
, &show_route_detail_cmd
);
3394 install_element(VIEW_NODE
, &show_route_summary_cmd
);
3395 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3396 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
3397 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
3398 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
3400 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3401 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3403 install_element(CONFIG_NODE
, &ipv6_route_blackhole_cmd
);
3404 install_element(VRF_NODE
, &ipv6_route_blackhole_vrf_cmd
);
3405 install_element(CONFIG_NODE
, &ipv6_route_address_interface_cmd
);
3406 install_element(VRF_NODE
, &ipv6_route_address_interface_vrf_cmd
);
3407 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
3408 install_element(VRF_NODE
, &ipv6_route_vrf_cmd
);
3409 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3410 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3411 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3412 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3413 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3415 /* Commands for VRF */
3416 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3418 install_element(VIEW_NODE
, &show_evpn_global_cmd
);
3419 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3420 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3421 install_element(VIEW_NODE
, &show_evpn_rmac_vni_mac_cmd
);
3422 install_element(VIEW_NODE
, &show_evpn_rmac_vni_cmd
);
3423 install_element(VIEW_NODE
, &show_evpn_rmac_vni_all_cmd
);
3424 install_element(VIEW_NODE
, &show_evpn_nh_vni_ip_cmd
);
3425 install_element(VIEW_NODE
, &show_evpn_nh_vni_cmd
);
3426 install_element(VIEW_NODE
, &show_evpn_nh_vni_all_cmd
);
3427 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3428 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3429 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3430 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3431 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3432 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3433 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3434 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3435 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
3437 install_element(CONFIG_NODE
, &default_vrf_vni_mapping_cmd
);
3438 install_element(CONFIG_NODE
, &no_default_vrf_vni_mapping_cmd
);
3439 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
3440 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);