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 /* VNI range as per RFC 7432 */
59 #define CMD_VNI_RANGE "(1-16777215)"
61 /* General function for static route. */
62 static int zebra_static_route(struct vty
*vty
, afi_t afi
, safi_t safi
,
63 const char *negate
, const char *dest_str
,
64 const char *mask_str
, const char *src_str
,
65 const char *gate_str
, const char *ifname
,
66 const char *flag_str
, const char *tag_str
,
67 const char *distance_str
, const char *vrf_id_str
,
68 const char *label_str
)
73 struct prefix_ipv6
*src_p
= NULL
;
75 union g_addr
*gatep
= NULL
;
79 struct zebra_vrf
*zvrf
;
81 struct static_nh_label snh_label
;
83 ret
= str2prefix(dest_str
, &p
);
85 vty_out(vty
, "%% Malformed address\n");
86 return CMD_WARNING_CONFIG_FAILED
;
91 /* Cisco like mask notation. */
93 ret
= inet_aton(mask_str
, &mask
);
95 vty_out(vty
, "%% Malformed address\n");
96 return CMD_WARNING_CONFIG_FAILED
;
98 p
.prefixlen
= ip_masklen(mask
);
102 /* srcdest routing */
104 ret
= str2prefix(src_str
, &src
);
105 if (ret
<= 0 || src
.family
!= AF_INET6
) {
106 vty_out(vty
, "%% Malformed source address\n");
107 return CMD_WARNING_CONFIG_FAILED
;
109 src_p
= (struct prefix_ipv6
*)&src
;
116 /* Apply mask for given prefix. */
119 /* Administrative distance. */
121 distance
= atoi(distance_str
);
123 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
127 tag
= strtoul(tag_str
, NULL
, 10);
130 zvrf
= zebra_vrf_lookup_by_name(vrf_id_str
);
133 vty_out(vty
, "%% vrf %s is not defined\n", vrf_id_str
);
134 return CMD_WARNING_CONFIG_FAILED
;
138 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
142 "%% MPLS not turned on in kernel, ignoring command\n");
143 return CMD_WARNING_CONFIG_FAILED
;
145 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
150 vty_out(vty
, "%% Malformed label(s)\n");
154 "%% Cannot use reserved label(s) (%d-%d)\n",
155 MPLS_MIN_RESERVED_LABEL
,
156 MPLS_MAX_RESERVED_LABEL
);
160 "%% Too many labels. Enter %d or fewer\n",
164 return CMD_WARNING_CONFIG_FAILED
;
168 /* Null0 static route. */
170 && (strncasecmp(ifname
, "Null0", strlen(ifname
)) == 0)) {
172 vty_out(vty
, "%% can not have flag %s with Null0\n",
174 return CMD_WARNING_CONFIG_FAILED
;
176 SET_FLAG(flag
, ZEBRA_FLAG_BLACKHOLE
);
182 switch (flag_str
[0]) {
185 SET_FLAG(flag
, ZEBRA_FLAG_REJECT
);
189 SET_FLAG(flag
, ZEBRA_FLAG_BLACKHOLE
);
192 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
193 return CMD_WARNING_CONFIG_FAILED
;
198 if (inet_pton(afi2family(afi
), gate_str
, &gate
) != 1) {
199 vty_out(vty
, "%% Malformed nexthop address %s\n",
201 return CMD_WARNING_CONFIG_FAILED
;
206 if (gate_str
== NULL
&& ifname
== NULL
)
207 type
= STATIC_BLACKHOLE
;
208 else if (gate_str
&& ifname
) {
210 type
= STATIC_IPV4_GATEWAY_IFNAME
;
212 type
= STATIC_IPV6_GATEWAY_IFNAME
;
214 type
= STATIC_IFNAME
;
217 type
= STATIC_IPV4_GATEWAY
;
219 type
= STATIC_IPV6_GATEWAY
;
223 static_add_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
224 flag
, tag
, distance
, zvrf
, &snh_label
);
226 static_delete_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
227 tag
, distance
, zvrf
, &snh_label
);
232 /* Static unicast routes for multicast RPF lookup. */
233 DEFPY (ip_mroute_dist
,
235 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
238 "Configure static unicast route into MRIB for multicast RPF lookup\n"
239 "IP destination prefix (e.g. 10.0.0.0/8)\n"
241 "Nexthop interface name\n"
244 return zebra_static_route(vty
, AFI_IP
, SAFI_MULTICAST
, no
, prefix_str
,
245 NULL
, NULL
, gate_str
, ifname
, NULL
, NULL
,
246 distance_str
, NULL
, NULL
);
249 DEFUN (ip_multicast_mode
,
250 ip_multicast_mode_cmd
,
251 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
253 "Multicast options\n"
254 "RPF lookup behavior\n"
255 "Lookup in unicast RIB only\n"
256 "Lookup in multicast RIB only\n"
257 "Try multicast RIB first, fall back to unicast RIB\n"
258 "Lookup both, use entry with lower distance\n"
259 "Lookup both, use entry with longer prefix\n")
261 char *mode
= argv
[3]->text
;
263 if (strmatch(mode
, "urib-only"))
264 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
265 else if (strmatch(mode
, "mrib-only"))
266 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
267 else if (strmatch(mode
, "mrib-then-urib"))
268 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
269 else if (strmatch(mode
, "lower-distance"))
270 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
271 else if (strmatch(mode
, "longer-prefix"))
272 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
274 vty_out(vty
, "Invalid mode specified\n");
275 return CMD_WARNING_CONFIG_FAILED
;
281 DEFUN (no_ip_multicast_mode
,
282 no_ip_multicast_mode_cmd
,
283 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
286 "Multicast options\n"
287 "RPF lookup behavior\n"
288 "Lookup in unicast RIB only\n"
289 "Lookup in multicast RIB only\n"
290 "Try multicast RIB first, fall back to unicast RIB\n"
291 "Lookup both, use entry with lower distance\n"
292 "Lookup both, use entry with longer prefix\n")
294 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
301 "show ip rpf [json]",
304 "Display RPF information for multicast source\n"
307 int uj
= use_json(argc
, argv
);
308 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
309 false, uj
, 0, NULL
, false, -1, 0);
312 DEFUN (show_ip_rpf_addr
,
313 show_ip_rpf_addr_cmd
,
314 "show ip rpf A.B.C.D",
317 "Display RPF information for multicast source\n"
318 "IP multicast source address (e.g. 10.0.0.0)\n")
322 struct route_node
*rn
;
323 struct route_entry
*re
;
326 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
328 vty_out(vty
, "%% Malformed address\n");
332 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
335 vty_show_ip_route_detail(vty
, rn
, 1);
337 vty_out(vty
, "%% No match for RPF lookup\n");
342 /* Static route configuration. */
346 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
348 {A.B.C.D$gate|INTERFACE$ifname}\
350 |<reject|blackhole>$flag\
360 "Establish static routes\n"
361 "IP destination prefix (e.g. 10.0.0.0/8)\n"
362 "IP destination prefix\n"
363 "IP destination prefix mask\n"
364 "IP gateway address\n"
365 "IP gateway interface name\n"
367 "Emit an ICMP unreachable when matched\n"
368 "Silently discard pkts when matched\n"
369 "Set tag for this route\n"
371 "Distance value for this route\n"
375 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
376 mask_str
, NULL
, gate_str
, ifname
, flag
,
377 tag_str
, distance_str
, vrf
, label
);
381 /* New RIB. Detailed information for IPv4 route. */
382 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
385 struct route_entry
*re
;
386 struct nexthop
*nexthop
;
387 char buf
[SRCDEST2STR_BUFFER
];
388 struct zebra_vrf
*zvrf
;
390 RNODE_FOREACH_RE(rn
, re
)
392 const char *mcast_info
= "";
394 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
395 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
396 ? " using Multicast RIB"
397 : " using Unicast RIB";
400 vty_out(vty
, "Routing entry for %s%s\n",
401 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
402 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
404 vty_out(vty
, "[%d]", re
->instance
);
406 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
409 vty_out(vty
, ", tag %d", re
->tag
);
411 vty_out(vty
, ", mtu %u", re
->mtu
);
412 if (re
->vrf_id
!= VRF_DEFAULT
) {
413 zvrf
= vrf_info_lookup(re
->vrf_id
);
414 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
416 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
417 vty_out(vty
, ", best");
419 vty_out(vty
, ", refcnt %ld", re
->refcnt
);
420 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
421 vty_out(vty
, ", blackhole");
422 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
423 vty_out(vty
, ", reject");
426 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
427 || re
->type
== ZEBRA_ROUTE_ISIS
428 || re
->type
== ZEBRA_ROUTE_NHRP
429 || re
->type
== ZEBRA_ROUTE_TABLE
430 || re
->type
== ZEBRA_ROUTE_BGP
) {
435 uptime
-= re
->uptime
;
436 tm
= gmtime(&uptime
);
438 vty_out(vty
, " Last update ");
440 if (uptime
< ONE_DAY_SECOND
)
441 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
442 tm
->tm_min
, tm
->tm_sec
);
443 else if (uptime
< ONE_WEEK_SECOND
)
444 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
445 tm
->tm_hour
, tm
->tm_min
);
447 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
448 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
450 vty_out(vty
, " ago\n");
453 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
456 vty_out(vty
, " %c%s",
457 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
460 nexthop
->rparent
? " " : "");
462 switch (nexthop
->type
) {
463 case NEXTHOP_TYPE_IPV4
:
464 case NEXTHOP_TYPE_IPV4_IFINDEX
:
466 inet_ntoa(nexthop
->gate
.ipv4
));
467 if (nexthop
->ifindex
)
468 vty_out(vty
, ", via %s",
469 ifindex2ifname(nexthop
->ifindex
,
472 case NEXTHOP_TYPE_IPV6
:
473 case NEXTHOP_TYPE_IPV6_IFINDEX
:
475 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
477 if (nexthop
->ifindex
)
478 vty_out(vty
, ", via %s",
479 ifindex2ifname(nexthop
->ifindex
,
482 case NEXTHOP_TYPE_IFINDEX
:
483 vty_out(vty
, " directly connected, %s",
484 ifindex2ifname(nexthop
->ifindex
,
487 case NEXTHOP_TYPE_BLACKHOLE
:
488 vty_out(vty
, " directly connected, Null0");
493 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
494 vty_out(vty
, " inactive");
496 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
497 vty_out(vty
, " onlink");
499 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
500 vty_out(vty
, " (recursive)");
502 switch (nexthop
->type
) {
503 case NEXTHOP_TYPE_IPV4
:
504 case NEXTHOP_TYPE_IPV4_IFINDEX
:
505 if (nexthop
->src
.ipv4
.s_addr
) {
506 if (inet_ntop(AF_INET
,
508 addrstr
, sizeof addrstr
))
509 vty_out(vty
, ", src %s",
513 case NEXTHOP_TYPE_IPV6
:
514 case NEXTHOP_TYPE_IPV6_IFINDEX
:
515 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
517 if (inet_ntop(AF_INET6
,
519 addrstr
, sizeof addrstr
))
520 vty_out(vty
, ", src %s",
529 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
531 /* Label information */
532 if (nexthop
->nh_label
533 && nexthop
->nh_label
->num_labels
) {
534 vty_out(vty
, ", label %s",
536 nexthop
->nh_label
->num_labels
,
537 nexthop
->nh_label
->label
, buf
,
547 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
548 struct route_entry
*re
, json_object
*json
)
550 struct nexthop
*nexthop
;
552 char buf
[SRCDEST2STR_BUFFER
];
553 json_object
*json_nexthops
= NULL
;
554 json_object
*json_nexthop
= NULL
;
555 json_object
*json_route
= NULL
;
556 json_object
*json_labels
= NULL
;
559 json_route
= json_object_new_object();
560 json_nexthops
= json_object_new_array();
562 json_object_string_add(json_route
, "prefix",
563 srcdest_rnode2str(rn
, buf
, sizeof buf
));
564 json_object_string_add(json_route
, "protocol",
565 zebra_route_string(re
->type
));
568 json_object_int_add(json_route
, "instance",
572 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
574 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
575 json_object_boolean_true_add(json_route
, "selected");
577 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
578 json_object_int_add(json_route
, "distance",
580 json_object_int_add(json_route
, "metric", re
->metric
);
583 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
584 json_object_boolean_true_add(json_route
, "blackhole");
586 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
587 json_object_boolean_true_add(json_route
, "reject");
589 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
590 || re
->type
== ZEBRA_ROUTE_ISIS
591 || re
->type
== ZEBRA_ROUTE_NHRP
592 || re
->type
== ZEBRA_ROUTE_TABLE
593 || re
->type
== ZEBRA_ROUTE_BGP
) {
598 uptime
-= re
->uptime
;
599 tm
= gmtime(&uptime
);
601 if (uptime
< ONE_DAY_SECOND
)
602 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
603 tm
->tm_min
, tm
->tm_sec
);
604 else if (uptime
< ONE_WEEK_SECOND
)
605 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
606 tm
->tm_hour
, tm
->tm_min
);
608 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
609 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
612 json_object_string_add(json_route
, "uptime", buf
);
615 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
616 json_nexthop
= json_object_new_object();
618 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
619 json_object_boolean_true_add(json_nexthop
,
622 switch (nexthop
->type
) {
623 case NEXTHOP_TYPE_IPV4
:
624 case NEXTHOP_TYPE_IPV4_IFINDEX
:
625 json_object_string_add(
627 inet_ntoa(nexthop
->gate
.ipv4
));
628 json_object_string_add(json_nexthop
, "afi",
631 if (nexthop
->ifindex
) {
632 json_object_int_add(json_nexthop
,
635 json_object_string_add(
636 json_nexthop
, "interfaceName",
637 ifindex2ifname(nexthop
->ifindex
,
641 case NEXTHOP_TYPE_IPV6
:
642 case NEXTHOP_TYPE_IPV6_IFINDEX
:
643 json_object_string_add(
645 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
647 json_object_string_add(json_nexthop
, "afi",
650 if (nexthop
->ifindex
) {
651 json_object_int_add(json_nexthop
,
654 json_object_string_add(
655 json_nexthop
, "interfaceName",
656 ifindex2ifname(nexthop
->ifindex
,
661 case NEXTHOP_TYPE_IFINDEX
:
662 json_object_boolean_true_add(
663 json_nexthop
, "directlyConnected");
664 json_object_int_add(json_nexthop
,
667 json_object_string_add(
668 json_nexthop
, "interfaceName",
669 ifindex2ifname(nexthop
->ifindex
,
672 case NEXTHOP_TYPE_BLACKHOLE
:
673 json_object_boolean_true_add(json_nexthop
,
680 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
681 json_object_boolean_true_add(json_nexthop
,
684 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
685 json_object_boolean_true_add(json_nexthop
,
688 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
689 json_object_boolean_true_add(json_nexthop
,
692 switch (nexthop
->type
) {
693 case NEXTHOP_TYPE_IPV4
:
694 case NEXTHOP_TYPE_IPV4_IFINDEX
:
695 if (nexthop
->src
.ipv4
.s_addr
) {
696 if (inet_ntop(AF_INET
,
697 &nexthop
->src
.ipv4
, buf
,
699 json_object_string_add(
700 json_nexthop
, "source",
704 case NEXTHOP_TYPE_IPV6
:
705 case NEXTHOP_TYPE_IPV6_IFINDEX
:
706 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
708 if (inet_ntop(AF_INET6
,
709 &nexthop
->src
.ipv6
, buf
,
711 json_object_string_add(
712 json_nexthop
, "source",
720 if (nexthop
->nh_label
721 && nexthop
->nh_label
->num_labels
) {
722 json_labels
= json_object_new_array();
724 for (int label_index
= 0;
726 < nexthop
->nh_label
->num_labels
;
728 json_object_array_add(
731 nexthop
->nh_label
->label
734 json_object_object_add(json_nexthop
, "labels",
738 json_object_array_add(json_nexthops
, json_nexthop
);
741 json_object_object_add(json_route
, "nexthops", json_nexthops
);
742 json_object_array_add(json
, json_route
);
746 /* Nexthop information. */
747 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
748 if (nexthop
== re
->nexthop
) {
749 /* Prefix information. */
750 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
752 len
+= vty_out(vty
, "[%d]", re
->instance
);
755 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
758 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
761 srcdest_rnode2str(rn
, buf
, sizeof buf
));
763 /* Distance and metric display. */
764 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
765 len
+= vty_out(vty
, " [%d/%d]", re
->distance
,
768 vty_out(vty
, " %c%*c",
769 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
772 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
774 switch (nexthop
->type
) {
775 case NEXTHOP_TYPE_IPV4
:
776 case NEXTHOP_TYPE_IPV4_IFINDEX
:
777 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
778 if (nexthop
->ifindex
)
780 ifindex2ifname(nexthop
->ifindex
,
783 case NEXTHOP_TYPE_IPV6
:
784 case NEXTHOP_TYPE_IPV6_IFINDEX
:
785 vty_out(vty
, " via %s",
786 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
788 if (nexthop
->ifindex
)
790 ifindex2ifname(nexthop
->ifindex
,
794 case NEXTHOP_TYPE_IFINDEX
:
795 vty_out(vty
, " is directly connected, %s",
796 ifindex2ifname(nexthop
->ifindex
, re
->vrf_id
));
798 case NEXTHOP_TYPE_BLACKHOLE
:
799 vty_out(vty
, " is directly connected, Null0");
804 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
805 vty_out(vty
, " inactive");
807 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
808 vty_out(vty
, " onlink");
810 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
811 vty_out(vty
, " (recursive)");
813 switch (nexthop
->type
) {
814 case NEXTHOP_TYPE_IPV4
:
815 case NEXTHOP_TYPE_IPV4_IFINDEX
:
816 if (nexthop
->src
.ipv4
.s_addr
) {
817 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
819 vty_out(vty
, ", src %s", buf
);
822 case NEXTHOP_TYPE_IPV6
:
823 case NEXTHOP_TYPE_IPV6_IFINDEX
:
824 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
825 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
827 vty_out(vty
, ", src %s", buf
);
834 /* Label information */
835 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
836 vty_out(vty
, ", label %s",
837 mpls_label2str(nexthop
->nh_label
->num_labels
,
838 nexthop
->nh_label
->label
, buf
,
842 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
843 vty_out(vty
, ", bh");
844 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
845 vty_out(vty
, ", rej");
847 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
848 || re
->type
== ZEBRA_ROUTE_ISIS
849 || re
->type
== ZEBRA_ROUTE_NHRP
850 || re
->type
== ZEBRA_ROUTE_TABLE
851 || re
->type
== ZEBRA_ROUTE_BGP
) {
856 uptime
-= re
->uptime
;
857 tm
= gmtime(&uptime
);
859 if (uptime
< ONE_DAY_SECOND
)
860 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
861 tm
->tm_min
, tm
->tm_sec
);
862 else if (uptime
< ONE_WEEK_SECOND
)
863 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
864 tm
->tm_hour
, tm
->tm_min
);
866 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
867 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
874 static bool use_fib(struct cmd_token
*token
)
876 return strncmp(token
->arg
, "route", strlen(token
->arg
));
879 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
880 safi_t safi
, bool use_fib
, u_char use_json
,
881 route_tag_t tag
, struct prefix
*longer_prefix_p
,
882 bool supernets_only
, int type
,
883 u_short ospf_instance_id
)
885 struct route_table
*table
;
886 struct route_node
*rn
;
887 struct route_entry
*re
;
889 struct zebra_vrf
*zvrf
= NULL
;
891 json_object
*json
= NULL
;
892 json_object
*json_prefix
= NULL
;
895 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
897 vty_out(vty
, "{}\n");
899 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
903 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
905 vty_out(vty
, "{}\n");
907 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
911 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
914 vty_out(vty
, "{}\n");
919 json
= json_object_new_object();
921 /* Show all routes. */
922 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
923 RNODE_FOREACH_RE(rn
, re
)
926 && !CHECK_FLAG(re
->status
,
927 ROUTE_ENTRY_SELECTED_FIB
))
930 if (tag
&& re
->tag
!= tag
)
934 && !prefix_match(longer_prefix_p
, &rn
->p
))
937 /* This can only be true when the afi is IPv4 */
938 if (supernets_only
) {
939 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
941 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
944 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
947 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
951 if (type
&& re
->type
!= type
)
955 && (re
->type
!= ZEBRA_ROUTE_OSPF
956 || re
->instance
!= ospf_instance_id
))
961 json_prefix
= json_object_new_array();
966 SHOW_ROUTE_V4_HEADER
);
969 SHOW_ROUTE_V6_HEADER
);
971 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
972 vty_out(vty
, "\nVRF %s:\n",
979 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
983 prefix2str(&rn
->p
, buf
, sizeof buf
);
984 json_object_object_add(json
, buf
, json_prefix
);
990 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
991 json
, JSON_C_TO_STRING_PRETTY
));
992 json_object_free(json
);
1000 "show ip nht [vrf NAME]",
1003 "IP nexthop tracking table\n"
1007 vrf_id_t vrf_id
= VRF_DEFAULT
;
1010 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1012 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1017 DEFUN (show_ip_nht_vrf_all
,
1018 show_ip_nht_vrf_all_cmd
,
1019 "show ip nht vrf all",
1022 "IP nexthop tracking table\n"
1023 VRF_ALL_CMD_HELP_STR
)
1026 struct zebra_vrf
*zvrf
;
1028 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1029 if ((zvrf
= vrf
->info
) != NULL
) {
1030 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1031 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1038 DEFUN (show_ipv6_nht
,
1040 "show ipv6 nht [vrf NAME]",
1043 "IPv6 nexthop tracking table\n"
1047 vrf_id_t vrf_id
= VRF_DEFAULT
;
1050 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1052 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1057 DEFUN (show_ipv6_nht_vrf_all
,
1058 show_ipv6_nht_vrf_all_cmd
,
1059 "show ipv6 nht vrf all",
1062 "IPv6 nexthop tracking table\n"
1063 VRF_ALL_CMD_HELP_STR
)
1066 struct zebra_vrf
*zvrf
;
1068 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1069 if ((zvrf
= vrf
->info
) != NULL
) {
1070 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1071 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1078 DEFUN (ip_nht_default_route
,
1079 ip_nht_default_route_cmd
,
1080 "ip nht resolve-via-default",
1082 "Filter Next Hop tracking route resolution\n"
1083 "Resolve via default route\n")
1085 if (zebra_rnh_ip_default_route
)
1088 zebra_rnh_ip_default_route
= 1;
1089 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1093 DEFUN (no_ip_nht_default_route
,
1094 no_ip_nht_default_route_cmd
,
1095 "no ip nht resolve-via-default",
1098 "Filter Next Hop tracking route resolution\n"
1099 "Resolve via default route\n")
1101 if (!zebra_rnh_ip_default_route
)
1104 zebra_rnh_ip_default_route
= 0;
1105 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1109 DEFUN (ipv6_nht_default_route
,
1110 ipv6_nht_default_route_cmd
,
1111 "ipv6 nht resolve-via-default",
1113 "Filter Next Hop tracking route resolution\n"
1114 "Resolve via default route\n")
1116 if (zebra_rnh_ipv6_default_route
)
1119 zebra_rnh_ipv6_default_route
= 1;
1120 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1124 DEFUN (no_ipv6_nht_default_route
,
1125 no_ipv6_nht_default_route_cmd
,
1126 "no ipv6 nht resolve-via-default",
1129 "Filter Next Hop tracking route resolution\n"
1130 "Resolve via default route\n")
1132 if (!zebra_rnh_ipv6_default_route
)
1135 zebra_rnh_ipv6_default_route
= 0;
1136 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1140 DEFUN (show_ip_route
,
1142 "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]",
1145 "IP forwarding table\n"
1146 "IP routing table\n"
1148 "Show only routes with tag\n"
1150 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1151 "Show route matching the specified Network/Mask pair only\n"
1152 "Show supernet entries only\n"
1153 FRR_IP_REDIST_HELP_STR_ZEBRA
1154 "Open Shortest Path First (OSPFv2)\n"
1158 bool uf
= use_fib(argv
[2]);
1159 struct route_table
*table
;
1161 route_tag_t tag
= 0;
1162 vrf_id_t vrf_id
= VRF_DEFAULT
;
1164 struct zebra_vrf
*zvrf
;
1165 int uj
= use_json(argc
, argv
);
1168 bool longer_prefixes
= false;
1169 bool supernets_only
= false;
1171 u_short ospf_instance_id
= 0;
1173 if (argv_find(argv
, argc
, "vrf", &idx
)) {
1174 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
1177 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
1180 if (argv_find(argv
, argc
, "tag", &idx
))
1181 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
1183 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)) {
1184 str2prefix(argv
[idx
]->arg
, &p
);
1185 longer_prefixes
= true;
1188 else if (argv_find(argv
, argc
, "supernets_only", &idx
))
1189 supernets_only
= true;
1192 if (argv_find(argv
, argc
, "kernel", &idx
))
1193 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1194 else if (argv_find(argv
, argc
, "babel", &idx
))
1195 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1196 else if (argv_find(argv
, argc
, "connected", &idx
))
1197 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1198 else if (argv_find(argv
, argc
, "static", &idx
))
1199 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1200 else if (argv_find(argv
, argc
, "rip", &idx
))
1201 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1202 else if (argv_find(argv
, argc
, "ospf", &idx
))
1203 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1204 else if (argv_find(argv
, argc
, "isis", &idx
))
1205 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1206 else if (argv_find(argv
, argc
, "bgp", &idx
))
1207 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1208 else if (argv_find(argv
, argc
, "pim", &idx
))
1209 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1210 else if (argv_find(argv
, argc
, "eigrp", &idx
))
1211 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1212 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1213 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1214 else if (argv_find(argv
, argc
, "table", &idx
))
1215 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1216 else if (argv_find(argv
, argc
, "vnc", &idx
))
1217 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1219 if (argv_find(argv
, argc
, "(1-65535)", &idx
))
1220 ospf_instance_id
= strtoul(argv
[idx
]->arg
, NULL
, 10);
1223 vty_out(vty
, "Unknown route type\n");
1229 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1231 if ((zvrf
= vrf
->info
) == NULL
1232 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
1237 vty
, zvrf_name(zvrf
), AFI_IP
, SAFI_UNICAST
, uf
,
1238 uj
, tag
, longer_prefixes
? &p
: NULL
,
1239 supernets_only
, type
, ospf_instance_id
);
1242 vrf
= vrf_lookup_by_id(vrf_id
);
1243 do_show_ip_route(vty
, vrf
->name
, AFI_IP
, SAFI_UNICAST
, uf
, uj
,
1244 tag
, longer_prefixes
? &p
: NULL
,
1245 supernets_only
, type
, ospf_instance_id
);
1250 DEFUN (show_ip_route_addr
,
1251 show_ip_route_addr_cmd
,
1252 "show ip route [vrf NAME] A.B.C.D",
1255 "IP routing table\n"
1257 "Network in the IP routing table to display\n")
1260 struct prefix_ipv4 p
;
1261 struct route_table
*table
;
1262 struct route_node
*rn
;
1263 vrf_id_t vrf_id
= VRF_DEFAULT
;
1265 if (strmatch(argv
[3]->text
, "vrf")) {
1266 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1267 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1269 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1273 vty_out(vty
, "%% Malformed IPv4 address\n");
1277 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1281 rn
= route_node_match(table
, (struct prefix
*)&p
);
1283 vty_out(vty
, "%% Network not in table\n");
1287 vty_show_ip_route_detail(vty
, rn
, 0);
1289 route_unlock_node(rn
);
1294 DEFUN (show_ip_route_prefix
,
1295 show_ip_route_prefix_cmd
,
1296 "show ip route [vrf NAME] A.B.C.D/M",
1299 "IP routing table\n"
1301 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1304 struct prefix_ipv4 p
;
1305 struct route_table
*table
;
1306 struct route_node
*rn
;
1307 vrf_id_t vrf_id
= VRF_DEFAULT
;
1309 if (strmatch(argv
[3]->text
, "vrf")) {
1310 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1311 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1313 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1317 vty_out(vty
, "%% Malformed IPv4 address\n");
1321 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1325 rn
= route_node_match(table
, (struct prefix
*)&p
);
1326 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1327 vty_out(vty
, "%% Network not in table\n");
1331 vty_show_ip_route_detail(vty
, rn
, 0);
1333 route_unlock_node(rn
);
1339 static void vty_show_ip_route_summary(struct vty
*vty
,
1340 struct route_table
*table
)
1342 struct route_node
*rn
;
1343 struct route_entry
*re
;
1344 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1345 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1346 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1347 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1351 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1352 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1353 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1354 RNODE_FOREACH_RE(rn
, re
)
1356 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1357 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1359 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1361 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1363 rib_cnt
[re
->type
]++;
1365 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1366 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1369 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1371 fib_cnt
[re
->type
]++;
1375 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1376 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1378 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1379 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1380 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1381 if (i
== ZEBRA_ROUTE_BGP
) {
1382 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1383 rib_cnt
[ZEBRA_ROUTE_BGP
],
1384 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1385 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1386 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1387 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1389 vty_out(vty
, "%-20s %-20d %-20d \n",
1390 zebra_route_string(i
), rib_cnt
[i
],
1395 vty_out(vty
, "------\n");
1396 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1397 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1402 * Implementation of the ip route summary prefix command.
1404 * This command prints the primary prefixes that have been installed by various
1405 * protocols on the box.
1408 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1409 struct route_table
*table
)
1411 struct route_node
*rn
;
1412 struct route_entry
*re
;
1413 struct nexthop
*nexthop
;
1414 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1415 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1416 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1417 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1421 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1422 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1423 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1424 RNODE_FOREACH_RE(rn
, re
)
1428 * In case of ECMP, count only once.
1431 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1432 nexthop
= nexthop
->next
) {
1434 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1435 rib_cnt
[re
->type
]++;
1436 if (CHECK_FLAG(nexthop
->flags
,
1437 NEXTHOP_FLAG_FIB
)) {
1438 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1439 fib_cnt
[re
->type
]++;
1441 if (re
->type
== ZEBRA_ROUTE_BGP
1442 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1443 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1444 if (CHECK_FLAG(nexthop
->flags
,
1446 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1451 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1452 "Prefix Routes", "FIB",
1453 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1455 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1456 if (rib_cnt
[i
] > 0) {
1457 if (i
== ZEBRA_ROUTE_BGP
) {
1458 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1459 rib_cnt
[ZEBRA_ROUTE_BGP
]
1460 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1461 fib_cnt
[ZEBRA_ROUTE_BGP
]
1462 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1463 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1464 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1465 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1467 vty_out(vty
, "%-20s %-20d %-20d \n",
1468 zebra_route_string(i
), rib_cnt
[i
],
1473 vty_out(vty
, "------\n");
1474 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1475 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1479 /* Show route summary. */
1480 DEFUN (show_ip_route_summary
,
1481 show_ip_route_summary_cmd
,
1482 "show ip route [vrf NAME] summary",
1485 "IP routing table\n"
1487 "Summary of all routes\n")
1489 struct route_table
*table
;
1490 vrf_id_t vrf_id
= VRF_DEFAULT
;
1492 if (strmatch(argv
[3]->text
, "vrf"))
1493 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1495 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1499 vty_show_ip_route_summary(vty
, table
);
1504 /* Show route summary prefix. */
1505 DEFUN (show_ip_route_summary_prefix
,
1506 show_ip_route_summary_prefix_cmd
,
1507 "show ip route [vrf NAME] summary prefix",
1510 "IP routing table\n"
1512 "Summary of all routes\n"
1515 struct route_table
*table
;
1516 vrf_id_t vrf_id
= VRF_DEFAULT
;
1518 if (strmatch(argv
[3]->text
, "vrf"))
1519 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1521 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1525 vty_show_ip_route_summary_prefix(vty
, table
);
1531 DEFUN (show_ip_route_vrf_all_addr
,
1532 show_ip_route_vrf_all_addr_cmd
,
1533 "show ip route vrf all A.B.C.D",
1536 "IP routing table\n"
1537 VRF_ALL_CMD_HELP_STR
1538 "Network in the IP routing table to display\n")
1542 struct prefix_ipv4 p
;
1543 struct route_table
*table
;
1544 struct route_node
*rn
;
1546 struct zebra_vrf
*zvrf
;
1548 ret
= str2prefix_ipv4(argv
[idx_ipv4
]->arg
, &p
);
1550 vty_out(vty
, "%% Malformed IPv4 address\n");
1554 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1556 if ((zvrf
= vrf
->info
) == NULL
1557 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1560 rn
= route_node_match(table
, (struct prefix
*)&p
);
1564 vty_show_ip_route_detail(vty
, rn
, 0);
1566 route_unlock_node(rn
);
1572 DEFUN (show_ip_route_vrf_all_prefix
,
1573 show_ip_route_vrf_all_prefix_cmd
,
1574 "show ip route vrf all A.B.C.D/M",
1577 "IP routing table\n"
1578 VRF_ALL_CMD_HELP_STR
1579 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1581 int idx_ipv4_prefixlen
= 5;
1583 struct prefix_ipv4 p
;
1584 struct route_table
*table
;
1585 struct route_node
*rn
;
1587 struct zebra_vrf
*zvrf
;
1589 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
1591 vty_out(vty
, "%% Malformed IPv4 address\n");
1595 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1597 if ((zvrf
= vrf
->info
) == NULL
1598 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1601 rn
= route_node_match(table
, (struct prefix
*)&p
);
1604 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
1605 route_unlock_node(rn
);
1609 vty_show_ip_route_detail(vty
, rn
, 0);
1611 route_unlock_node(rn
);
1617 DEFUN (show_ip_route_vrf_all_summary
,
1618 show_ip_route_vrf_all_summary_cmd
,
1619 "show ip route vrf all summary ",
1622 "IP routing table\n"
1623 VRF_ALL_CMD_HELP_STR
1624 "Summary of all routes\n")
1627 struct zebra_vrf
*zvrf
;
1629 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1630 if ((zvrf
= vrf
->info
) != NULL
)
1631 vty_show_ip_route_summary(vty
,
1632 zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1637 DEFUN (show_ip_route_vrf_all_summary_prefix
,
1638 show_ip_route_vrf_all_summary_prefix_cmd
,
1639 "show ip route vrf all summary prefix",
1642 "IP routing table\n"
1643 VRF_ALL_CMD_HELP_STR
1644 "Summary of all routes\n"
1648 struct zebra_vrf
*zvrf
;
1650 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1651 if ((zvrf
= vrf
->info
) != NULL
)
1652 vty_show_ip_route_summary_prefix(
1653 vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1658 /* Write static route configuration. */
1659 static int static_config(struct vty
*vty
, afi_t afi
, safi_t safi
,
1662 struct route_node
*rn
;
1663 struct static_route
*si
;
1664 struct route_table
*stable
;
1666 struct zebra_vrf
*zvrf
;
1667 char buf
[SRCDEST2STR_BUFFER
];
1670 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1672 if (!(zvrf
= vrf
->info
))
1674 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1677 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1678 for (si
= rn
->info
; si
; si
= si
->next
) {
1679 vty_out(vty
, "%s %s", cmd
,
1680 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1683 case STATIC_IPV4_GATEWAY
:
1685 inet_ntoa(si
->addr
.ipv4
));
1687 case STATIC_IPV6_GATEWAY
:
1690 &si
->addr
.ipv6
, buf
,
1694 vty_out(vty
, " %s", si
->ifname
);
1696 /* blackhole and Null0 mean the same thing */
1697 case STATIC_BLACKHOLE
:
1698 if (CHECK_FLAG(si
->flags
, ZEBRA_FLAG_REJECT
))
1699 vty_out(vty
, " reject");
1701 vty_out(vty
, " Null0");
1703 case STATIC_IPV4_GATEWAY_IFNAME
:
1704 vty_out(vty
, " %s %s",
1706 &si
->addr
.ipv4
, buf
,
1708 ifindex2ifname(si
->ifindex
,
1711 case STATIC_IPV6_GATEWAY_IFNAME
:
1712 vty_out(vty
, " %s %s",
1714 &si
->addr
.ipv6
, buf
,
1716 ifindex2ifname(si
->ifindex
,
1721 /* flags are incompatible with STATIC_BLACKHOLE
1723 if (si
->type
!= STATIC_BLACKHOLE
) {
1724 if (CHECK_FLAG(si
->flags
,
1726 vty_out(vty
, " %s", "reject");
1728 if (CHECK_FLAG(si
->flags
,
1729 ZEBRA_FLAG_BLACKHOLE
))
1735 vty_out(vty
, " tag %" ROUTE_TAG_PRI
,
1739 != ZEBRA_STATIC_DISTANCE_DEFAULT
)
1740 vty_out(vty
, " %d", si
->distance
);
1742 if (si
->vrf_id
!= VRF_DEFAULT
)
1743 vty_out(vty
, " vrf %s",
1746 /* Label information */
1747 if (si
->snh_label
.num_labels
)
1748 vty_out(vty
, " label %s",
1752 si
->snh_label
.label
,
1753 buf
, sizeof buf
, 0));
1765 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
1767 {X:X::X:X$gate|INTERFACE$ifname}\
1769 |<reject|blackhole>$flag\
1779 "Establish static routes\n"
1780 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1781 "IPv6 source-dest route\n"
1782 "IPv6 source prefix\n"
1783 "IPv6 gateway address\n"
1784 "IPv6 gateway interface name\n"
1786 "Emit an ICMP unreachable when matched\n"
1787 "Silently discard pkts when matched\n"
1788 "Set tag for this route\n"
1790 "Distance value for this prefix\n"
1794 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1795 NULL
, from_str
, gate_str
, ifname
, flag
,
1796 tag_str
, distance_str
, vrf
, label
);
1799 DEFUN (show_ipv6_route
,
1800 show_ipv6_route_cmd
,
1801 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA
"] [json]",
1804 "IP forwarding table\n"
1805 "IP routing table\n"
1807 "Show only routes with tag\n"
1810 "Show route matching the specified Network/Mask pair only\n"
1811 FRR_IP6_REDIST_HELP_STR_ZEBRA
1814 bool uf
= use_fib(argv
[2]);
1815 struct route_table
*table
;
1817 route_tag_t tag
= 0;
1818 vrf_id_t vrf_id
= VRF_DEFAULT
;
1820 struct zebra_vrf
*zvrf
;
1821 int uj
= use_json(argc
, argv
);
1824 bool longer_prefixes
= false;
1825 bool supernets_only
= false;
1828 if (argv_find(argv
, argc
, "vrf", &idx
)) {
1829 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
1832 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
1835 if (argv_find(argv
, argc
, "tag", &idx
))
1836 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
1838 else if (argv_find(argv
, argc
, "X:X::X:X/M", &idx
)) {
1839 str2prefix(argv
[idx
]->arg
, &p
);
1840 longer_prefixes
= true;
1844 if (argv_find(argv
, argc
, "kernel", &idx
))
1845 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1846 else if (argv_find(argv
, argc
, "babel", &idx
))
1847 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1848 else if (argv_find(argv
, argc
, "connected", &idx
))
1849 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1850 else if (argv_find(argv
, argc
, "static", &idx
))
1851 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1852 else if (argv_find(argv
, argc
, "ripng", &idx
))
1853 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1854 else if (argv_find(argv
, argc
, "ospf6", &idx
))
1855 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1856 else if (argv_find(argv
, argc
, "isis", &idx
))
1857 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1858 else if (argv_find(argv
, argc
, "bgp", &idx
))
1859 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1860 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1861 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1862 else if (argv_find(argv
, argc
, "table", &idx
))
1863 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1864 else if (argv_find(argv
, argc
, "vnc", &idx
))
1865 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1868 vty_out(vty
, "Unknown route type\n");
1874 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1876 if ((zvrf
= vrf
->info
) == NULL
1877 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
])
1881 do_show_ip_route(vty
, zvrf_name(zvrf
), AFI_IP6
,
1882 SAFI_UNICAST
, uf
, uj
, tag
,
1883 longer_prefixes
? &p
: NULL
,
1884 supernets_only
, type
, 0);
1887 vrf
= vrf_lookup_by_id(vrf_id
);
1888 do_show_ip_route(vty
, vrf
->name
, AFI_IP6
, SAFI_UNICAST
, uf
, uj
,
1889 tag
, longer_prefixes
? &p
: NULL
,
1890 supernets_only
, type
, 0);
1895 DEFUN (show_ipv6_route_addr
,
1896 show_ipv6_route_addr_cmd
,
1897 "show ipv6 route [vrf NAME] X:X::X:X",
1900 "IPv6 routing table\n"
1905 struct prefix_ipv6 p
;
1906 struct route_table
*table
;
1907 struct route_node
*rn
;
1908 vrf_id_t vrf_id
= VRF_DEFAULT
;
1910 if (strmatch(argv
[3]->text
, "vrf")) {
1911 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1912 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1914 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1918 vty_out(vty
, "Malformed IPv6 address\n");
1922 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1926 rn
= route_node_match(table
, (struct prefix
*)&p
);
1928 vty_out(vty
, "%% Network not in table\n");
1932 vty_show_ip_route_detail(vty
, rn
, 0);
1934 route_unlock_node(rn
);
1939 DEFUN (show_ipv6_route_prefix
,
1940 show_ipv6_route_prefix_cmd
,
1941 "show ipv6 route [vrf NAME] X:X::X:X/M",
1944 "IPv6 routing table\n"
1949 struct prefix_ipv6 p
;
1950 struct route_table
*table
;
1951 struct route_node
*rn
;
1952 vrf_id_t vrf_id
= VRF_DEFAULT
;
1954 if (strmatch(argv
[3]->text
, "vrf")) {
1955 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1956 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1958 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1961 vty_out(vty
, "Malformed IPv6 prefix\n");
1965 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1969 rn
= route_node_match(table
, (struct prefix
*)&p
);
1970 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1971 vty_out(vty
, "%% Network not in table\n");
1975 vty_show_ip_route_detail(vty
, rn
, 0);
1977 route_unlock_node(rn
);
1983 /* Show route summary. */
1984 DEFUN (show_ipv6_route_summary
,
1985 show_ipv6_route_summary_cmd
,
1986 "show ipv6 route [vrf NAME] summary",
1989 "IPv6 routing table\n"
1991 "Summary of all IPv6 routes\n")
1993 struct route_table
*table
;
1994 vrf_id_t vrf_id
= VRF_DEFAULT
;
1996 if (strmatch(argv
[3]->text
, "vrf"))
1997 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1999 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2003 vty_show_ip_route_summary(vty
, table
);
2009 /* Show ipv6 route summary prefix. */
2010 DEFUN (show_ipv6_route_summary_prefix
,
2011 show_ipv6_route_summary_prefix_cmd
,
2012 "show ipv6 route [vrf NAME] summary prefix",
2015 "IPv6 routing table\n"
2017 "Summary of all IPv6 routes\n"
2020 struct route_table
*table
;
2021 vrf_id_t vrf_id
= VRF_DEFAULT
;
2023 if (strmatch(argv
[3]->text
, "vrf"))
2024 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2026 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2030 vty_show_ip_route_summary_prefix(vty
, table
);
2037 * Show IPv6 mroute command.Used to dump
2038 * the Multicast routing table.
2040 DEFUN (show_ipv6_mroute
,
2041 show_ipv6_mroute_cmd
,
2042 "show ipv6 mroute [vrf NAME]",
2045 "IPv6 Multicast routing table\n"
2048 struct route_table
*table
;
2049 struct route_node
*rn
;
2050 struct route_entry
*re
;
2052 vrf_id_t vrf_id
= VRF_DEFAULT
;
2055 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2057 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2061 /* Show all IPv6 route. */
2062 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2063 RNODE_FOREACH_RE(rn
, re
)
2066 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2069 vty_show_ip_route(vty
, rn
, re
, NULL
);
2074 DEFUN (show_ipv6_route_vrf_all_addr
,
2075 show_ipv6_route_vrf_all_addr_cmd
,
2076 "show ipv6 route vrf all X:X::X:X",
2079 "IPv6 routing table\n"
2080 VRF_ALL_CMD_HELP_STR
2085 struct prefix_ipv6 p
;
2086 struct route_table
*table
;
2087 struct route_node
*rn
;
2089 struct zebra_vrf
*zvrf
;
2091 ret
= str2prefix_ipv6(argv
[idx_ipv6
]->arg
, &p
);
2093 vty_out(vty
, "Malformed IPv6 address\n");
2097 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2099 if ((zvrf
= vrf
->info
) == NULL
2100 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2103 rn
= route_node_match(table
, (struct prefix
*)&p
);
2107 vty_show_ip_route_detail(vty
, rn
, 0);
2109 route_unlock_node(rn
);
2115 DEFUN (show_ipv6_route_vrf_all_prefix
,
2116 show_ipv6_route_vrf_all_prefix_cmd
,
2117 "show ipv6 route vrf all X:X::X:X/M",
2120 "IPv6 routing table\n"
2121 VRF_ALL_CMD_HELP_STR
2124 int idx_ipv6_prefixlen
= 5;
2126 struct prefix_ipv6 p
;
2127 struct route_table
*table
;
2128 struct route_node
*rn
;
2130 struct zebra_vrf
*zvrf
;
2132 ret
= str2prefix_ipv6(argv
[idx_ipv6_prefixlen
]->arg
, &p
);
2134 vty_out(vty
, "Malformed IPv6 prefix\n");
2138 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2140 if ((zvrf
= vrf
->info
) == NULL
2141 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2144 rn
= route_node_match(table
, (struct prefix
*)&p
);
2147 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
2148 route_unlock_node(rn
);
2152 vty_show_ip_route_detail(vty
, rn
, 0);
2154 route_unlock_node(rn
);
2160 DEFUN (show_ipv6_route_vrf_all_summary
,
2161 show_ipv6_route_vrf_all_summary_cmd
,
2162 "show ipv6 route vrf all summary",
2165 "IPv6 routing table\n"
2166 VRF_ALL_CMD_HELP_STR
2167 "Summary of all IPv6 routes\n")
2170 struct zebra_vrf
*zvrf
;
2172 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2173 if ((zvrf
= vrf
->info
) != NULL
)
2174 vty_show_ip_route_summary(vty
,
2175 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2180 DEFUN (show_ipv6_mroute_vrf_all
,
2181 show_ipv6_mroute_vrf_all_cmd
,
2182 "show ipv6 mroute vrf all",
2185 "IPv6 Multicast routing table\n"
2186 VRF_ALL_CMD_HELP_STR
)
2188 struct route_table
*table
;
2189 struct route_node
*rn
;
2190 struct route_entry
*re
;
2192 struct zebra_vrf
*zvrf
;
2195 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2197 if ((zvrf
= vrf
->info
) == NULL
2198 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2201 /* Show all IPv6 route. */
2202 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2203 RNODE_FOREACH_RE(rn
, re
)
2206 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2209 vty_show_ip_route(vty
, rn
, re
, NULL
);
2215 DEFUN (show_ipv6_route_vrf_all_summary_prefix
,
2216 show_ipv6_route_vrf_all_summary_prefix_cmd
,
2217 "show ipv6 route vrf all summary prefix",
2220 "IPv6 routing table\n"
2221 VRF_ALL_CMD_HELP_STR
2222 "Summary of all IPv6 routes\n"
2226 struct zebra_vrf
*zvrf
;
2228 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2229 if ((zvrf
= vrf
->info
) != NULL
)
2230 vty_show_ip_route_summary_prefix(
2231 vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2236 DEFUN (allow_external_route_update
,
2237 allow_external_route_update_cmd
,
2238 "allow-external-route-update",
2239 "Allow FRR routes to be overwritten by external processes\n")
2246 DEFUN (no_allow_external_route_update
,
2247 no_allow_external_route_update_cmd
,
2248 "no allow-external-route-update",
2250 "Allow FRR routes to be overwritten by external processes\n")
2265 struct zebra_vrf
*zvrf
;
2267 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2269 if (!(zvrf
= vrf
->info
))
2274 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2275 if (zvrf_id(zvrf
) == VRF_UNKNOWN
)
2276 vty_out(vty
, "inactive");
2278 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2286 DEFUN (show_evpn_vni
,
2291 "VxLAN information\n")
2293 struct zebra_vrf
*zvrf
;
2295 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2296 zebra_vxlan_print_vnis(vty
, zvrf
);
2300 DEFUN (show_evpn_vni_vni
,
2301 show_evpn_vni_vni_cmd
,
2302 "show evpn vni " CMD_VNI_RANGE
,
2305 "VxLAN Network Identifier\n"
2308 struct zebra_vrf
*zvrf
;
2311 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2312 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2313 zebra_vxlan_print_vni(vty
, zvrf
, vni
);
2317 DEFUN (show_evpn_mac_vni
,
2318 show_evpn_mac_vni_cmd
,
2319 "show evpn mac vni " CMD_VNI_RANGE
,
2323 "VxLAN Network Identifier\n"
2326 struct zebra_vrf
*zvrf
;
2329 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2330 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2331 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
);
2335 DEFUN (show_evpn_mac_vni_all
,
2336 show_evpn_mac_vni_all_cmd
,
2337 "show evpn mac vni all",
2341 "VxLAN Network Identifier\n"
2344 struct zebra_vrf
*zvrf
;
2346 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2347 zebra_vxlan_print_macs_all_vni(vty
, zvrf
);
2351 DEFUN (show_evpn_mac_vni_all_vtep
,
2352 show_evpn_mac_vni_all_vtep_cmd
,
2353 "show evpn mac vni all vtep A.B.C.D",
2357 "VxLAN Network Identifier\n"
2360 "Remote VTEP IP address\n")
2362 struct zebra_vrf
*zvrf
;
2363 struct in_addr vtep_ip
;
2365 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2366 vty_out(vty
, "%% Malformed VTEP IP address\n");
2369 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2370 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
);
2376 DEFUN (show_evpn_mac_vni_mac
,
2377 show_evpn_mac_vni_mac_cmd
,
2378 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2382 "VxLAN Network Identifier\n"
2385 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2387 struct zebra_vrf
*zvrf
;
2391 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2392 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2393 vty_out(vty
, "%% Malformed MAC address");
2396 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2397 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2401 DEFUN (show_evpn_mac_vni_vtep
,
2402 show_evpn_mac_vni_vtep_cmd
,
2403 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D",
2407 "VxLAN Network Identifier\n"
2410 "Remote VTEP IP address\n")
2412 struct zebra_vrf
*zvrf
;
2414 struct in_addr vtep_ip
;
2416 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2417 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2418 vty_out(vty
, "%% Malformed VTEP IP address\n");
2422 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2423 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
);
2427 DEFUN (show_evpn_neigh_vni
,
2428 show_evpn_neigh_vni_cmd
,
2429 "show evpn arp-cache vni " CMD_VNI_RANGE
,
2432 "ARP and ND cache\n"
2433 "VxLAN Network Identifier\n"
2436 struct zebra_vrf
*zvrf
;
2439 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2440 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2441 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
);
2445 DEFUN (show_evpn_neigh_vni_all
,
2446 show_evpn_neigh_vni_all_cmd
,
2447 "show evpn arp-cache vni all",
2450 "ARP and ND cache\n"
2451 "VxLAN Network Identifier\n"
2454 struct zebra_vrf
*zvrf
;
2456 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2457 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
);
2461 DEFUN (show_evpn_neigh_vni_neigh
,
2462 show_evpn_neigh_vni_neigh_cmd
,
2463 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD",
2466 "ARP and ND cache\n"
2467 "VxLAN Network Identifier\n"
2470 "Neighbor address (IPv4 or IPv6 address)\n")
2472 struct zebra_vrf
*zvrf
;
2476 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2477 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2478 vty_out(vty
, "%% Malformed Neighbor address\n");
2481 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2482 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
);
2486 DEFUN (show_evpn_neigh_vni_vtep
,
2487 show_evpn_neigh_vni_vtep_cmd
,
2488 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D",
2491 "ARP and ND cache\n"
2492 "VxLAN Network Identifier\n"
2495 "Remote VTEP IP address\n")
2497 struct zebra_vrf
*zvrf
;
2499 struct in_addr vtep_ip
;
2501 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2502 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2503 vty_out(vty
, "%% Malformed VTEP IP address\n");
2507 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2508 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
);
2512 /* Static ip route configuration write function. */
2513 static int zebra_ip_config(struct vty
*vty
)
2517 write
+= static_config(vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
2518 write
+= static_config(vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
2519 write
+= static_config(vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
2521 write
+= zebra_import_table_config(vty
);
2525 DEFUN (ip_zebra_import_table_distance
,
2526 ip_zebra_import_table_distance_cmd
,
2527 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2529 "import routes from non-main kernel table\n"
2530 "kernel routing table id\n"
2531 "Distance for imported routes\n"
2532 "Default distance value\n"
2533 "route-map for filtering\n"
2536 u_int32_t table_id
= 0;
2538 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2539 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2541 strmatch(argv
[argc
- 2]->text
, "route-map")
2542 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2546 if (argc
== 7 || (argc
== 5 && !rmap
))
2547 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2549 if (!is_zebra_valid_kernel_table(table_id
)) {
2551 "Invalid routing table ID, %d. Must be in range 1-252\n",
2556 if (is_zebra_main_routing_table(table_id
)) {
2558 "Invalid routing table ID, %d. Must be non-default table\n",
2563 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2565 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2570 DEFUN (no_ip_zebra_import_table
,
2571 no_ip_zebra_import_table_cmd
,
2572 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2575 "import routes from non-main kernel table\n"
2576 "kernel routing table id\n"
2577 "Distance for imported routes\n"
2578 "Default distance value\n"
2579 "route-map for filtering\n"
2582 u_int32_t table_id
= 0;
2583 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2585 if (!is_zebra_valid_kernel_table(table_id
)) {
2587 "Invalid routing table ID. Must be in range 1-252\n");
2591 if (is_zebra_main_routing_table(table_id
)) {
2593 "Invalid routing table ID, %d. Must be non-default table\n",
2598 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2601 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2604 static int config_write_protocol(struct vty
*vty
)
2607 vty_out(vty
, "allow-external-route-update\n");
2609 if (zebra_rnh_ip_default_route
)
2610 vty_out(vty
, "ip nht resolve-via-default\n");
2612 if (zebra_rnh_ipv6_default_route
)
2613 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2615 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2617 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2618 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2619 ipv4_multicast_mode
== MCAST_URIB_ONLY
2621 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2623 : ipv4_multicast_mode
2624 == MCAST_MIX_MRIB_FIRST
2626 : ipv4_multicast_mode
2627 == MCAST_MIX_DISTANCE
2631 zebra_routemap_config_write_protocol(vty
);
2636 /* IP node for static routes. */
2637 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2638 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2641 void zebra_vty_init(void)
2643 install_node(&ip_node
, zebra_ip_config
);
2644 install_node(&protocol_node
, config_write_protocol
);
2646 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2647 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2648 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
2649 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2650 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2651 install_element(CONFIG_NODE
, &ip_route_cmd
);
2652 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2653 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2655 install_element(VIEW_NODE
, &show_vrf_cmd
);
2656 install_element(VIEW_NODE
, &show_ip_route_cmd
);
2657 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2658 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2659 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2660 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2661 install_element(VIEW_NODE
, &show_ip_route_addr_cmd
);
2662 install_element(VIEW_NODE
, &show_ip_route_prefix_cmd
);
2663 install_element(VIEW_NODE
, &show_ip_route_summary_cmd
);
2664 install_element(VIEW_NODE
, &show_ip_route_summary_prefix_cmd
);
2666 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2667 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2669 install_element(VIEW_NODE
, &show_ip_route_vrf_all_addr_cmd
);
2670 install_element(VIEW_NODE
, &show_ip_route_vrf_all_prefix_cmd
);
2671 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_cmd
);
2672 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_prefix_cmd
);
2674 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
2675 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2676 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2677 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2678 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2679 install_element(VIEW_NODE
, &show_ipv6_route_cmd
);
2680 install_element(VIEW_NODE
, &show_ipv6_route_summary_cmd
);
2681 install_element(VIEW_NODE
, &show_ipv6_route_summary_prefix_cmd
);
2682 install_element(VIEW_NODE
, &show_ipv6_route_addr_cmd
);
2683 install_element(VIEW_NODE
, &show_ipv6_route_prefix_cmd
);
2684 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2686 /* Commands for VRF */
2687 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_cmd
);
2688 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_prefix_cmd
);
2689 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_addr_cmd
);
2690 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_prefix_cmd
);
2692 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2694 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2695 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2696 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2697 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2698 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2699 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2700 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2701 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2702 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2703 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2704 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);