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 #include "zebra/zebra_vty_clippy.c"
48 extern int allow_delete
;
50 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
51 safi_t safi
, bool use_fib
, u_char use_json
,
52 route_tag_t tag
, struct prefix
*longer_prefix_p
,
53 bool supernets_only
, int type
,
54 u_short ospf_instance_id
);
55 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
58 #define ONE_DAY_SECOND 60*60*24
59 #define ONE_WEEK_SECOND 60*60*24*7
61 /* VNI range as per RFC 7432 */
62 #define CMD_VNI_RANGE "(1-16777215)"
64 /* General function for static route. */
65 static int zebra_static_route(struct vty
*vty
, afi_t afi
, safi_t safi
,
66 const char *negate
, const char *dest_str
,
67 const char *mask_str
, const char *src_str
,
68 const char *gate_str
, const char *ifname
,
69 const char *flag_str
, const char *tag_str
,
70 const char *distance_str
, const char *vrf_id_str
,
71 const char *label_str
)
76 struct prefix_ipv6
*src_p
= NULL
;
78 union g_addr
*gatep
= NULL
;
82 struct zebra_vrf
*zvrf
;
83 unsigned int ifindex
= 0;
85 struct static_nh_label snh_label
;
87 ret
= str2prefix(dest_str
, &p
);
89 vty_out(vty
, "%% Malformed address\n");
90 return CMD_WARNING_CONFIG_FAILED
;
95 /* Cisco like mask notation. */
97 ret
= inet_aton(mask_str
, &mask
);
99 vty_out(vty
, "%% Malformed address\n");
100 return CMD_WARNING_CONFIG_FAILED
;
102 p
.prefixlen
= ip_masklen(mask
);
106 /* srcdest routing */
108 ret
= str2prefix(src_str
, &src
);
109 if (ret
<= 0 || src
.family
!= AF_INET6
) {
110 vty_out(vty
, "%% Malformed source address\n");
111 return CMD_WARNING_CONFIG_FAILED
;
113 src_p
= (struct prefix_ipv6
*)&src
;
120 /* Apply mask for given prefix. */
123 /* Administrative distance. */
125 distance
= atoi(distance_str
);
127 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
131 tag
= strtoul(tag_str
, NULL
, 10);
134 zvrf
= zebra_vrf_lookup_by_name(vrf_id_str
);
137 vty_out(vty
, "%% vrf %s is not defined\n", vrf_id_str
);
138 return CMD_WARNING_CONFIG_FAILED
;
142 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
146 "%% MPLS not turned on in kernel, ignoring command\n");
147 return CMD_WARNING_CONFIG_FAILED
;
149 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
154 vty_out(vty
, "%% Malformed label(s)\n");
158 "%% Cannot use reserved label(s) (%d-%d)\n",
159 MPLS_MIN_RESERVED_LABEL
,
160 MPLS_MAX_RESERVED_LABEL
);
164 "%% Too many labels. Enter %d or fewer\n",
168 return CMD_WARNING_CONFIG_FAILED
;
172 /* Null0 static route. */
174 && (strncasecmp(ifname
, "Null0", strlen(ifname
)) == 0)) {
176 vty_out(vty
, "%% can not have flag %s with Null0\n",
178 return CMD_WARNING_CONFIG_FAILED
;
180 SET_FLAG(flag
, ZEBRA_FLAG_BLACKHOLE
);
186 switch (flag_str
[0]) {
189 SET_FLAG(flag
, ZEBRA_FLAG_REJECT
);
193 SET_FLAG(flag
, ZEBRA_FLAG_BLACKHOLE
);
196 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
197 return CMD_WARNING_CONFIG_FAILED
;
202 if (inet_pton(afi2family(afi
), gate_str
, &gate
) != 1) {
203 vty_out(vty
, "%% Malformed nexthop address %s\n",
205 return CMD_WARNING_CONFIG_FAILED
;
211 struct interface
*ifp
;
212 ifp
= if_lookup_by_name(ifname
, zvrf_id(zvrf
));
214 vty_out(vty
, "%% Malformed Interface name %s\n",
216 ifindex
= IFINDEX_DELETED
;
218 ifindex
= ifp
->ifindex
;
221 if (gate_str
== NULL
&& ifname
== NULL
)
222 type
= STATIC_BLACKHOLE
;
223 else if (gate_str
&& ifname
) {
225 type
= STATIC_IPV4_GATEWAY_IFINDEX
;
227 type
= STATIC_IPV6_GATEWAY_IFINDEX
;
229 type
= STATIC_IFINDEX
;
232 type
= STATIC_IPV4_GATEWAY
;
234 type
= STATIC_IPV6_GATEWAY
;
238 static_add_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifindex
,
239 ifname
, flag
, tag
, distance
, zvrf
, &snh_label
);
241 static_delete_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifindex
,
242 tag
, distance
, zvrf
, &snh_label
);
247 /* Static unicast routes for multicast RPF lookup. */
248 DEFPY (ip_mroute_dist
,
250 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
253 "Configure static unicast route into MRIB for multicast RPF lookup\n"
254 "IP destination prefix (e.g. 10.0.0.0/8)\n"
256 "Nexthop interface name\n"
259 return zebra_static_route(vty
, AFI_IP
, SAFI_MULTICAST
, no
, prefix_str
,
260 NULL
, NULL
, gate_str
, ifname
, NULL
, NULL
,
261 distance_str
, NULL
, NULL
);
264 DEFUN (ip_multicast_mode
,
265 ip_multicast_mode_cmd
,
266 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
268 "Multicast options\n"
269 "RPF lookup behavior\n"
270 "Lookup in unicast RIB only\n"
271 "Lookup in multicast RIB only\n"
272 "Try multicast RIB first, fall back to unicast RIB\n"
273 "Lookup both, use entry with lower distance\n"
274 "Lookup both, use entry with longer prefix\n")
276 char *mode
= argv
[3]->text
;
278 if (strmatch(mode
, "urib-only"))
279 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
280 else if (strmatch(mode
, "mrib-only"))
281 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
282 else if (strmatch(mode
, "mrib-then-urib"))
283 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
284 else if (strmatch(mode
, "lower-distance"))
285 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
286 else if (strmatch(mode
, "longer-prefix"))
287 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
289 vty_out(vty
, "Invalid mode specified\n");
290 return CMD_WARNING_CONFIG_FAILED
;
296 DEFUN (no_ip_multicast_mode
,
297 no_ip_multicast_mode_cmd
,
298 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
301 "Multicast options\n"
302 "RPF lookup behavior\n"
303 "Lookup in unicast RIB only\n"
304 "Lookup in multicast RIB only\n"
305 "Try multicast RIB first, fall back to unicast RIB\n"
306 "Lookup both, use entry with lower distance\n"
307 "Lookup both, use entry with longer prefix\n")
309 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
316 "show ip rpf [json]",
319 "Display RPF information for multicast source\n"
322 int uj
= use_json(argc
, argv
);
323 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
324 false, uj
, 0, NULL
, false, -1, 0);
327 DEFUN (show_ip_rpf_addr
,
328 show_ip_rpf_addr_cmd
,
329 "show ip rpf A.B.C.D",
332 "Display RPF information for multicast source\n"
333 "IP multicast source address (e.g. 10.0.0.0)\n")
337 struct route_node
*rn
;
338 struct route_entry
*re
;
341 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
343 vty_out(vty
, "%% Malformed address\n");
347 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
350 vty_show_ip_route_detail(vty
, rn
, 1);
352 vty_out(vty
, "%% No match for RPF lookup\n");
357 /* Static route configuration. */
361 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
363 {A.B.C.D$gate|INTERFACE$ifname}\
365 |<reject|blackhole>$flag\
375 "Establish static routes\n"
376 "IP destination prefix (e.g. 10.0.0.0/8)\n"
377 "IP destination prefix\n"
378 "IP destination prefix mask\n"
379 "IP gateway address\n"
380 "IP gateway interface name\n"
382 "Emit an ICMP unreachable when matched\n"
383 "Silently discard pkts when matched\n"
384 "Set tag for this route\n"
386 "Distance value for this route\n"
390 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
391 mask_str
, NULL
, gate_str
, ifname
, flag
,
392 tag_str
, distance_str
, vrf
, label
);
396 /* New RIB. Detailed information for IPv4 route. */
397 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
400 struct route_entry
*re
;
401 struct nexthop
*nexthop
;
402 char buf
[SRCDEST2STR_BUFFER
];
403 struct zebra_vrf
*zvrf
;
405 RNODE_FOREACH_RE(rn
, re
)
407 const char *mcast_info
= "";
409 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
410 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
411 ? " using Multicast RIB"
412 : " using Unicast RIB";
415 vty_out(vty
, "Routing entry for %s%s\n",
416 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
417 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
419 vty_out(vty
, "[%d]", re
->instance
);
421 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
424 vty_out(vty
, ", tag %d", re
->tag
);
426 vty_out(vty
, ", mtu %u", re
->mtu
);
427 if (re
->vrf_id
!= VRF_DEFAULT
) {
428 zvrf
= vrf_info_lookup(re
->vrf_id
);
429 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
431 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
432 vty_out(vty
, ", best");
434 vty_out(vty
, ", refcnt %ld", re
->refcnt
);
435 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
436 vty_out(vty
, ", blackhole");
437 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
438 vty_out(vty
, ", reject");
441 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
442 || re
->type
== ZEBRA_ROUTE_ISIS
443 || re
->type
== ZEBRA_ROUTE_NHRP
444 || re
->type
== ZEBRA_ROUTE_TABLE
445 || re
->type
== ZEBRA_ROUTE_BGP
) {
450 uptime
-= re
->uptime
;
451 tm
= gmtime(&uptime
);
453 vty_out(vty
, " Last update ");
455 if (uptime
< ONE_DAY_SECOND
)
456 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
457 tm
->tm_min
, tm
->tm_sec
);
458 else if (uptime
< ONE_WEEK_SECOND
)
459 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
460 tm
->tm_hour
, tm
->tm_min
);
462 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
463 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
465 vty_out(vty
, " ago\n");
468 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
471 vty_out(vty
, " %c%s",
472 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
475 nexthop
->rparent
? " " : "");
477 switch (nexthop
->type
) {
478 case NEXTHOP_TYPE_IPV4
:
479 case NEXTHOP_TYPE_IPV4_IFINDEX
:
481 inet_ntoa(nexthop
->gate
.ipv4
));
482 if (nexthop
->ifindex
)
483 vty_out(vty
, ", via %s",
484 ifindex2ifname(nexthop
->ifindex
,
487 case NEXTHOP_TYPE_IPV6
:
488 case NEXTHOP_TYPE_IPV6_IFINDEX
:
490 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
492 if (nexthop
->ifindex
)
493 vty_out(vty
, ", via %s",
494 ifindex2ifname(nexthop
->ifindex
,
497 case NEXTHOP_TYPE_IFINDEX
:
498 vty_out(vty
, " directly connected, %s",
499 ifindex2ifname(nexthop
->ifindex
,
502 case NEXTHOP_TYPE_BLACKHOLE
:
503 vty_out(vty
, " directly connected, Null0");
508 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
509 vty_out(vty
, " inactive");
511 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
512 vty_out(vty
, " onlink");
514 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
515 vty_out(vty
, " (recursive)");
517 switch (nexthop
->type
) {
518 case NEXTHOP_TYPE_IPV4
:
519 case NEXTHOP_TYPE_IPV4_IFINDEX
:
520 if (nexthop
->src
.ipv4
.s_addr
) {
521 if (inet_ntop(AF_INET
,
523 addrstr
, sizeof addrstr
))
524 vty_out(vty
, ", src %s",
528 case NEXTHOP_TYPE_IPV6
:
529 case NEXTHOP_TYPE_IPV6_IFINDEX
:
530 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
532 if (inet_ntop(AF_INET6
,
534 addrstr
, sizeof addrstr
))
535 vty_out(vty
, ", src %s",
544 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
546 /* Label information */
547 if (nexthop
->nh_label
548 && nexthop
->nh_label
->num_labels
) {
549 vty_out(vty
, ", label %s",
551 nexthop
->nh_label
->num_labels
,
552 nexthop
->nh_label
->label
, buf
,
562 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
563 struct route_entry
*re
, json_object
*json
)
565 struct nexthop
*nexthop
;
567 char buf
[SRCDEST2STR_BUFFER
];
568 json_object
*json_nexthops
= NULL
;
569 json_object
*json_nexthop
= NULL
;
570 json_object
*json_route
= NULL
;
571 json_object
*json_labels
= NULL
;
574 json_route
= json_object_new_object();
575 json_nexthops
= json_object_new_array();
577 json_object_string_add(json_route
, "prefix",
578 srcdest_rnode2str(rn
, buf
, sizeof buf
));
579 json_object_string_add(json_route
, "protocol",
580 zebra_route_string(re
->type
));
583 json_object_int_add(json_route
, "instance",
587 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
589 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
590 json_object_boolean_true_add(json_route
, "selected");
592 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
593 json_object_int_add(json_route
, "distance",
595 json_object_int_add(json_route
, "metric", re
->metric
);
598 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
599 json_object_boolean_true_add(json_route
, "blackhole");
601 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
602 json_object_boolean_true_add(json_route
, "reject");
604 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
605 || re
->type
== ZEBRA_ROUTE_ISIS
606 || re
->type
== ZEBRA_ROUTE_NHRP
607 || re
->type
== ZEBRA_ROUTE_TABLE
608 || re
->type
== ZEBRA_ROUTE_BGP
) {
613 uptime
-= re
->uptime
;
614 tm
= gmtime(&uptime
);
616 if (uptime
< ONE_DAY_SECOND
)
617 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
618 tm
->tm_min
, tm
->tm_sec
);
619 else if (uptime
< ONE_WEEK_SECOND
)
620 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
621 tm
->tm_hour
, tm
->tm_min
);
623 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
624 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
627 json_object_string_add(json_route
, "uptime", buf
);
630 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
631 json_nexthop
= json_object_new_object();
633 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
634 json_object_boolean_true_add(json_nexthop
,
637 switch (nexthop
->type
) {
638 case NEXTHOP_TYPE_IPV4
:
639 case NEXTHOP_TYPE_IPV4_IFINDEX
:
640 json_object_string_add(
642 inet_ntoa(nexthop
->gate
.ipv4
));
643 json_object_string_add(json_nexthop
, "afi",
646 if (nexthop
->ifindex
) {
647 json_object_int_add(json_nexthop
,
650 json_object_string_add(
651 json_nexthop
, "interfaceName",
652 ifindex2ifname(nexthop
->ifindex
,
656 case NEXTHOP_TYPE_IPV6
:
657 case NEXTHOP_TYPE_IPV6_IFINDEX
:
658 json_object_string_add(
660 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
662 json_object_string_add(json_nexthop
, "afi",
665 if (nexthop
->ifindex
) {
666 json_object_int_add(json_nexthop
,
669 json_object_string_add(
670 json_nexthop
, "interfaceName",
671 ifindex2ifname(nexthop
->ifindex
,
676 case NEXTHOP_TYPE_IFINDEX
:
677 json_object_boolean_true_add(
678 json_nexthop
, "directlyConnected");
679 json_object_int_add(json_nexthop
,
682 json_object_string_add(
683 json_nexthop
, "interfaceName",
684 ifindex2ifname(nexthop
->ifindex
,
687 case NEXTHOP_TYPE_BLACKHOLE
:
688 json_object_boolean_true_add(json_nexthop
,
695 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
696 json_object_boolean_true_add(json_nexthop
,
699 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
700 json_object_boolean_true_add(json_nexthop
,
703 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
704 json_object_boolean_true_add(json_nexthop
,
707 switch (nexthop
->type
) {
708 case NEXTHOP_TYPE_IPV4
:
709 case NEXTHOP_TYPE_IPV4_IFINDEX
:
710 if (nexthop
->src
.ipv4
.s_addr
) {
711 if (inet_ntop(AF_INET
,
712 &nexthop
->src
.ipv4
, buf
,
714 json_object_string_add(
715 json_nexthop
, "source",
719 case NEXTHOP_TYPE_IPV6
:
720 case NEXTHOP_TYPE_IPV6_IFINDEX
:
721 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
723 if (inet_ntop(AF_INET6
,
724 &nexthop
->src
.ipv6
, buf
,
726 json_object_string_add(
727 json_nexthop
, "source",
735 if (nexthop
->nh_label
736 && nexthop
->nh_label
->num_labels
) {
737 json_labels
= json_object_new_array();
739 for (int label_index
= 0;
741 < nexthop
->nh_label
->num_labels
;
743 json_object_array_add(
746 nexthop
->nh_label
->label
749 json_object_object_add(json_nexthop
, "labels",
753 json_object_array_add(json_nexthops
, json_nexthop
);
756 json_object_object_add(json_route
, "nexthops", json_nexthops
);
757 json_object_array_add(json
, json_route
);
761 /* Nexthop information. */
762 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
763 if (nexthop
== re
->nexthop
) {
764 /* Prefix information. */
765 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
767 len
+= vty_out(vty
, "[%d]", re
->instance
);
770 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
773 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
776 srcdest_rnode2str(rn
, buf
, sizeof buf
));
778 /* Distance and metric display. */
779 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
780 len
+= vty_out(vty
, " [%d/%d]", re
->distance
,
783 vty_out(vty
, " %c%*c",
784 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
787 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
789 switch (nexthop
->type
) {
790 case NEXTHOP_TYPE_IPV4
:
791 case NEXTHOP_TYPE_IPV4_IFINDEX
:
792 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
793 if (nexthop
->ifindex
)
795 ifindex2ifname(nexthop
->ifindex
,
798 case NEXTHOP_TYPE_IPV6
:
799 case NEXTHOP_TYPE_IPV6_IFINDEX
:
800 vty_out(vty
, " via %s",
801 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
803 if (nexthop
->ifindex
)
805 ifindex2ifname(nexthop
->ifindex
,
809 case NEXTHOP_TYPE_IFINDEX
:
810 vty_out(vty
, " is directly connected, %s",
811 ifindex2ifname(nexthop
->ifindex
, re
->vrf_id
));
813 case NEXTHOP_TYPE_BLACKHOLE
:
814 vty_out(vty
, " is directly connected, Null0");
819 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
820 vty_out(vty
, " inactive");
822 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
823 vty_out(vty
, " onlink");
825 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
826 vty_out(vty
, " (recursive)");
828 switch (nexthop
->type
) {
829 case NEXTHOP_TYPE_IPV4
:
830 case NEXTHOP_TYPE_IPV4_IFINDEX
:
831 if (nexthop
->src
.ipv4
.s_addr
) {
832 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
834 vty_out(vty
, ", src %s", buf
);
837 case NEXTHOP_TYPE_IPV6
:
838 case NEXTHOP_TYPE_IPV6_IFINDEX
:
839 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
840 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
842 vty_out(vty
, ", src %s", buf
);
849 /* Label information */
850 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
851 vty_out(vty
, ", label %s",
852 mpls_label2str(nexthop
->nh_label
->num_labels
,
853 nexthop
->nh_label
->label
, buf
,
857 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
858 vty_out(vty
, ", bh");
859 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
860 vty_out(vty
, ", rej");
862 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
863 || re
->type
== ZEBRA_ROUTE_ISIS
864 || re
->type
== ZEBRA_ROUTE_NHRP
865 || re
->type
== ZEBRA_ROUTE_TABLE
866 || re
->type
== ZEBRA_ROUTE_BGP
) {
871 uptime
-= re
->uptime
;
872 tm
= gmtime(&uptime
);
874 if (uptime
< ONE_DAY_SECOND
)
875 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
876 tm
->tm_min
, tm
->tm_sec
);
877 else if (uptime
< ONE_WEEK_SECOND
)
878 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
879 tm
->tm_hour
, tm
->tm_min
);
881 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
882 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
889 static bool use_fib(struct cmd_token
*token
)
891 return strncmp(token
->arg
, "route", strlen(token
->arg
));
894 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
895 safi_t safi
, bool use_fib
, u_char use_json
,
896 route_tag_t tag
, struct prefix
*longer_prefix_p
,
897 bool supernets_only
, int type
,
898 u_short ospf_instance_id
)
900 struct route_table
*table
;
901 struct route_node
*rn
;
902 struct route_entry
*re
;
904 struct zebra_vrf
*zvrf
= NULL
;
906 json_object
*json
= NULL
;
907 json_object
*json_prefix
= NULL
;
910 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
912 vty_out(vty
, "{}\n");
914 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
918 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
920 vty_out(vty
, "{}\n");
922 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
926 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
929 vty_out(vty
, "{}\n");
934 json
= json_object_new_object();
936 /* Show all routes. */
937 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
938 RNODE_FOREACH_RE(rn
, re
)
941 && !CHECK_FLAG(re
->status
,
942 ROUTE_ENTRY_SELECTED_FIB
))
945 if (tag
&& re
->tag
!= tag
)
949 && !prefix_match(longer_prefix_p
, &rn
->p
))
952 /* This can only be true when the afi is IPv4 */
953 if (supernets_only
) {
954 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
956 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
959 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
962 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
966 if (type
&& re
->type
!= type
)
970 && (re
->type
!= ZEBRA_ROUTE_OSPF
971 || re
->instance
!= ospf_instance_id
))
976 json_prefix
= json_object_new_array();
981 SHOW_ROUTE_V4_HEADER
);
984 SHOW_ROUTE_V6_HEADER
);
986 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
987 vty_out(vty
, "\nVRF %s:\n",
994 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
998 prefix2str(&rn
->p
, buf
, sizeof buf
);
999 json_object_object_add(json
, buf
, json_prefix
);
1005 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1006 json
, JSON_C_TO_STRING_PRETTY
));
1007 json_object_free(json
);
1015 "show ip nht [vrf NAME]",
1018 "IP nexthop tracking table\n"
1022 vrf_id_t vrf_id
= VRF_DEFAULT
;
1025 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1027 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1032 DEFUN (show_ip_nht_vrf_all
,
1033 show_ip_nht_vrf_all_cmd
,
1034 "show ip nht vrf all",
1037 "IP nexthop tracking table\n"
1038 VRF_ALL_CMD_HELP_STR
)
1041 struct zebra_vrf
*zvrf
;
1043 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1044 if ((zvrf
= vrf
->info
) != NULL
) {
1045 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1046 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1053 DEFUN (show_ipv6_nht
,
1055 "show ipv6 nht [vrf NAME]",
1058 "IPv6 nexthop tracking table\n"
1062 vrf_id_t vrf_id
= VRF_DEFAULT
;
1065 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1067 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1072 DEFUN (show_ipv6_nht_vrf_all
,
1073 show_ipv6_nht_vrf_all_cmd
,
1074 "show ipv6 nht vrf all",
1077 "IPv6 nexthop tracking table\n"
1078 VRF_ALL_CMD_HELP_STR
)
1081 struct zebra_vrf
*zvrf
;
1083 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1084 if ((zvrf
= vrf
->info
) != NULL
) {
1085 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1086 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1093 DEFUN (ip_nht_default_route
,
1094 ip_nht_default_route_cmd
,
1095 "ip nht resolve-via-default",
1097 "Filter Next Hop tracking route resolution\n"
1098 "Resolve via default route\n")
1100 if (zebra_rnh_ip_default_route
)
1103 zebra_rnh_ip_default_route
= 1;
1104 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1108 DEFUN (no_ip_nht_default_route
,
1109 no_ip_nht_default_route_cmd
,
1110 "no ip nht resolve-via-default",
1113 "Filter Next Hop tracking route resolution\n"
1114 "Resolve via default route\n")
1116 if (!zebra_rnh_ip_default_route
)
1119 zebra_rnh_ip_default_route
= 0;
1120 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1124 DEFUN (ipv6_nht_default_route
,
1125 ipv6_nht_default_route_cmd
,
1126 "ipv6 nht resolve-via-default",
1128 "Filter Next Hop tracking route resolution\n"
1129 "Resolve via default route\n")
1131 if (zebra_rnh_ipv6_default_route
)
1134 zebra_rnh_ipv6_default_route
= 1;
1135 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1139 DEFUN (no_ipv6_nht_default_route
,
1140 no_ipv6_nht_default_route_cmd
,
1141 "no ipv6 nht resolve-via-default",
1144 "Filter Next Hop tracking route resolution\n"
1145 "Resolve via default route\n")
1147 if (!zebra_rnh_ipv6_default_route
)
1150 zebra_rnh_ipv6_default_route
= 0;
1151 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1155 DEFUN (show_ip_route
,
1157 "show ip <fib|route> [vrf NAME] [tag (1-4294967295)|A.B.C.D/M longer-prefixes|supernets-only|" FRR_IP_REDIST_STR_ZEBRA
"|ospf (1-65535)] [json]",
1160 "IP forwarding table\n"
1161 "IP routing table\n"
1163 "Show only routes with tag\n"
1165 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1166 "Show route matching the specified Network/Mask pair only\n"
1167 "Show supernet entries only\n"
1168 FRR_IP_REDIST_HELP_STR_ZEBRA
1169 "Open Shortest Path First (OSPFv2)\n"
1173 bool uf
= use_fib(argv
[2]);
1174 struct route_table
*table
;
1176 route_tag_t tag
= 0;
1177 vrf_id_t vrf_id
= VRF_DEFAULT
;
1179 struct zebra_vrf
*zvrf
;
1180 int uj
= use_json(argc
, argv
);
1183 bool longer_prefixes
= false;
1184 bool supernets_only
= false;
1186 u_short ospf_instance_id
= 0;
1188 if (argv_find(argv
, argc
, "vrf", &idx
)) {
1189 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
1192 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
1195 if (argv_find(argv
, argc
, "tag", &idx
))
1196 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
1198 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)) {
1199 str2prefix(argv
[idx
]->arg
, &p
);
1200 longer_prefixes
= true;
1203 else if (argv_find(argv
, argc
, "supernets_only", &idx
))
1204 supernets_only
= true;
1207 if (argv_find(argv
, argc
, "kernel", &idx
))
1208 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1209 else if (argv_find(argv
, argc
, "babel", &idx
))
1210 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1211 else if (argv_find(argv
, argc
, "connected", &idx
))
1212 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1213 else if (argv_find(argv
, argc
, "static", &idx
))
1214 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1215 else if (argv_find(argv
, argc
, "rip", &idx
))
1216 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1217 else if (argv_find(argv
, argc
, "ospf", &idx
))
1218 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1219 else if (argv_find(argv
, argc
, "isis", &idx
))
1220 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1221 else if (argv_find(argv
, argc
, "bgp", &idx
))
1222 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1223 else if (argv_find(argv
, argc
, "pim", &idx
))
1224 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1225 else if (argv_find(argv
, argc
, "eigrp", &idx
))
1226 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1227 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1228 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1229 else if (argv_find(argv
, argc
, "table", &idx
))
1230 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1231 else if (argv_find(argv
, argc
, "vnc", &idx
))
1232 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1234 if (argv_find(argv
, argc
, "(1-65535)", &idx
))
1235 ospf_instance_id
= strtoul(argv
[idx
]->arg
, NULL
, 10);
1238 vty_out(vty
, "Unknown route type\n");
1244 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1246 if ((zvrf
= vrf
->info
) == NULL
1247 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
1252 vty
, zvrf_name(zvrf
), AFI_IP
, SAFI_UNICAST
, uf
,
1253 uj
, tag
, longer_prefixes
? &p
: NULL
,
1254 supernets_only
, type
, ospf_instance_id
);
1257 vrf
= vrf_lookup_by_id(vrf_id
);
1258 do_show_ip_route(vty
, vrf
->name
, AFI_IP
, SAFI_UNICAST
, uf
, uj
,
1259 tag
, longer_prefixes
? &p
: NULL
,
1260 supernets_only
, type
, ospf_instance_id
);
1265 DEFUN (show_ip_route_addr
,
1266 show_ip_route_addr_cmd
,
1267 "show ip route [vrf NAME] A.B.C.D",
1270 "IP routing table\n"
1272 "Network in the IP routing table to display\n")
1275 struct prefix_ipv4 p
;
1276 struct route_table
*table
;
1277 struct route_node
*rn
;
1278 vrf_id_t vrf_id
= VRF_DEFAULT
;
1280 if (strmatch(argv
[3]->text
, "vrf")) {
1281 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1282 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1284 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1288 vty_out(vty
, "%% Malformed IPv4 address\n");
1292 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1296 rn
= route_node_match(table
, (struct prefix
*)&p
);
1298 vty_out(vty
, "%% Network not in table\n");
1302 vty_show_ip_route_detail(vty
, rn
, 0);
1304 route_unlock_node(rn
);
1309 DEFUN (show_ip_route_prefix
,
1310 show_ip_route_prefix_cmd
,
1311 "show ip route [vrf NAME] A.B.C.D/M",
1314 "IP routing table\n"
1316 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1319 struct prefix_ipv4 p
;
1320 struct route_table
*table
;
1321 struct route_node
*rn
;
1322 vrf_id_t vrf_id
= VRF_DEFAULT
;
1324 if (strmatch(argv
[3]->text
, "vrf")) {
1325 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1326 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1328 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1332 vty_out(vty
, "%% Malformed IPv4 address\n");
1336 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1340 rn
= route_node_match(table
, (struct prefix
*)&p
);
1341 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1342 vty_out(vty
, "%% Network not in table\n");
1346 vty_show_ip_route_detail(vty
, rn
, 0);
1348 route_unlock_node(rn
);
1354 static void vty_show_ip_route_summary(struct vty
*vty
,
1355 struct route_table
*table
)
1357 struct route_node
*rn
;
1358 struct route_entry
*re
;
1359 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1360 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1361 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1362 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1366 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1367 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1368 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1369 RNODE_FOREACH_RE(rn
, re
)
1371 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1372 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1374 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1376 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1378 rib_cnt
[re
->type
]++;
1380 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1381 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1384 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1386 fib_cnt
[re
->type
]++;
1390 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1391 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1393 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1394 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1395 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1396 if (i
== ZEBRA_ROUTE_BGP
) {
1397 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1398 rib_cnt
[ZEBRA_ROUTE_BGP
],
1399 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1400 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1401 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1402 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1404 vty_out(vty
, "%-20s %-20d %-20d \n",
1405 zebra_route_string(i
), rib_cnt
[i
],
1410 vty_out(vty
, "------\n");
1411 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1412 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1417 * Implementation of the ip route summary prefix command.
1419 * This command prints the primary prefixes that have been installed by various
1420 * protocols on the box.
1423 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1424 struct route_table
*table
)
1426 struct route_node
*rn
;
1427 struct route_entry
*re
;
1428 struct nexthop
*nexthop
;
1429 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1430 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1431 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1432 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1436 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1437 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1438 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1439 RNODE_FOREACH_RE(rn
, re
)
1443 * In case of ECMP, count only once.
1446 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1447 nexthop
= nexthop
->next
) {
1449 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1450 rib_cnt
[re
->type
]++;
1451 if (CHECK_FLAG(nexthop
->flags
,
1452 NEXTHOP_FLAG_FIB
)) {
1453 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1454 fib_cnt
[re
->type
]++;
1456 if (re
->type
== ZEBRA_ROUTE_BGP
1457 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1458 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1459 if (CHECK_FLAG(nexthop
->flags
,
1461 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1466 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1467 "Prefix Routes", "FIB",
1468 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1470 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1471 if (rib_cnt
[i
] > 0) {
1472 if (i
== ZEBRA_ROUTE_BGP
) {
1473 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1474 rib_cnt
[ZEBRA_ROUTE_BGP
]
1475 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1476 fib_cnt
[ZEBRA_ROUTE_BGP
]
1477 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1478 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1479 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1480 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1482 vty_out(vty
, "%-20s %-20d %-20d \n",
1483 zebra_route_string(i
), rib_cnt
[i
],
1488 vty_out(vty
, "------\n");
1489 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1490 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1494 /* Show route summary. */
1495 DEFUN (show_ip_route_summary
,
1496 show_ip_route_summary_cmd
,
1497 "show ip route [vrf NAME] summary",
1500 "IP routing table\n"
1502 "Summary of all routes\n")
1504 struct route_table
*table
;
1505 vrf_id_t vrf_id
= VRF_DEFAULT
;
1507 if (strmatch(argv
[3]->text
, "vrf"))
1508 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1510 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1514 vty_show_ip_route_summary(vty
, table
);
1519 /* Show route summary prefix. */
1520 DEFUN (show_ip_route_summary_prefix
,
1521 show_ip_route_summary_prefix_cmd
,
1522 "show ip route [vrf NAME] summary prefix",
1525 "IP routing table\n"
1527 "Summary of all routes\n"
1530 struct route_table
*table
;
1531 vrf_id_t vrf_id
= VRF_DEFAULT
;
1533 if (strmatch(argv
[3]->text
, "vrf"))
1534 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1536 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1540 vty_show_ip_route_summary_prefix(vty
, table
);
1546 DEFUN (show_ip_route_vrf_all_addr
,
1547 show_ip_route_vrf_all_addr_cmd
,
1548 "show ip route vrf all A.B.C.D",
1551 "IP routing table\n"
1552 VRF_ALL_CMD_HELP_STR
1553 "Network in the IP routing table to display\n")
1557 struct prefix_ipv4 p
;
1558 struct route_table
*table
;
1559 struct route_node
*rn
;
1561 struct zebra_vrf
*zvrf
;
1563 ret
= str2prefix_ipv4(argv
[idx_ipv4
]->arg
, &p
);
1565 vty_out(vty
, "%% Malformed IPv4 address\n");
1569 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1571 if ((zvrf
= vrf
->info
) == NULL
1572 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1575 rn
= route_node_match(table
, (struct prefix
*)&p
);
1579 vty_show_ip_route_detail(vty
, rn
, 0);
1581 route_unlock_node(rn
);
1587 DEFUN (show_ip_route_vrf_all_prefix
,
1588 show_ip_route_vrf_all_prefix_cmd
,
1589 "show ip route vrf all A.B.C.D/M",
1592 "IP routing table\n"
1593 VRF_ALL_CMD_HELP_STR
1594 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1596 int idx_ipv4_prefixlen
= 5;
1598 struct prefix_ipv4 p
;
1599 struct route_table
*table
;
1600 struct route_node
*rn
;
1602 struct zebra_vrf
*zvrf
;
1604 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
1606 vty_out(vty
, "%% Malformed IPv4 address\n");
1610 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1612 if ((zvrf
= vrf
->info
) == NULL
1613 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1616 rn
= route_node_match(table
, (struct prefix
*)&p
);
1619 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
1620 route_unlock_node(rn
);
1624 vty_show_ip_route_detail(vty
, rn
, 0);
1626 route_unlock_node(rn
);
1632 DEFUN (show_ip_route_vrf_all_summary
,
1633 show_ip_route_vrf_all_summary_cmd
,
1634 "show ip route vrf all summary ",
1637 "IP routing table\n"
1638 VRF_ALL_CMD_HELP_STR
1639 "Summary of all routes\n")
1642 struct zebra_vrf
*zvrf
;
1644 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1645 if ((zvrf
= vrf
->info
) != NULL
)
1646 vty_show_ip_route_summary(vty
,
1647 zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1652 DEFUN (show_ip_route_vrf_all_summary_prefix
,
1653 show_ip_route_vrf_all_summary_prefix_cmd
,
1654 "show ip route vrf all summary prefix",
1657 "IP routing table\n"
1658 VRF_ALL_CMD_HELP_STR
1659 "Summary of all routes\n"
1663 struct zebra_vrf
*zvrf
;
1665 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1666 if ((zvrf
= vrf
->info
) != NULL
)
1667 vty_show_ip_route_summary_prefix(
1668 vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1673 /* Write static route configuration. */
1674 static int static_config(struct vty
*vty
, afi_t afi
, safi_t safi
,
1677 struct route_node
*rn
;
1678 struct static_route
*si
;
1679 struct route_table
*stable
;
1681 struct zebra_vrf
*zvrf
;
1682 char buf
[SRCDEST2STR_BUFFER
];
1685 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1687 if (!(zvrf
= vrf
->info
))
1689 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1692 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1693 for (si
= rn
->info
; si
; si
= si
->next
) {
1694 vty_out(vty
, "%s %s", cmd
,
1695 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1698 case STATIC_IPV4_GATEWAY
:
1700 inet_ntoa(si
->addr
.ipv4
));
1702 case STATIC_IPV6_GATEWAY
:
1705 &si
->addr
.ipv6
, buf
,
1708 case STATIC_IFINDEX
:
1709 vty_out(vty
, " %s", si
->ifname
);
1711 /* blackhole and Null0 mean the same thing */
1712 case STATIC_BLACKHOLE
:
1713 if (CHECK_FLAG(si
->flags
, ZEBRA_FLAG_REJECT
))
1714 vty_out(vty
, " reject");
1716 vty_out(vty
, " Null0");
1718 case STATIC_IPV4_GATEWAY_IFINDEX
:
1719 vty_out(vty
, " %s %s",
1721 &si
->addr
.ipv4
, buf
,
1723 ifindex2ifname(si
->ifindex
,
1726 case STATIC_IPV6_GATEWAY_IFINDEX
:
1727 vty_out(vty
, " %s %s",
1729 &si
->addr
.ipv6
, buf
,
1731 ifindex2ifname(si
->ifindex
,
1736 /* flags are incompatible with STATIC_BLACKHOLE
1738 if (si
->type
!= STATIC_BLACKHOLE
) {
1739 if (CHECK_FLAG(si
->flags
,
1741 vty_out(vty
, " %s", "reject");
1743 if (CHECK_FLAG(si
->flags
,
1744 ZEBRA_FLAG_BLACKHOLE
))
1750 vty_out(vty
, " tag %" ROUTE_TAG_PRI
,
1754 != ZEBRA_STATIC_DISTANCE_DEFAULT
)
1755 vty_out(vty
, " %d", si
->distance
);
1757 if (si
->vrf_id
!= VRF_DEFAULT
)
1758 vty_out(vty
, " vrf %s",
1761 /* Label information */
1762 if (si
->snh_label
.num_labels
)
1763 vty_out(vty
, " label %s",
1767 si
->snh_label
.label
,
1768 buf
, sizeof buf
, 0));
1780 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
1782 {X:X::X:X$gate|INTERFACE$ifname}\
1784 |<reject|blackhole>$flag\
1794 "Establish static routes\n"
1795 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1796 "IPv6 source-dest route\n"
1797 "IPv6 source prefix\n"
1798 "IPv6 gateway address\n"
1799 "IPv6 gateway interface name\n"
1801 "Emit an ICMP unreachable when matched\n"
1802 "Silently discard pkts when matched\n"
1803 "Set tag for this route\n"
1805 "Distance value for this prefix\n"
1809 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1810 NULL
, from_str
, gate_str
, ifname
, flag
,
1811 tag_str
, distance_str
, vrf
, label
);
1814 DEFUN (show_ipv6_route
,
1815 show_ipv6_route_cmd
,
1816 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA
"] [json]",
1819 "IP forwarding table\n"
1820 "IP routing table\n"
1822 "Show only routes with tag\n"
1825 "Show route matching the specified Network/Mask pair only\n"
1826 FRR_IP6_REDIST_HELP_STR_ZEBRA
1829 bool uf
= use_fib(argv
[2]);
1830 struct route_table
*table
;
1832 route_tag_t tag
= 0;
1833 vrf_id_t vrf_id
= VRF_DEFAULT
;
1835 struct zebra_vrf
*zvrf
;
1836 int uj
= use_json(argc
, argv
);
1839 bool longer_prefixes
= false;
1840 bool supernets_only
= false;
1843 if (argv_find(argv
, argc
, "vrf", &idx
)) {
1844 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
1847 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
1850 if (argv_find(argv
, argc
, "tag", &idx
))
1851 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
1853 else if (argv_find(argv
, argc
, "X:X::X:X/M", &idx
)) {
1854 str2prefix(argv
[idx
]->arg
, &p
);
1855 longer_prefixes
= true;
1859 if (argv_find(argv
, argc
, "kernel", &idx
))
1860 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1861 else if (argv_find(argv
, argc
, "babel", &idx
))
1862 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1863 else if (argv_find(argv
, argc
, "connected", &idx
))
1864 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1865 else if (argv_find(argv
, argc
, "static", &idx
))
1866 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1867 else if (argv_find(argv
, argc
, "ripng", &idx
))
1868 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1869 else if (argv_find(argv
, argc
, "ospf6", &idx
))
1870 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1871 else if (argv_find(argv
, argc
, "isis", &idx
))
1872 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1873 else if (argv_find(argv
, argc
, "bgp", &idx
))
1874 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1875 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1876 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1877 else if (argv_find(argv
, argc
, "table", &idx
))
1878 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1879 else if (argv_find(argv
, argc
, "vnc", &idx
))
1880 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1883 vty_out(vty
, "Unknown route type\n");
1889 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1891 if ((zvrf
= vrf
->info
) == NULL
1892 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
])
1896 do_show_ip_route(vty
, zvrf_name(zvrf
), AFI_IP6
,
1897 SAFI_UNICAST
, uf
, uj
, tag
,
1898 longer_prefixes
? &p
: NULL
,
1899 supernets_only
, type
, 0);
1902 vrf
= vrf_lookup_by_id(vrf_id
);
1903 do_show_ip_route(vty
, vrf
->name
, AFI_IP6
, SAFI_UNICAST
, uf
, uj
,
1904 tag
, longer_prefixes
? &p
: NULL
,
1905 supernets_only
, type
, 0);
1910 DEFUN (show_ipv6_route_addr
,
1911 show_ipv6_route_addr_cmd
,
1912 "show ipv6 route [vrf NAME] X:X::X:X",
1915 "IPv6 routing table\n"
1920 struct prefix_ipv6 p
;
1921 struct route_table
*table
;
1922 struct route_node
*rn
;
1923 vrf_id_t vrf_id
= VRF_DEFAULT
;
1925 if (strmatch(argv
[3]->text
, "vrf")) {
1926 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1927 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1929 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1933 vty_out(vty
, "Malformed IPv6 address\n");
1937 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1941 rn
= route_node_match(table
, (struct prefix
*)&p
);
1943 vty_out(vty
, "%% Network not in table\n");
1947 vty_show_ip_route_detail(vty
, rn
, 0);
1949 route_unlock_node(rn
);
1954 DEFUN (show_ipv6_route_prefix
,
1955 show_ipv6_route_prefix_cmd
,
1956 "show ipv6 route [vrf NAME] X:X::X:X/M",
1959 "IPv6 routing table\n"
1964 struct prefix_ipv6 p
;
1965 struct route_table
*table
;
1966 struct route_node
*rn
;
1967 vrf_id_t vrf_id
= VRF_DEFAULT
;
1969 if (strmatch(argv
[3]->text
, "vrf")) {
1970 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1971 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1973 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1976 vty_out(vty
, "Malformed IPv6 prefix\n");
1980 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1984 rn
= route_node_match(table
, (struct prefix
*)&p
);
1985 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1986 vty_out(vty
, "%% Network not in table\n");
1990 vty_show_ip_route_detail(vty
, rn
, 0);
1992 route_unlock_node(rn
);
1998 /* Show route summary. */
1999 DEFUN (show_ipv6_route_summary
,
2000 show_ipv6_route_summary_cmd
,
2001 "show ipv6 route [vrf NAME] summary",
2004 "IPv6 routing table\n"
2006 "Summary of all IPv6 routes\n")
2008 struct route_table
*table
;
2009 vrf_id_t vrf_id
= VRF_DEFAULT
;
2011 if (strmatch(argv
[3]->text
, "vrf"))
2012 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2014 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2018 vty_show_ip_route_summary(vty
, table
);
2024 /* Show ipv6 route summary prefix. */
2025 DEFUN (show_ipv6_route_summary_prefix
,
2026 show_ipv6_route_summary_prefix_cmd
,
2027 "show ipv6 route [vrf NAME] summary prefix",
2030 "IPv6 routing table\n"
2032 "Summary of all IPv6 routes\n"
2035 struct route_table
*table
;
2036 vrf_id_t vrf_id
= VRF_DEFAULT
;
2038 if (strmatch(argv
[3]->text
, "vrf"))
2039 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2041 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2045 vty_show_ip_route_summary_prefix(vty
, table
);
2052 * Show IPv6 mroute command.Used to dump
2053 * the Multicast routing table.
2055 DEFUN (show_ipv6_mroute
,
2056 show_ipv6_mroute_cmd
,
2057 "show ipv6 mroute [vrf NAME]",
2060 "IPv6 Multicast routing table\n"
2063 struct route_table
*table
;
2064 struct route_node
*rn
;
2065 struct route_entry
*re
;
2067 vrf_id_t vrf_id
= VRF_DEFAULT
;
2070 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2072 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2076 /* Show all IPv6 route. */
2077 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2078 RNODE_FOREACH_RE(rn
, re
)
2081 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2084 vty_show_ip_route(vty
, rn
, re
, NULL
);
2089 DEFUN (show_ipv6_route_vrf_all_addr
,
2090 show_ipv6_route_vrf_all_addr_cmd
,
2091 "show ipv6 route vrf all X:X::X:X",
2094 "IPv6 routing table\n"
2095 VRF_ALL_CMD_HELP_STR
2100 struct prefix_ipv6 p
;
2101 struct route_table
*table
;
2102 struct route_node
*rn
;
2104 struct zebra_vrf
*zvrf
;
2106 ret
= str2prefix_ipv6(argv
[idx_ipv6
]->arg
, &p
);
2108 vty_out(vty
, "Malformed IPv6 address\n");
2112 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2114 if ((zvrf
= vrf
->info
) == NULL
2115 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2118 rn
= route_node_match(table
, (struct prefix
*)&p
);
2122 vty_show_ip_route_detail(vty
, rn
, 0);
2124 route_unlock_node(rn
);
2130 DEFUN (show_ipv6_route_vrf_all_prefix
,
2131 show_ipv6_route_vrf_all_prefix_cmd
,
2132 "show ipv6 route vrf all X:X::X:X/M",
2135 "IPv6 routing table\n"
2136 VRF_ALL_CMD_HELP_STR
2139 int idx_ipv6_prefixlen
= 5;
2141 struct prefix_ipv6 p
;
2142 struct route_table
*table
;
2143 struct route_node
*rn
;
2145 struct zebra_vrf
*zvrf
;
2147 ret
= str2prefix_ipv6(argv
[idx_ipv6_prefixlen
]->arg
, &p
);
2149 vty_out(vty
, "Malformed IPv6 prefix\n");
2153 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2155 if ((zvrf
= vrf
->info
) == NULL
2156 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2159 rn
= route_node_match(table
, (struct prefix
*)&p
);
2162 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
2163 route_unlock_node(rn
);
2167 vty_show_ip_route_detail(vty
, rn
, 0);
2169 route_unlock_node(rn
);
2175 DEFUN (show_ipv6_route_vrf_all_summary
,
2176 show_ipv6_route_vrf_all_summary_cmd
,
2177 "show ipv6 route vrf all summary",
2180 "IPv6 routing table\n"
2181 VRF_ALL_CMD_HELP_STR
2182 "Summary of all IPv6 routes\n")
2185 struct zebra_vrf
*zvrf
;
2187 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2188 if ((zvrf
= vrf
->info
) != NULL
)
2189 vty_show_ip_route_summary(vty
,
2190 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2195 DEFUN (show_ipv6_mroute_vrf_all
,
2196 show_ipv6_mroute_vrf_all_cmd
,
2197 "show ipv6 mroute vrf all",
2200 "IPv6 Multicast routing table\n"
2201 VRF_ALL_CMD_HELP_STR
)
2203 struct route_table
*table
;
2204 struct route_node
*rn
;
2205 struct route_entry
*re
;
2207 struct zebra_vrf
*zvrf
;
2210 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2212 if ((zvrf
= vrf
->info
) == NULL
2213 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2216 /* Show all IPv6 route. */
2217 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2218 RNODE_FOREACH_RE(rn
, re
)
2221 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2224 vty_show_ip_route(vty
, rn
, re
, NULL
);
2230 DEFUN (show_ipv6_route_vrf_all_summary_prefix
,
2231 show_ipv6_route_vrf_all_summary_prefix_cmd
,
2232 "show ipv6 route vrf all summary prefix",
2235 "IPv6 routing table\n"
2236 VRF_ALL_CMD_HELP_STR
2237 "Summary of all IPv6 routes\n"
2241 struct zebra_vrf
*zvrf
;
2243 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2244 if ((zvrf
= vrf
->info
) != NULL
)
2245 vty_show_ip_route_summary_prefix(
2246 vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2251 DEFUN (allow_external_route_update
,
2252 allow_external_route_update_cmd
,
2253 "allow-external-route-update",
2254 "Allow FRR routes to be overwritten by external processes\n")
2261 DEFUN (no_allow_external_route_update
,
2262 no_allow_external_route_update_cmd
,
2263 "no allow-external-route-update",
2265 "Allow FRR routes to be overwritten by external processes\n")
2280 struct zebra_vrf
*zvrf
;
2282 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2284 if (!(zvrf
= vrf
->info
))
2289 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2290 if (zvrf_id(zvrf
) == VRF_UNKNOWN
)
2291 vty_out(vty
, "inactive");
2293 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2301 DEFUN (show_evpn_vni
,
2303 "show evpn vni [json]",
2306 "VxLAN information\n"
2307 "JavaScript Object Notation\n")
2309 struct zebra_vrf
*zvrf
;
2310 u_char uj
= use_json(argc
, argv
);
2312 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2313 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2317 DEFUN (show_evpn_vni_vni
,
2318 show_evpn_vni_vni_cmd
,
2319 "show evpn vni " CMD_VNI_RANGE
"[json]",
2322 "VxLAN Network Identifier\n"
2324 "JavaScript Object Notation\n")
2326 struct zebra_vrf
*zvrf
;
2328 u_char uj
= use_json(argc
, argv
);
2330 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2331 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2332 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2336 DEFUN (show_evpn_mac_vni
,
2337 show_evpn_mac_vni_cmd
,
2338 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2342 "VxLAN Network Identifier\n"
2344 "JavaScript Object Notation\n")
2346 struct zebra_vrf
*zvrf
;
2348 u_char uj
= use_json(argc
, argv
);
2350 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2351 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2352 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2356 DEFUN (show_evpn_mac_vni_all
,
2357 show_evpn_mac_vni_all_cmd
,
2358 "show evpn mac vni all [json]",
2362 "VxLAN Network Identifier\n"
2364 "JavaScript Object Notation\n")
2366 struct zebra_vrf
*zvrf
;
2367 u_char uj
= use_json(argc
, argv
);
2369 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2370 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
2374 DEFUN (show_evpn_mac_vni_all_vtep
,
2375 show_evpn_mac_vni_all_vtep_cmd
,
2376 "show evpn mac vni all vtep A.B.C.D [json]",
2380 "VxLAN Network Identifier\n"
2383 "Remote VTEP IP address\n"
2384 "JavaScript Object Notation\n")
2386 struct zebra_vrf
*zvrf
;
2387 struct in_addr vtep_ip
;
2388 u_char uj
= use_json(argc
, argv
);
2390 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2392 vty_out(vty
, "%% Malformed VTEP IP address\n");
2395 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2396 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2402 DEFUN (show_evpn_mac_vni_mac
,
2403 show_evpn_mac_vni_mac_cmd
,
2404 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2408 "VxLAN Network Identifier\n"
2411 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2413 struct zebra_vrf
*zvrf
;
2417 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2418 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2419 vty_out(vty
, "%% Malformed MAC address");
2422 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2423 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2427 DEFUN (show_evpn_mac_vni_vtep
,
2428 show_evpn_mac_vni_vtep_cmd
,
2429 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2433 "VxLAN Network Identifier\n"
2436 "Remote VTEP IP address\n"
2437 "JavaScript Object Notation\n")
2439 struct zebra_vrf
*zvrf
;
2441 struct in_addr vtep_ip
;
2442 u_char uj
= use_json(argc
, argv
);
2444 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2445 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2447 vty_out(vty
, "%% Malformed VTEP IP address\n");
2451 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2452 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2456 DEFUN (show_evpn_neigh_vni
,
2457 show_evpn_neigh_vni_cmd
,
2458 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2461 "ARP and ND cache\n"
2462 "VxLAN Network Identifier\n"
2464 "JavaScript Object Notation\n")
2466 struct zebra_vrf
*zvrf
;
2468 u_char uj
= use_json(argc
, argv
);
2470 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2471 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2472 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2476 DEFUN (show_evpn_neigh_vni_all
,
2477 show_evpn_neigh_vni_all_cmd
,
2478 "show evpn arp-cache vni all [json]",
2481 "ARP and ND cache\n"
2482 "VxLAN Network Identifier\n"
2484 "JavaScript Object Notation\n")
2486 struct zebra_vrf
*zvrf
;
2487 u_char uj
= use_json(argc
, argv
);
2489 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2490 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2494 DEFUN (show_evpn_neigh_vni_neigh
,
2495 show_evpn_neigh_vni_neigh_cmd
,
2496 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2499 "ARP and ND cache\n"
2500 "VxLAN Network Identifier\n"
2503 "Neighbor address (IPv4 or IPv6 address)\n"
2504 "JavaScript Object Notation\n")
2506 struct zebra_vrf
*zvrf
;
2509 u_char uj
= use_json(argc
, argv
);
2511 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2512 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2514 vty_out(vty
, "%% Malformed Neighbor address\n");
2517 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2518 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2522 DEFUN (show_evpn_neigh_vni_vtep
,
2523 show_evpn_neigh_vni_vtep_cmd
,
2524 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2527 "ARP and ND cache\n"
2528 "VxLAN Network Identifier\n"
2531 "Remote VTEP IP address\n"
2532 "JavaScript Object Notation\n")
2534 struct zebra_vrf
*zvrf
;
2536 struct in_addr vtep_ip
;
2537 u_char uj
= use_json(argc
, argv
);
2539 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2540 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2542 vty_out(vty
, "%% Malformed VTEP IP address\n");
2546 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2547 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2551 /* Static ip route configuration write function. */
2552 static int zebra_ip_config(struct vty
*vty
)
2556 write
+= static_config(vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
2557 write
+= static_config(vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
2558 write
+= static_config(vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
2560 write
+= zebra_import_table_config(vty
);
2564 DEFUN (ip_zebra_import_table_distance
,
2565 ip_zebra_import_table_distance_cmd
,
2566 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2568 "import routes from non-main kernel table\n"
2569 "kernel routing table id\n"
2570 "Distance for imported routes\n"
2571 "Default distance value\n"
2572 "route-map for filtering\n"
2575 u_int32_t table_id
= 0;
2577 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2578 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2580 strmatch(argv
[argc
- 2]->text
, "route-map")
2581 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2585 if (argc
== 7 || (argc
== 5 && !rmap
))
2586 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2588 if (!is_zebra_valid_kernel_table(table_id
)) {
2590 "Invalid routing table ID, %d. Must be in range 1-252\n",
2595 if (is_zebra_main_routing_table(table_id
)) {
2597 "Invalid routing table ID, %d. Must be non-default table\n",
2602 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2604 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2609 DEFUN (no_ip_zebra_import_table
,
2610 no_ip_zebra_import_table_cmd
,
2611 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2614 "import routes from non-main kernel table\n"
2615 "kernel routing table id\n"
2616 "Distance for imported routes\n"
2617 "Default distance value\n"
2618 "route-map for filtering\n"
2621 u_int32_t table_id
= 0;
2622 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2624 if (!is_zebra_valid_kernel_table(table_id
)) {
2626 "Invalid routing table ID. Must be in range 1-252\n");
2630 if (is_zebra_main_routing_table(table_id
)) {
2632 "Invalid routing table ID, %d. Must be non-default table\n",
2637 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2640 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2643 static int config_write_protocol(struct vty
*vty
)
2646 vty_out(vty
, "allow-external-route-update\n");
2648 if (zebra_rnh_ip_default_route
)
2649 vty_out(vty
, "ip nht resolve-via-default\n");
2651 if (zebra_rnh_ipv6_default_route
)
2652 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2654 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2656 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2657 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2658 ipv4_multicast_mode
== MCAST_URIB_ONLY
2660 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2662 : ipv4_multicast_mode
2663 == MCAST_MIX_MRIB_FIRST
2665 : ipv4_multicast_mode
2666 == MCAST_MIX_DISTANCE
2670 zebra_routemap_config_write_protocol(vty
);
2675 /* IP node for static routes. */
2676 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2677 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2680 void zebra_vty_init(void)
2682 install_node(&ip_node
, zebra_ip_config
);
2683 install_node(&protocol_node
, config_write_protocol
);
2685 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2686 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2687 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
2688 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2689 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2690 install_element(CONFIG_NODE
, &ip_route_cmd
);
2691 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2692 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2694 install_element(VIEW_NODE
, &show_vrf_cmd
);
2695 install_element(VIEW_NODE
, &show_ip_route_cmd
);
2696 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2697 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2698 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2699 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2700 install_element(VIEW_NODE
, &show_ip_route_addr_cmd
);
2701 install_element(VIEW_NODE
, &show_ip_route_prefix_cmd
);
2702 install_element(VIEW_NODE
, &show_ip_route_summary_cmd
);
2703 install_element(VIEW_NODE
, &show_ip_route_summary_prefix_cmd
);
2705 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2706 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2708 install_element(VIEW_NODE
, &show_ip_route_vrf_all_addr_cmd
);
2709 install_element(VIEW_NODE
, &show_ip_route_vrf_all_prefix_cmd
);
2710 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_cmd
);
2711 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_prefix_cmd
);
2713 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
2714 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2715 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2716 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2717 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2718 install_element(VIEW_NODE
, &show_ipv6_route_cmd
);
2719 install_element(VIEW_NODE
, &show_ipv6_route_summary_cmd
);
2720 install_element(VIEW_NODE
, &show_ipv6_route_summary_prefix_cmd
);
2721 install_element(VIEW_NODE
, &show_ipv6_route_addr_cmd
);
2722 install_element(VIEW_NODE
, &show_ipv6_route_prefix_cmd
);
2723 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2725 /* Commands for VRF */
2726 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_cmd
);
2727 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_prefix_cmd
);
2728 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_addr_cmd
);
2729 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_prefix_cmd
);
2731 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2733 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2734 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2735 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2736 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2737 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2738 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2739 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2740 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2741 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2742 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2743 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);