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(struct vty
*vty
, afi_t afi
, safi_t safi
,
82 const char *negate
, const char *dest_str
,
83 const char *mask_str
, const char *src_str
,
84 const char *gate_str
, const char *ifname
,
85 const char *flag_str
, const char *tag_str
,
86 const char *distance_str
, const char *vrf_id_str
,
87 const char *label_str
)
92 struct prefix_ipv6
*src_p
= NULL
;
94 union g_addr
*gatep
= NULL
;
96 enum static_blackhole_type bh_type
= 0;
98 struct zebra_vrf
*zvrf
;
100 struct static_nh_label snh_label
;
102 ret
= str2prefix(dest_str
, &p
);
104 vty_out(vty
, "%% Malformed address\n");
105 return CMD_WARNING_CONFIG_FAILED
;
110 /* Cisco like mask notation. */
112 ret
= inet_aton(mask_str
, &mask
);
114 vty_out(vty
, "%% Malformed address\n");
115 return CMD_WARNING_CONFIG_FAILED
;
117 p
.prefixlen
= ip_masklen(mask
);
121 /* srcdest routing */
123 ret
= str2prefix(src_str
, &src
);
124 if (ret
<= 0 || src
.family
!= AF_INET6
) {
125 vty_out(vty
, "%% Malformed source address\n");
126 return CMD_WARNING_CONFIG_FAILED
;
128 src_p
= (struct prefix_ipv6
*)&src
;
135 /* Apply mask for given prefix. */
138 /* Administrative distance. */
140 distance
= atoi(distance_str
);
142 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
146 tag
= strtoul(tag_str
, NULL
, 10);
149 zvrf
= zebra_vrf_lookup_by_name(vrf_id_str
);
152 vty_out(vty
, "%% vrf %s is not defined\n", vrf_id_str
);
153 return CMD_WARNING_CONFIG_FAILED
;
157 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
161 "%% MPLS not turned on in kernel, ignoring command\n");
162 return CMD_WARNING_CONFIG_FAILED
;
164 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
169 vty_out(vty
, "%% Malformed label(s)\n");
173 "%% Cannot use reserved label(s) (%d-%d)\n",
174 MPLS_MIN_RESERVED_LABEL
,
175 MPLS_MAX_RESERVED_LABEL
);
179 "%% Too many labels. Enter %d or fewer\n",
183 return CMD_WARNING_CONFIG_FAILED
;
187 /* Null0 static route. */
188 if (ifname
!= NULL
) {
189 if (strncasecmp(ifname
, "Null0", strlen(ifname
)) == 0 ||
190 strncasecmp(ifname
, "reject", strlen(ifname
)) == 0 ||
191 strncasecmp(ifname
, "blackhole", strlen(ifname
)) == 0) {
192 vty_out(vty
, "%% Nexthop interface cannot be Null0, reject or blackhole\n");
193 return CMD_WARNING_CONFIG_FAILED
;
199 switch (flag_str
[0]) {
201 bh_type
= STATIC_BLACKHOLE_REJECT
;
204 bh_type
= STATIC_BLACKHOLE_DROP
;
207 bh_type
= STATIC_BLACKHOLE_NULL
;
210 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
211 return CMD_WARNING_CONFIG_FAILED
;
216 if (inet_pton(afi2family(afi
), gate_str
, &gate
) != 1) {
217 vty_out(vty
, "%% Malformed nexthop address %s\n",
219 return CMD_WARNING_CONFIG_FAILED
;
224 if (gate_str
== NULL
&& ifname
== NULL
)
225 type
= STATIC_BLACKHOLE
;
226 else if (gate_str
&& ifname
) {
228 type
= STATIC_IPV4_GATEWAY_IFNAME
;
230 type
= STATIC_IPV6_GATEWAY_IFNAME
;
232 type
= STATIC_IFNAME
;
235 type
= STATIC_IPV4_GATEWAY
;
237 type
= STATIC_IPV6_GATEWAY
;
241 static_add_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
242 bh_type
, tag
, distance
, zvrf
, &snh_label
);
244 static_delete_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
245 tag
, distance
, zvrf
, &snh_label
);
250 /* Static unicast routes for multicast RPF lookup. */
251 DEFPY (ip_mroute_dist
,
253 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
256 "Configure static unicast route into MRIB for multicast RPF lookup\n"
257 "IP destination prefix (e.g. 10.0.0.0/8)\n"
259 "Nexthop interface name\n"
262 return zebra_static_route(vty
, AFI_IP
, SAFI_MULTICAST
, no
, prefix_str
,
263 NULL
, NULL
, gate_str
, ifname
, NULL
, NULL
,
264 distance_str
, NULL
, NULL
);
267 DEFUN (ip_multicast_mode
,
268 ip_multicast_mode_cmd
,
269 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
271 "Multicast options\n"
272 "RPF lookup behavior\n"
273 "Lookup in unicast RIB only\n"
274 "Lookup in multicast RIB only\n"
275 "Try multicast RIB first, fall back to unicast RIB\n"
276 "Lookup both, use entry with lower distance\n"
277 "Lookup both, use entry with longer prefix\n")
279 char *mode
= argv
[3]->text
;
281 if (strmatch(mode
, "urib-only"))
282 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
283 else if (strmatch(mode
, "mrib-only"))
284 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
285 else if (strmatch(mode
, "mrib-then-urib"))
286 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
287 else if (strmatch(mode
, "lower-distance"))
288 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
289 else if (strmatch(mode
, "longer-prefix"))
290 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
292 vty_out(vty
, "Invalid mode specified\n");
293 return CMD_WARNING_CONFIG_FAILED
;
299 DEFUN (no_ip_multicast_mode
,
300 no_ip_multicast_mode_cmd
,
301 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
304 "Multicast options\n"
305 "RPF lookup behavior\n"
306 "Lookup in unicast RIB only\n"
307 "Lookup in multicast RIB only\n"
308 "Try multicast RIB first, fall back to unicast RIB\n"
309 "Lookup both, use entry with lower distance\n"
310 "Lookup both, use entry with longer prefix\n")
312 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
319 "show ip rpf [json]",
322 "Display RPF information for multicast source\n"
325 int uj
= use_json(argc
, argv
);
326 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
327 false, uj
, 0, NULL
, false, 0, 0);
330 DEFUN (show_ip_rpf_addr
,
331 show_ip_rpf_addr_cmd
,
332 "show ip rpf A.B.C.D",
335 "Display RPF information for multicast source\n"
336 "IP multicast source address (e.g. 10.0.0.0)\n")
340 struct route_node
*rn
;
341 struct route_entry
*re
;
344 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
346 vty_out(vty
, "%% Malformed address\n");
350 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
353 vty_show_ip_route_detail(vty
, rn
, 1);
355 vty_out(vty
, "%% No match for RPF lookup\n");
360 /* Static route configuration. */
361 DEFPY(ip_route_blackhole
,
362 ip_route_blackhole_cmd
,
364 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
365 <reject|blackhole>$flag \
373 "Establish static routes\n"
374 "IP destination prefix (e.g. 10.0.0.0/8)\n"
375 "IP destination prefix\n"
376 "IP destination prefix mask\n"
377 "Emit an ICMP unreachable when matched\n"
378 "Silently discard pkts when matched\n"
379 "Set tag for this route\n"
381 "Distance value for this route\n"
385 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
386 mask_str
, NULL
, NULL
, NULL
, flag
,
387 tag_str
, distance_str
, vrf
, label
);
390 DEFPY(ip_route_address_interface
,
391 ip_route_address_interface_cmd
,
393 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
403 "Establish static routes\n"
404 "IP destination prefix (e.g. 10.0.0.0/8)\n"
405 "IP destination prefix\n"
406 "IP destination prefix mask\n"
407 "IP gateway address\n"
408 "IP gateway interface name. Specify 'Null0' (case-insensitive) for a \
410 "Set tag for this route\n"
412 "Distance value for this route\n"
416 const char *flag
= NULL
;
417 if (ifname
&& !strncasecmp(ifname
, "Null0", 5)) {
421 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
422 mask_str
, NULL
, gate_str
, ifname
, flag
,
423 tag_str
, distance_str
, vrf
, label
);
429 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
430 <A.B.C.D$gate|INTERFACE$ifname> \
438 "Establish static routes\n"
439 "IP destination prefix (e.g. 10.0.0.0/8)\n"
440 "IP destination prefix\n"
441 "IP destination prefix mask\n"
442 "IP gateway address\n"
443 "IP gateway interface name\n"
444 "Set tag for this route\n"
446 "Distance value for this route\n"
450 const char *flag
= NULL
;
451 if (ifname
&& !strncasecmp(ifname
, "Null0", 5)) {
455 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
456 mask_str
, NULL
, gate_str
, ifname
, flag
,
457 tag_str
, distance_str
, vrf
, label
);
460 /* New RIB. Detailed information for IPv4 route. */
461 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
464 struct route_entry
*re
;
465 struct nexthop
*nexthop
;
466 char buf
[SRCDEST2STR_BUFFER
];
467 struct zebra_vrf
*zvrf
;
469 RNODE_FOREACH_RE (rn
, re
) {
470 const char *mcast_info
= "";
472 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
473 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
474 ? " using Multicast RIB"
475 : " using Unicast RIB";
478 vty_out(vty
, "Routing entry for %s%s\n",
479 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
480 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
482 vty_out(vty
, "[%d]", re
->instance
);
484 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
487 vty_out(vty
, ", tag %u", re
->tag
);
488 #if defined(SUPPORT_REALMS)
489 if (re
->tag
> 0 && re
->tag
<= 255)
490 vty_out(vty
, "(realm)");
494 vty_out(vty
, ", mtu %u", re
->mtu
);
495 if (re
->vrf_id
!= VRF_DEFAULT
) {
496 zvrf
= vrf_info_lookup(re
->vrf_id
);
497 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
499 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
500 vty_out(vty
, ", best");
507 uptime
-= re
->uptime
;
508 tm
= gmtime(&uptime
);
510 vty_out(vty
, " Last update ");
512 if (uptime
< ONE_DAY_SECOND
)
513 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
514 tm
->tm_min
, tm
->tm_sec
);
515 else if (uptime
< ONE_WEEK_SECOND
)
516 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
517 tm
->tm_hour
, tm
->tm_min
);
519 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
520 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
522 vty_out(vty
, " ago\n");
524 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
527 vty_out(vty
, " %c%s",
528 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
529 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
532 nexthop
->rparent
? " " : "");
534 switch (nexthop
->type
) {
535 case NEXTHOP_TYPE_IPV4
:
536 case NEXTHOP_TYPE_IPV4_IFINDEX
:
538 inet_ntoa(nexthop
->gate
.ipv4
));
539 if (nexthop
->ifindex
)
540 vty_out(vty
, ", via %s",
541 ifindex2ifname(nexthop
->ifindex
,
544 case NEXTHOP_TYPE_IPV6
:
545 case NEXTHOP_TYPE_IPV6_IFINDEX
:
547 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
549 if (nexthop
->ifindex
)
550 vty_out(vty
, ", via %s",
551 ifindex2ifname(nexthop
->ifindex
,
554 case NEXTHOP_TYPE_IFINDEX
:
555 vty_out(vty
, " directly connected, %s",
556 ifindex2ifname(nexthop
->ifindex
,
559 case NEXTHOP_TYPE_BLACKHOLE
:
560 vty_out(vty
, " unreachable");
561 switch (nexthop
->bh_type
) {
562 case BLACKHOLE_REJECT
:
563 vty_out(vty
, " (ICMP unreachable)");
565 case BLACKHOLE_ADMINPROHIB
:
567 " (ICMP admin-prohibited)");
570 vty_out(vty
, " (blackhole)");
572 case BLACKHOLE_UNSPEC
:
579 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
580 vty_out(vty
, " (duplicate nexthop removed)");
582 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
583 vty_out(vty
, " inactive");
585 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
586 vty_out(vty
, " onlink");
588 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
589 vty_out(vty
, " (recursive)");
591 switch (nexthop
->type
) {
592 case NEXTHOP_TYPE_IPV4
:
593 case NEXTHOP_TYPE_IPV4_IFINDEX
:
594 if (nexthop
->src
.ipv4
.s_addr
) {
595 if (inet_ntop(AF_INET
,
597 addrstr
, sizeof addrstr
))
598 vty_out(vty
, ", src %s",
602 case NEXTHOP_TYPE_IPV6
:
603 case NEXTHOP_TYPE_IPV6_IFINDEX
:
604 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
606 if (inet_ntop(AF_INET6
,
608 addrstr
, sizeof addrstr
))
609 vty_out(vty
, ", src %s",
618 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
620 /* Label information */
621 if (nexthop
->nh_label
622 && nexthop
->nh_label
->num_labels
) {
623 vty_out(vty
, ", label %s",
625 nexthop
->nh_label
->num_labels
,
626 nexthop
->nh_label
->label
, buf
,
636 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
637 struct route_entry
*re
, json_object
*json
)
639 struct nexthop
*nexthop
;
641 char buf
[SRCDEST2STR_BUFFER
];
642 json_object
*json_nexthops
= NULL
;
643 json_object
*json_nexthop
= NULL
;
644 json_object
*json_route
= NULL
;
645 json_object
*json_labels
= NULL
;
650 uptime
-= re
->uptime
;
651 tm
= gmtime(&uptime
);
654 json_route
= json_object_new_object();
655 json_nexthops
= json_object_new_array();
657 json_object_string_add(json_route
, "prefix",
658 srcdest_rnode2str(rn
, buf
, sizeof buf
));
659 json_object_string_add(json_route
, "protocol",
660 zebra_route_string(re
->type
));
663 json_object_int_add(json_route
, "instance",
667 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
669 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
670 json_object_boolean_true_add(json_route
, "selected");
672 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
673 json_object_int_add(json_route
, "distance",
675 json_object_int_add(json_route
, "metric", re
->metric
);
678 if (uptime
< ONE_DAY_SECOND
)
679 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
680 tm
->tm_min
, tm
->tm_sec
);
681 else if (uptime
< ONE_WEEK_SECOND
)
682 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
683 tm
->tm_hour
, tm
->tm_min
);
685 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
686 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
689 json_object_string_add(json_route
, "uptime", buf
);
691 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
692 json_nexthop
= json_object_new_object();
694 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
695 json_object_boolean_true_add(json_nexthop
,
698 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
699 json_object_boolean_true_add(json_nexthop
,
702 switch (nexthop
->type
) {
703 case NEXTHOP_TYPE_IPV4
:
704 case NEXTHOP_TYPE_IPV4_IFINDEX
:
705 json_object_string_add(
707 inet_ntoa(nexthop
->gate
.ipv4
));
708 json_object_string_add(json_nexthop
, "afi",
711 if (nexthop
->ifindex
) {
712 json_object_int_add(json_nexthop
,
715 json_object_string_add(
716 json_nexthop
, "interfaceName",
717 ifindex2ifname(nexthop
->ifindex
,
721 case NEXTHOP_TYPE_IPV6
:
722 case NEXTHOP_TYPE_IPV6_IFINDEX
:
723 json_object_string_add(
725 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
727 json_object_string_add(json_nexthop
, "afi",
730 if (nexthop
->ifindex
) {
731 json_object_int_add(json_nexthop
,
734 json_object_string_add(
735 json_nexthop
, "interfaceName",
736 ifindex2ifname(nexthop
->ifindex
,
741 case NEXTHOP_TYPE_IFINDEX
:
742 json_object_boolean_true_add(
743 json_nexthop
, "directlyConnected");
744 json_object_int_add(json_nexthop
,
747 json_object_string_add(
748 json_nexthop
, "interfaceName",
749 ifindex2ifname(nexthop
->ifindex
,
752 case NEXTHOP_TYPE_BLACKHOLE
:
753 json_object_boolean_true_add(json_nexthop
,
755 switch (nexthop
->bh_type
) {
756 case BLACKHOLE_REJECT
:
757 json_object_boolean_true_add(
758 json_nexthop
, "reject");
760 case BLACKHOLE_ADMINPROHIB
:
761 json_object_boolean_true_add(
766 json_object_boolean_true_add(
767 json_nexthop
, "blackhole");
769 case BLACKHOLE_UNSPEC
:
777 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
778 json_object_boolean_true_add(json_nexthop
,
781 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
782 json_object_boolean_true_add(json_nexthop
,
785 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
786 json_object_boolean_true_add(json_nexthop
,
789 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
790 json_object_boolean_true_add(json_nexthop
,
793 switch (nexthop
->type
) {
794 case NEXTHOP_TYPE_IPV4
:
795 case NEXTHOP_TYPE_IPV4_IFINDEX
:
796 if (nexthop
->src
.ipv4
.s_addr
) {
797 if (inet_ntop(AF_INET
,
798 &nexthop
->src
.ipv4
, buf
,
800 json_object_string_add(
801 json_nexthop
, "source",
805 case NEXTHOP_TYPE_IPV6
:
806 case NEXTHOP_TYPE_IPV6_IFINDEX
:
807 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
809 if (inet_ntop(AF_INET6
,
810 &nexthop
->src
.ipv6
, buf
,
812 json_object_string_add(
813 json_nexthop
, "source",
821 if (nexthop
->nh_label
822 && nexthop
->nh_label
->num_labels
) {
823 json_labels
= json_object_new_array();
825 for (int label_index
= 0;
827 < nexthop
->nh_label
->num_labels
;
829 json_object_array_add(
832 nexthop
->nh_label
->label
835 json_object_object_add(json_nexthop
, "labels",
839 json_object_array_add(json_nexthops
, json_nexthop
);
842 json_object_object_add(json_route
, "nexthops", json_nexthops
);
843 json_object_array_add(json
, json_route
);
847 /* Nexthop information. */
848 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
849 if (nexthop
== re
->nexthop
) {
850 /* Prefix information. */
851 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
853 len
+= vty_out(vty
, "[%d]", re
->instance
);
856 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
859 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
862 srcdest_rnode2str(rn
, buf
, sizeof buf
));
864 /* Distance and metric display. */
865 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
866 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
869 vty_out(vty
, " %c%*c",
870 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
871 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
874 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
877 switch (nexthop
->type
) {
878 case NEXTHOP_TYPE_IPV4
:
879 case NEXTHOP_TYPE_IPV4_IFINDEX
:
880 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
881 if (nexthop
->ifindex
)
883 ifindex2ifname(nexthop
->ifindex
,
886 case NEXTHOP_TYPE_IPV6
:
887 case NEXTHOP_TYPE_IPV6_IFINDEX
:
888 vty_out(vty
, " via %s",
889 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
891 if (nexthop
->ifindex
)
893 ifindex2ifname(nexthop
->ifindex
,
897 case NEXTHOP_TYPE_IFINDEX
:
898 vty_out(vty
, " is directly connected, %s",
899 ifindex2ifname(nexthop
->ifindex
, re
->vrf_id
));
901 case NEXTHOP_TYPE_BLACKHOLE
:
902 vty_out(vty
, " unreachable");
903 switch (nexthop
->bh_type
) {
904 case BLACKHOLE_REJECT
:
905 vty_out(vty
, " (ICMP unreachable)");
907 case BLACKHOLE_ADMINPROHIB
:
908 vty_out(vty
, " (ICMP admin-prohibited)");
911 vty_out(vty
, " (blackhole)");
913 case BLACKHOLE_UNSPEC
:
920 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
921 vty_out(vty
, " inactive");
923 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
924 vty_out(vty
, " onlink");
926 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
927 vty_out(vty
, " (recursive)");
929 switch (nexthop
->type
) {
930 case NEXTHOP_TYPE_IPV4
:
931 case NEXTHOP_TYPE_IPV4_IFINDEX
:
932 if (nexthop
->src
.ipv4
.s_addr
) {
933 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
935 vty_out(vty
, ", src %s", buf
);
938 case NEXTHOP_TYPE_IPV6
:
939 case NEXTHOP_TYPE_IPV6_IFINDEX
:
940 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
941 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
943 vty_out(vty
, ", src %s", buf
);
950 /* Label information */
951 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
952 vty_out(vty
, ", label %s",
953 mpls_label2str(nexthop
->nh_label
->num_labels
,
954 nexthop
->nh_label
->label
, buf
,
958 if (uptime
< ONE_DAY_SECOND
)
959 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
960 tm
->tm_min
, tm
->tm_sec
);
961 else if (uptime
< ONE_WEEK_SECOND
)
962 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
963 tm
->tm_hour
, tm
->tm_min
);
965 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
966 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
972 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
973 safi_t safi
, bool use_fib
, u_char use_json
,
975 const struct prefix
*longer_prefix_p
,
976 bool supernets_only
, int type
,
977 u_short ospf_instance_id
)
979 struct route_table
*table
;
981 struct route_node
*rn
;
982 struct route_entry
*re
;
984 struct zebra_vrf
*zvrf
= NULL
;
986 json_object
*json
= NULL
;
987 json_object
*json_prefix
= NULL
;
990 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
992 vty_out(vty
, "{}\n");
994 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
998 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
1000 vty_out(vty
, "{}\n");
1002 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
1006 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
1009 vty_out(vty
, "{}\n");
1014 json
= json_object_new_object();
1016 /* Show all routes. */
1017 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
1018 dest
= rib_dest_from_rnode(rn
);
1020 RNODE_FOREACH_RE (rn
, re
) {
1022 && re
!= dest
->selected_fib
)
1025 if (tag
&& re
->tag
!= tag
)
1029 && !prefix_match(longer_prefix_p
, &rn
->p
))
1032 /* This can only be true when the afi is IPv4 */
1033 if (supernets_only
) {
1034 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1036 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1039 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1042 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1046 if (type
&& re
->type
!= type
)
1049 if (ospf_instance_id
1050 && (re
->type
!= ZEBRA_ROUTE_OSPF
1051 || re
->instance
!= ospf_instance_id
))
1056 json_prefix
= json_object_new_array();
1061 SHOW_ROUTE_V4_HEADER
);
1064 SHOW_ROUTE_V6_HEADER
);
1066 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
1067 vty_out(vty
, "\nVRF %s:\n",
1074 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
1078 prefix2str(&rn
->p
, buf
, sizeof buf
);
1079 json_object_object_add(json
, buf
, json_prefix
);
1085 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1086 json
, JSON_C_TO_STRING_PRETTY
));
1087 json_object_free(json
);
1095 "show ip nht [vrf NAME]",
1098 "IP nexthop tracking table\n"
1102 vrf_id_t vrf_id
= VRF_DEFAULT
;
1105 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1107 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1112 DEFUN (show_ip_nht_vrf_all
,
1113 show_ip_nht_vrf_all_cmd
,
1114 "show ip nht vrf all",
1117 "IP nexthop tracking table\n"
1118 VRF_ALL_CMD_HELP_STR
)
1121 struct zebra_vrf
*zvrf
;
1123 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1124 if ((zvrf
= vrf
->info
) != NULL
) {
1125 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1126 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1133 DEFUN (show_ipv6_nht
,
1135 "show ipv6 nht [vrf NAME]",
1138 "IPv6 nexthop tracking table\n"
1142 vrf_id_t vrf_id
= VRF_DEFAULT
;
1145 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1147 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1152 DEFUN (show_ipv6_nht_vrf_all
,
1153 show_ipv6_nht_vrf_all_cmd
,
1154 "show ipv6 nht vrf all",
1157 "IPv6 nexthop tracking table\n"
1158 VRF_ALL_CMD_HELP_STR
)
1161 struct zebra_vrf
*zvrf
;
1163 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1164 if ((zvrf
= vrf
->info
) != NULL
) {
1165 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1166 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1173 DEFUN (ip_nht_default_route
,
1174 ip_nht_default_route_cmd
,
1175 "ip nht resolve-via-default",
1177 "Filter Next Hop tracking route resolution\n"
1178 "Resolve via default route\n")
1180 if (zebra_rnh_ip_default_route
)
1183 zebra_rnh_ip_default_route
= 1;
1184 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1188 DEFUN (no_ip_nht_default_route
,
1189 no_ip_nht_default_route_cmd
,
1190 "no ip nht resolve-via-default",
1193 "Filter Next Hop tracking route resolution\n"
1194 "Resolve via default route\n")
1196 if (!zebra_rnh_ip_default_route
)
1199 zebra_rnh_ip_default_route
= 0;
1200 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1204 DEFUN (ipv6_nht_default_route
,
1205 ipv6_nht_default_route_cmd
,
1206 "ipv6 nht resolve-via-default",
1208 "Filter Next Hop tracking route resolution\n"
1209 "Resolve via default route\n")
1211 if (zebra_rnh_ipv6_default_route
)
1214 zebra_rnh_ipv6_default_route
= 1;
1215 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1219 DEFUN (no_ipv6_nht_default_route
,
1220 no_ipv6_nht_default_route_cmd
,
1221 "no ipv6 nht resolve-via-default",
1224 "Filter Next Hop tracking route resolution\n"
1225 "Resolve via default route\n")
1227 if (!zebra_rnh_ipv6_default_route
)
1230 zebra_rnh_ipv6_default_route
= 0;
1231 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1239 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1242 |A.B.C.D/M$prefix longer-prefixes\
1243 |supernets-only$supernets_only\
1246 " FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1247 |ospf$type_str (1-65535)$ospf_instance_id\
1249 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1252 |X:X::X:X/M$prefix longer-prefixes\
1254 [" FRR_IP6_REDIST_STR_ZEBRA
"$type_str]\
1259 "IP forwarding table\n"
1260 "IP routing table\n"
1261 VRF_FULL_CMD_HELP_STR
1262 "Show only routes with tag\n"
1264 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1265 "Show route matching the specified Network/Mask pair only\n"
1266 "Show supernet entries only\n"
1267 FRR_IP_REDIST_HELP_STR_ZEBRA
1268 "Open Shortest Path First (OSPFv2)\n"
1271 "IP forwarding table\n"
1272 "IP routing table\n"
1273 VRF_FULL_CMD_HELP_STR
1274 "Show only routes with tag\n"
1277 "Show route matching the specified Network/Mask pair only\n"
1278 FRR_IP6_REDIST_HELP_STR_ZEBRA
1281 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1286 type
= proto_redistnum(afi
, type_str
);
1288 vty_out(vty
, "Unknown route type\n");
1294 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1295 struct zebra_vrf
*zvrf
;
1296 struct route_table
*table
;
1298 if ((zvrf
= vrf
->info
) == NULL
1299 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1303 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1304 !!json
, tag
, prefix_str
? prefix
: NULL
,
1305 !!supernets_only
, type
, ospf_instance_id
);
1308 vrf_id_t vrf_id
= VRF_DEFAULT
;
1311 VRF_GET_ID(vrf_id
, vrf_name
);
1312 vrf
= vrf_lookup_by_id(vrf_id
);
1313 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1314 !!json
, tag
, prefix_str
? prefix
: NULL
,
1315 !!supernets_only
, type
, ospf_instance_id
);
1321 DEFPY (show_route_detail
,
1322 show_route_detail_cmd
,
1325 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1330 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1338 "IP routing table\n"
1339 VRF_FULL_CMD_HELP_STR
1340 "Network in the IP routing table to display\n"
1341 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1343 "IP routing table\n"
1344 VRF_FULL_CMD_HELP_STR
1348 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1349 struct route_table
*table
;
1351 struct route_node
*rn
;
1354 prefix_str
= address_str
;
1355 if (str2prefix(prefix_str
, &p
) < 0) {
1356 vty_out(vty
, "%% Malformed address\n");
1362 struct zebra_vrf
*zvrf
;
1364 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
1365 if ((zvrf
= vrf
->info
) == NULL
1366 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1369 rn
= route_node_match(table
, &p
);
1372 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1373 route_unlock_node(rn
);
1377 vty_show_ip_route_detail(vty
, rn
, 0);
1379 route_unlock_node(rn
);
1382 vrf_id_t vrf_id
= VRF_DEFAULT
;
1385 VRF_GET_ID(vrf_id
, vrf_name
);
1387 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1391 rn
= route_node_match(table
, &p
);
1393 vty_out(vty
, "%% Network not in table\n");
1396 if (!address_str
&& rn
->p
.prefixlen
!= p
.prefixlen
) {
1397 vty_out(vty
, "%% Network not in table\n");
1398 route_unlock_node(rn
);
1402 vty_show_ip_route_detail(vty
, rn
, 0);
1404 route_unlock_node(rn
);
1410 DEFPY (show_route_summary
,
1411 show_route_summary_cmd
,
1414 ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
1415 summary [prefix$prefix]\
1416 |ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
1417 summary [prefix$prefix]\
1421 "IP routing table\n"
1422 VRF_FULL_CMD_HELP_STR
1423 "Summary of all routes\n"
1426 "IP routing table\n"
1427 VRF_FULL_CMD_HELP_STR
1428 "Summary of all routes\n"
1431 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1432 struct route_table
*table
;
1436 struct zebra_vrf
*zvrf
;
1438 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
1439 if ((zvrf
= vrf
->info
) == NULL
1440 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1444 vty_show_ip_route_summary_prefix(vty
, table
);
1446 vty_show_ip_route_summary(vty
, table
);
1449 vrf_id_t vrf_id
= VRF_DEFAULT
;
1452 VRF_GET_ID(vrf_id
, vrf_name
);
1454 table
= zebra_vrf_table(afi
, SAFI_UNICAST
, vrf_id
);
1459 vty_show_ip_route_summary_prefix(vty
, table
);
1461 vty_show_ip_route_summary(vty
, table
);
1467 static void vty_show_ip_route_summary(struct vty
*vty
,
1468 struct route_table
*table
)
1470 struct route_node
*rn
;
1471 struct route_entry
*re
;
1472 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1473 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1474 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1475 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1479 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1480 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1481 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1482 RNODE_FOREACH_RE (rn
, re
) {
1483 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1484 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1486 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1488 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1490 rib_cnt
[re
->type
]++;
1492 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1493 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1496 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1498 fib_cnt
[re
->type
]++;
1502 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1503 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1505 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1506 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1507 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1508 if (i
== ZEBRA_ROUTE_BGP
) {
1509 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1510 rib_cnt
[ZEBRA_ROUTE_BGP
],
1511 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1512 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1513 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1514 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1516 vty_out(vty
, "%-20s %-20d %-20d \n",
1517 zebra_route_string(i
), rib_cnt
[i
],
1522 vty_out(vty
, "------\n");
1523 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1524 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1529 * Implementation of the ip route summary prefix command.
1531 * This command prints the primary prefixes that have been installed by various
1532 * protocols on the box.
1535 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1536 struct route_table
*table
)
1538 struct route_node
*rn
;
1539 struct route_entry
*re
;
1540 struct nexthop
*nexthop
;
1541 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1542 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1543 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1544 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1548 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1549 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1550 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1551 RNODE_FOREACH_RE (rn
, re
) {
1554 * In case of ECMP, count only once.
1557 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1558 nexthop
= nexthop
->next
) {
1560 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1561 rib_cnt
[re
->type
]++;
1562 if (CHECK_FLAG(nexthop
->flags
,
1563 NEXTHOP_FLAG_FIB
)) {
1564 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1565 fib_cnt
[re
->type
]++;
1567 if (re
->type
== ZEBRA_ROUTE_BGP
1568 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1569 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1570 if (CHECK_FLAG(nexthop
->flags
,
1572 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1577 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1578 "Prefix Routes", "FIB",
1579 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1581 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1582 if (rib_cnt
[i
] > 0) {
1583 if (i
== ZEBRA_ROUTE_BGP
) {
1584 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1585 rib_cnt
[ZEBRA_ROUTE_BGP
]
1586 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1587 fib_cnt
[ZEBRA_ROUTE_BGP
]
1588 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1589 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1590 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1591 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1593 vty_out(vty
, "%-20s %-20d %-20d \n",
1594 zebra_route_string(i
), rib_cnt
[i
],
1599 vty_out(vty
, "------\n");
1600 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1601 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1605 /* Write static route configuration. */
1606 static int static_config(struct vty
*vty
, afi_t afi
, safi_t safi
,
1609 struct route_node
*rn
;
1610 struct static_route
*si
;
1611 struct route_table
*stable
;
1613 struct zebra_vrf
*zvrf
;
1614 char buf
[SRCDEST2STR_BUFFER
];
1617 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1618 if (!(zvrf
= vrf
->info
))
1620 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1623 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1624 for (si
= rn
->info
; si
; si
= si
->next
) {
1625 vty_out(vty
, "%s %s", cmd
,
1626 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1629 case STATIC_IPV4_GATEWAY
:
1631 inet_ntoa(si
->addr
.ipv4
));
1633 case STATIC_IPV6_GATEWAY
:
1636 &si
->addr
.ipv6
, buf
,
1640 vty_out(vty
, " %s", si
->ifname
);
1642 case STATIC_BLACKHOLE
:
1643 switch (si
->bh_type
) {
1644 case STATIC_BLACKHOLE_DROP
:
1645 vty_out(vty
, " blackhole");
1647 case STATIC_BLACKHOLE_NULL
:
1648 vty_out(vty
, " Null0");
1650 case STATIC_BLACKHOLE_REJECT
:
1651 vty_out(vty
, " reject");
1655 case STATIC_IPV4_GATEWAY_IFNAME
:
1656 vty_out(vty
, " %s %s",
1658 &si
->addr
.ipv4
, buf
,
1662 case STATIC_IPV6_GATEWAY_IFNAME
:
1663 vty_out(vty
, " %s %s",
1665 &si
->addr
.ipv6
, buf
,
1672 vty_out(vty
, " tag %" ROUTE_TAG_PRI
,
1676 != ZEBRA_STATIC_DISTANCE_DEFAULT
)
1677 vty_out(vty
, " %d", si
->distance
);
1679 if (si
->vrf_id
!= VRF_DEFAULT
)
1680 vty_out(vty
, " vrf %s",
1683 /* Label information */
1684 if (si
->snh_label
.num_labels
)
1685 vty_out(vty
, " label %s",
1689 si
->snh_label
.label
,
1690 buf
, sizeof buf
, 0));
1700 DEFPY(ipv6_route_blackhole
,
1701 ipv6_route_blackhole_cmd
,
1702 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1703 <Null0|reject|blackhole>$flag \
1705 tag (1-4294967295) \
1712 "Establish static routes\n"
1713 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1714 "IPv6 source-dest route\n"
1715 "IPv6 source prefix\n"
1717 "Emit an ICMP unreachable when matched\n"
1718 "Silently discard pkts when matched\n"
1719 "Set tag for this route\n"
1721 "Distance value for this prefix\n"
1725 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1726 NULL
, from_str
, NULL
, NULL
, flag
,
1727 tag_str
, distance_str
, vrf
, label
);
1730 DEFPY(ipv6_route_address_interface
,
1731 ipv6_route_address_interface_cmd
,
1732 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1736 tag (1-4294967295) \
1743 "Establish static routes\n"
1744 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1745 "IPv6 source-dest route\n"
1746 "IPv6 source prefix\n"
1747 "IPv6 gateway address\n"
1748 "IPv6 gateway interface name\n"
1749 "Set tag for this route\n"
1751 "Distance value for this prefix\n"
1755 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1756 NULL
, from_str
, gate_str
, ifname
, NULL
,
1757 tag_str
, distance_str
, vrf
, label
);
1762 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1763 <X:X::X:X$gate|INTERFACE$ifname> \
1765 tag (1-4294967295) \
1772 "Establish static routes\n"
1773 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1774 "IPv6 source-dest route\n"
1775 "IPv6 source prefix\n"
1776 "IPv6 gateway address\n"
1777 "IPv6 gateway interface name\n"
1778 "Set tag for this route\n"
1780 "Distance value for this prefix\n"
1784 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1785 NULL
, from_str
, gate_str
, ifname
, NULL
,
1786 tag_str
, distance_str
, vrf
, label
);
1790 * Show IPv6 mroute command.Used to dump
1791 * the Multicast routing table.
1793 DEFUN (show_ipv6_mroute
,
1794 show_ipv6_mroute_cmd
,
1795 "show ipv6 mroute [vrf NAME]",
1798 "IPv6 Multicast routing table\n"
1801 struct route_table
*table
;
1802 struct route_node
*rn
;
1803 struct route_entry
*re
;
1805 vrf_id_t vrf_id
= VRF_DEFAULT
;
1808 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1810 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
1814 /* Show all IPv6 route. */
1815 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1816 RNODE_FOREACH_RE (rn
, re
) {
1818 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1821 vty_show_ip_route(vty
, rn
, re
, NULL
);
1826 DEFUN (show_ipv6_mroute_vrf_all
,
1827 show_ipv6_mroute_vrf_all_cmd
,
1828 "show ipv6 mroute vrf all",
1831 "IPv6 Multicast routing table\n"
1832 VRF_ALL_CMD_HELP_STR
)
1834 struct route_table
*table
;
1835 struct route_node
*rn
;
1836 struct route_entry
*re
;
1838 struct zebra_vrf
*zvrf
;
1841 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1842 if ((zvrf
= vrf
->info
) == NULL
1843 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
1846 /* Show all IPv6 route. */
1847 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1848 RNODE_FOREACH_RE (rn
, re
) {
1850 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
1853 vty_show_ip_route(vty
, rn
, re
, NULL
);
1859 DEFUN (allow_external_route_update
,
1860 allow_external_route_update_cmd
,
1861 "allow-external-route-update",
1862 "Allow FRR routes to be overwritten by external processes\n")
1869 DEFUN (no_allow_external_route_update
,
1870 no_allow_external_route_update_cmd
,
1871 "no allow-external-route-update",
1873 "Allow FRR routes to be overwritten by external processes\n")
1888 struct zebra_vrf
*zvrf
;
1890 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1891 if (!(zvrf
= vrf
->info
))
1896 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
1897 if (zvrf_id(zvrf
) == VRF_UNKNOWN
)
1898 vty_out(vty
, "inactive");
1900 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
1908 DEFUN (vrf_vni_mapping
,
1909 vrf_vni_mapping_cmd
,
1910 "vni " CMD_VNI_RANGE
,
1916 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1917 vni_t vni
= strtoul(argv
[1]->arg
, NULL
, 10);
1918 char err
[ERR_STR_SZ
];
1923 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 1);
1925 vty_out(vty
, "%s\n", err
);
1932 DEFUN (no_vrf_vni_mapping
,
1933 no_vrf_vni_mapping_cmd
,
1934 "no vni " CMD_VNI_RANGE
,
1940 char err
[ERR_STR_SZ
];
1941 vni_t vni
= strtoul(argv
[2]->arg
, NULL
, 10);
1943 ZEBRA_DECLVAR_CONTEXT(vrf
, zvrf
);
1948 ret
= zebra_vxlan_process_vrf_vni_cmd(zvrf
, vni
, err
, ERR_STR_SZ
, 0);
1950 vty_out(vty
, "%s\n", err
);
1958 DEFUN (show_vrf_vni
,
1960 "show vrf vni [json]",
1967 struct zebra_vrf
*zvrf
;
1968 json_object
*json
= NULL
;
1969 json_object
*json_vrfs
= NULL
;
1970 u_char uj
= use_json(argc
, argv
);
1973 json
= json_object_new_object();
1974 json_vrfs
= json_object_new_array();
1977 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
1986 vty_out(vty
, "vrf: %s VNI: %u",
1991 json_object
*json_vrf
= NULL
;
1993 json_vrf
= json_object_new_object();
1994 json_object_string_add(json_vrf
, "vrf",
1996 json_object_int_add(json_vrf
, "l3vni",
1998 json_object_array_add(json_vrfs
, json_vrf
);
2003 json_object_object_add(json
, "vrfs", json_vrfs
);
2004 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
2005 json
, JSON_C_TO_STRING_PRETTY
));
2006 json_object_free(json
);
2012 DEFUN (show_evpn_vni
,
2014 "show evpn vni [json]",
2017 "VxLAN information\n"
2020 struct zebra_vrf
*zvrf
;
2021 u_char uj
= use_json(argc
, argv
);
2023 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2024 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2028 DEFUN (show_evpn_vni_vni
,
2029 show_evpn_vni_vni_cmd
,
2030 "show evpn vni " CMD_VNI_RANGE
"[json]",
2033 "VxLAN Network Identifier\n"
2037 struct zebra_vrf
*zvrf
;
2039 u_char uj
= use_json(argc
, argv
);
2041 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2042 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2043 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2047 DEFUN (show_evpn_l3vni
,
2048 show_evpn_l3vni_cmd
,
2049 "show evpn l3vni [json]",
2055 u_char uj
= use_json(argc
, argv
);
2057 zebra_vxlan_print_l3vnis(vty
, uj
);
2061 DEFUN (show_evpn_l3vni_vni
,
2062 show_evpn_l3vni_vni_cmd
,
2063 "show evpn l3vni " CMD_VNI_RANGE
"[json]",
2066 "L3 VxLAN Network Identifier\n"
2071 u_char uj
= use_json(argc
, argv
);
2073 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2074 zebra_vxlan_print_l3vni(vty
, vni
, uj
);
2078 DEFUN (show_evpn_rmac_l3vni_mac
,
2079 show_evpn_rmac_l3vni_mac_cmd
,
2080 "show evpn rmac l3vni " CMD_VNI_RANGE
" mac WORD [json]",
2087 "mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
2092 u_char uj
= use_json(argc
, argv
);
2094 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2095 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2096 vty_out(vty
, "%% Malformed MAC address\n");
2099 zebra_vxlan_print_specific_rmac_l3vni(vty
, l3vni
, &mac
, uj
);
2103 DEFUN (show_evpn_rmac_l3vni
,
2104 show_evpn_rmac_l3vni_cmd
,
2105 "show evpn rmac l3vni " CMD_VNI_RANGE
"[json]",
2114 u_char uj
= use_json(argc
, argv
);
2116 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2117 zebra_vxlan_print_rmacs_l3vni(vty
, l3vni
, uj
);
2122 DEFUN (show_evpn_rmac_l3vni_all
,
2123 show_evpn_rmac_l3vni_all_cmd
,
2124 "show evpn rmac l3vni all [json]",
2132 u_char uj
= use_json(argc
, argv
);
2134 zebra_vxlan_print_rmacs_all_l3vni(vty
, uj
);
2139 DEFUN (show_evpn_nh_l3vni_ip
,
2140 show_evpn_nh_l3vni_ip_cmd
,
2141 "show evpn next-hops l3vni " CMD_VNI_RANGE
" ip WORD [json]",
2148 "Host address (ipv4 or ipv6)\n"
2153 u_char uj
= use_json(argc
, argv
);
2155 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2156 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2158 vty_out(vty
, "%% Malformed Neighbor address\n");
2161 zebra_vxlan_print_specific_nh_l3vni(vty
, l3vni
, &ip
, uj
);
2166 DEFUN (show_evpn_nh_l3vni
,
2167 show_evpn_nh_l3vni_cmd
,
2168 "show evpn next-hops l3vni " CMD_VNI_RANGE
"[json]",
2177 u_char uj
= use_json(argc
, argv
);
2179 l3vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2180 zebra_vxlan_print_nh_l3vni(vty
, l3vni
, uj
);
2185 DEFUN (show_evpn_nh_l3vni_all
,
2186 show_evpn_nh_l3vni_all_cmd
,
2187 "show evpn next-hops l3vni all [json]",
2195 u_char uj
= use_json(argc
, argv
);
2197 zebra_vxlan_print_nh_all_l3vni(vty
, uj
);
2202 DEFUN (show_evpn_mac_vni
,
2203 show_evpn_mac_vni_cmd
,
2204 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2208 "VxLAN Network Identifier\n"
2212 struct zebra_vrf
*zvrf
;
2214 u_char uj
= use_json(argc
, argv
);
2216 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2217 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2218 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2222 DEFUN (show_evpn_mac_vni_all
,
2223 show_evpn_mac_vni_all_cmd
,
2224 "show evpn mac vni all [json]",
2228 "VxLAN Network Identifier\n"
2232 struct zebra_vrf
*zvrf
;
2233 u_char uj
= use_json(argc
, argv
);
2235 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2236 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
2240 DEFUN (show_evpn_mac_vni_all_vtep
,
2241 show_evpn_mac_vni_all_vtep_cmd
,
2242 "show evpn mac vni all vtep A.B.C.D [json]",
2246 "VxLAN Network Identifier\n"
2249 "Remote VTEP IP address\n"
2252 struct zebra_vrf
*zvrf
;
2253 struct in_addr vtep_ip
;
2254 u_char uj
= use_json(argc
, argv
);
2256 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2258 vty_out(vty
, "%% Malformed VTEP IP address\n");
2261 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2262 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2268 DEFUN (show_evpn_mac_vni_mac
,
2269 show_evpn_mac_vni_mac_cmd
,
2270 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2274 "VxLAN Network Identifier\n"
2277 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2279 struct zebra_vrf
*zvrf
;
2283 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2284 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2285 vty_out(vty
, "%% Malformed MAC address");
2288 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2289 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2293 DEFUN (show_evpn_mac_vni_vtep
,
2294 show_evpn_mac_vni_vtep_cmd
,
2295 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2299 "VxLAN Network Identifier\n"
2302 "Remote VTEP IP address\n"
2305 struct zebra_vrf
*zvrf
;
2307 struct in_addr vtep_ip
;
2308 u_char uj
= use_json(argc
, argv
);
2310 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2311 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2313 vty_out(vty
, "%% Malformed VTEP IP address\n");
2317 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2318 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2322 DEFUN (show_evpn_neigh_vni
,
2323 show_evpn_neigh_vni_cmd
,
2324 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2327 "ARP and ND cache\n"
2328 "VxLAN Network Identifier\n"
2332 struct zebra_vrf
*zvrf
;
2334 u_char uj
= use_json(argc
, argv
);
2336 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2337 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2338 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2342 DEFUN (show_evpn_neigh_vni_all
,
2343 show_evpn_neigh_vni_all_cmd
,
2344 "show evpn arp-cache vni all [json]",
2347 "ARP and ND cache\n"
2348 "VxLAN Network Identifier\n"
2352 struct zebra_vrf
*zvrf
;
2353 u_char uj
= use_json(argc
, argv
);
2355 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2356 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2360 DEFUN (show_evpn_neigh_vni_neigh
,
2361 show_evpn_neigh_vni_neigh_cmd
,
2362 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2365 "ARP and ND cache\n"
2366 "VxLAN Network Identifier\n"
2369 "Neighbor address (IPv4 or IPv6 address)\n"
2372 struct zebra_vrf
*zvrf
;
2375 u_char uj
= use_json(argc
, argv
);
2377 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2378 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2380 vty_out(vty
, "%% Malformed Neighbor address\n");
2383 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2384 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2388 DEFUN (show_evpn_neigh_vni_vtep
,
2389 show_evpn_neigh_vni_vtep_cmd
,
2390 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2393 "ARP and ND cache\n"
2394 "VxLAN Network Identifier\n"
2397 "Remote VTEP IP address\n"
2400 struct zebra_vrf
*zvrf
;
2402 struct in_addr vtep_ip
;
2403 u_char uj
= use_json(argc
, argv
);
2405 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2406 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2408 vty_out(vty
, "%% Malformed VTEP IP address\n");
2412 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2413 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2417 /* Static ip route configuration write function. */
2418 static int zebra_ip_config(struct vty
*vty
)
2422 write
+= static_config(vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
2423 write
+= static_config(vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
2424 write
+= static_config(vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
2426 write
+= zebra_import_table_config(vty
);
2430 DEFUN (ip_zebra_import_table_distance
,
2431 ip_zebra_import_table_distance_cmd
,
2432 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2434 "import routes from non-main kernel table\n"
2435 "kernel routing table id\n"
2436 "Distance for imported routes\n"
2437 "Default distance value\n"
2438 "route-map for filtering\n"
2441 u_int32_t table_id
= 0;
2443 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2444 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2446 strmatch(argv
[argc
- 2]->text
, "route-map")
2447 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2451 if (argc
== 7 || (argc
== 5 && !rmap
))
2452 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2454 if (!is_zebra_valid_kernel_table(table_id
)) {
2456 "Invalid routing table ID, %d. Must be in range 1-252\n",
2459 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2463 if (is_zebra_main_routing_table(table_id
)) {
2465 "Invalid routing table ID, %d. Must be non-default table\n",
2468 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2472 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2474 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2479 DEFUN_HIDDEN (zebra_packet_process
,
2480 zebra_packet_process_cmd
,
2481 "zebra zapi-packets (1-10000)",
2484 "Number of packets to process before relinquishing thread\n")
2486 uint32_t packets
= strtoul(argv
[2]->arg
, NULL
, 10);
2488 zebrad
.packets_to_process
= packets
;
2493 DEFUN_HIDDEN (no_zebra_packet_process
,
2494 no_zebra_packet_process_cmd
,
2495 "no zebra zapi-packets [(1-10000)]",
2499 "Number of packets to process before relinquishing thread\n")
2501 zebrad
.packets_to_process
= ZEBRA_ZAPI_PACKETS_TO_PROCESS
;
2506 DEFUN_HIDDEN (zebra_workqueue_timer
,
2507 zebra_workqueue_timer_cmd
,
2508 "zebra work-queue (0-10000)",
2511 "Time in milliseconds\n")
2513 uint32_t timer
= strtoul(argv
[2]->arg
, NULL
, 10);
2514 zebrad
.ribq
->spec
.hold
= timer
;
2519 DEFUN_HIDDEN (no_zebra_workqueue_timer
,
2520 no_zebra_workqueue_timer_cmd
,
2521 "no zebra work-queue [(0-10000)]",
2525 "Time in milliseconds\n")
2527 zebrad
.ribq
->spec
.hold
= ZEBRA_RIB_PROCESS_HOLD_TIME
;
2532 DEFUN (no_ip_zebra_import_table
,
2533 no_ip_zebra_import_table_cmd
,
2534 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2537 "import routes from non-main kernel table\n"
2538 "kernel routing table id\n"
2539 "Distance for imported routes\n"
2540 "Default distance value\n"
2541 "route-map for filtering\n"
2544 u_int32_t table_id
= 0;
2545 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2547 if (!is_zebra_valid_kernel_table(table_id
)) {
2549 "Invalid routing table ID. Must be in range 1-252\n");
2553 if (is_zebra_main_routing_table(table_id
)) {
2555 "Invalid routing table ID, %d. Must be non-default table\n",
2560 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2563 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2566 static int config_write_protocol(struct vty
*vty
)
2569 vty_out(vty
, "allow-external-route-update\n");
2571 if (zebra_rnh_ip_default_route
)
2572 vty_out(vty
, "ip nht resolve-via-default\n");
2574 if (zebra_rnh_ipv6_default_route
)
2575 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2577 if (zebrad
.ribq
->spec
.hold
!= ZEBRA_RIB_PROCESS_HOLD_TIME
)
2578 vty_out(vty
, "zebra work-queue %u\n", zebrad
.ribq
->spec
.hold
);
2580 if (zebrad
.packets_to_process
!= ZEBRA_ZAPI_PACKETS_TO_PROCESS
)
2582 "zebra zapi-packets %u\n", zebrad
.packets_to_process
);
2584 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2586 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2587 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2588 ipv4_multicast_mode
== MCAST_URIB_ONLY
2590 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2592 : ipv4_multicast_mode
2593 == MCAST_MIX_MRIB_FIRST
2595 : ipv4_multicast_mode
2596 == MCAST_MIX_DISTANCE
2600 zebra_routemap_config_write_protocol(vty
);
2606 /* Display default rtm_table for all clients. */
2611 "default routing table to use for all clients\n")
2613 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2617 DEFUN (config_table
,
2620 "Configure target kernel routing table\n"
2623 zebrad
.rtm_table_default
= strtol(argv
[1]->arg
, (char **)0, 10);
2627 DEFUN (no_config_table
,
2628 no_config_table_cmd
,
2629 "no table [TABLENO]",
2631 "Configure target kernel routing table\n"
2634 zebrad
.rtm_table_default
= 0;
2648 " Route Route Neighbor LSP LSP\n");
2650 "VRF Installs Removals Updates Installs Removals\n");
2652 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
) {
2653 struct zebra_vrf
*zvrf
= vrf
->info
;
2655 vty_out(vty
, "%-25s %10" PRIu64
" %10" PRIu64
" %10" PRIu64
2656 " %10" PRIu64
" %10" PRIu64
"\n",
2657 vrf
->name
, zvrf
->installs
, zvrf
->removals
,
2658 zvrf
->neigh_updates
, zvrf
->lsp_installs
,
2659 zvrf
->lsp_removals
);
2665 DEFUN (ip_forwarding
,
2669 "Turn on IP forwarding\n")
2675 ret
= ipforward_on();
2678 vty_out(vty
, "Can't turn on IP forwarding\n");
2679 return CMD_WARNING_CONFIG_FAILED
;
2685 DEFUN (no_ip_forwarding
,
2686 no_ip_forwarding_cmd
,
2690 "Turn off IP forwarding\n")
2696 ret
= ipforward_off();
2699 vty_out(vty
, "Can't turn off IP forwarding\n");
2700 return CMD_WARNING_CONFIG_FAILED
;
2706 /* Only display ip forwarding is enabled or not. */
2707 DEFUN (show_ip_forwarding
,
2708 show_ip_forwarding_cmd
,
2709 "show ip forwarding",
2712 "IP forwarding status\n")
2719 vty_out(vty
, "IP forwarding is off\n");
2721 vty_out(vty
, "IP forwarding is on\n");
2725 /* Only display ipv6 forwarding is enabled or not. */
2726 DEFUN (show_ipv6_forwarding
,
2727 show_ipv6_forwarding_cmd
,
2728 "show ipv6 forwarding",
2730 "IPv6 information\n"
2731 "Forwarding status\n")
2735 ret
= ipforward_ipv6();
2739 vty_out(vty
, "ipv6 forwarding is unknown\n");
2742 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2745 vty_out(vty
, "ipv6 forwarding is %s\n", "on");
2748 vty_out(vty
, "ipv6 forwarding is %s\n", "off");
2754 DEFUN (ipv6_forwarding
,
2755 ipv6_forwarding_cmd
,
2758 "Turn on IPv6 forwarding\n")
2762 ret
= ipforward_ipv6();
2764 ret
= ipforward_ipv6_on();
2767 vty_out(vty
, "Can't turn on IPv6 forwarding\n");
2768 return CMD_WARNING_CONFIG_FAILED
;
2774 DEFUN (no_ipv6_forwarding
,
2775 no_ipv6_forwarding_cmd
,
2776 "no ipv6 forwarding",
2779 "Turn off IPv6 forwarding\n")
2783 ret
= ipforward_ipv6();
2785 ret
= ipforward_ipv6_off();
2788 vty_out(vty
, "Can't turn off IPv6 forwarding\n");
2789 return CMD_WARNING_CONFIG_FAILED
;
2795 /* Table configuration write function. */
2796 static int config_write_table(struct vty
*vty
)
2798 if (zebrad
.rtm_table_default
)
2799 vty_out(vty
, "table %d\n", zebrad
.rtm_table_default
);
2803 /* IPForwarding configuration write function. */
2804 static int config_write_forwarding(struct vty
*vty
)
2806 /* FIXME: Find better place for that. */
2807 router_id_write(vty
);
2810 vty_out(vty
, "no ip forwarding\n");
2811 if (!ipforward_ipv6())
2812 vty_out(vty
, "no ipv6 forwarding\n");
2813 vty_out(vty
, "!\n");
2817 /* IP node for static routes. */
2818 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2819 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2820 /* table node for routing tables. */
2821 static struct cmd_node table_node
= {TABLE_NODE
,
2822 "", /* This node has no interface. */
2824 static struct cmd_node forwarding_node
= {FORWARDING_NODE
,
2825 "", /* This node has no interface. */
2829 void zebra_vty_init(void)
2831 /* Install configuration write function. */
2832 install_node(&table_node
, config_write_table
);
2833 install_node(&forwarding_node
, config_write_forwarding
);
2835 install_element(VIEW_NODE
, &show_ip_forwarding_cmd
);
2836 install_element(CONFIG_NODE
, &ip_forwarding_cmd
);
2837 install_element(CONFIG_NODE
, &no_ip_forwarding_cmd
);
2838 install_element(ENABLE_NODE
, &show_zebra_cmd
);
2841 install_element(VIEW_NODE
, &show_table_cmd
);
2842 install_element(CONFIG_NODE
, &config_table_cmd
);
2843 install_element(CONFIG_NODE
, &no_config_table_cmd
);
2844 #endif /* HAVE_NETLINK */
2846 install_element(VIEW_NODE
, &show_ipv6_forwarding_cmd
);
2847 install_element(CONFIG_NODE
, &ipv6_forwarding_cmd
);
2848 install_element(CONFIG_NODE
, &no_ipv6_forwarding_cmd
);
2851 zebra_route_map_init();
2853 install_node(&ip_node
, zebra_ip_config
);
2854 install_node(&protocol_node
, config_write_protocol
);
2856 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2857 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2858 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
2859 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2860 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2861 install_element(CONFIG_NODE
, &ip_route_blackhole_cmd
);
2862 install_element(CONFIG_NODE
, &ip_route_address_interface_cmd
);
2863 install_element(CONFIG_NODE
, &ip_route_cmd
);
2864 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2865 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2866 install_element(CONFIG_NODE
, &zebra_workqueue_timer_cmd
);
2867 install_element(CONFIG_NODE
, &no_zebra_workqueue_timer_cmd
);
2868 install_element(CONFIG_NODE
, &zebra_packet_process_cmd
);
2869 install_element(CONFIG_NODE
, &no_zebra_packet_process_cmd
);
2871 install_element(VIEW_NODE
, &show_vrf_cmd
);
2872 install_element(VIEW_NODE
, &show_vrf_vni_cmd
);
2873 install_element(VIEW_NODE
, &show_route_cmd
);
2874 install_element(VIEW_NODE
, &show_route_detail_cmd
);
2875 install_element(VIEW_NODE
, &show_route_summary_cmd
);
2876 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2877 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2878 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2879 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2881 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2882 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2884 install_element(CONFIG_NODE
, &ipv6_route_blackhole_cmd
);
2885 install_element(CONFIG_NODE
, &ipv6_route_address_interface_cmd
);
2886 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
2887 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2888 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2889 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2890 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2891 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2893 /* Commands for VRF */
2894 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2896 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2897 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2898 install_element(VIEW_NODE
, &show_evpn_l3vni_cmd
);
2899 install_element(VIEW_NODE
, &show_evpn_l3vni_vni_cmd
);
2900 install_element(VIEW_NODE
, &show_evpn_rmac_l3vni_mac_cmd
);
2901 install_element(VIEW_NODE
, &show_evpn_rmac_l3vni_cmd
);
2902 install_element(VIEW_NODE
, &show_evpn_rmac_l3vni_all_cmd
);
2903 install_element(VIEW_NODE
, &show_evpn_nh_l3vni_ip_cmd
);
2904 install_element(VIEW_NODE
, &show_evpn_nh_l3vni_cmd
);
2905 install_element(VIEW_NODE
, &show_evpn_nh_l3vni_all_cmd
);
2906 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2907 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2908 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2909 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2910 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2911 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2912 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2913 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2914 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);
2916 install_element(CONFIG_NODE
, &no_vrf_vni_mapping_cmd
);
2917 install_element(VRF_NODE
, &vrf_vni_mapping_cmd
);
2918 install_element(VRF_NODE
, &no_vrf_vni_mapping_cmd
);