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
,
53 const struct prefix
*longer_prefix_p
,
54 bool supernets_only
, int type
,
55 u_short ospf_instance_id
);
56 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
59 /* VNI range as per RFC 7432 */
60 #define CMD_VNI_RANGE "(1-16777215)"
62 /* General function for static route. */
63 static int zebra_static_route(struct vty
*vty
, afi_t afi
, safi_t safi
,
64 const char *negate
, const char *dest_str
,
65 const char *mask_str
, const char *src_str
,
66 const char *gate_str
, const char *ifname
,
67 const char *flag_str
, const char *tag_str
,
68 const char *distance_str
, const char *vrf_id_str
,
69 const char *label_str
)
74 struct prefix_ipv6
*src_p
= NULL
;
76 union g_addr
*gatep
= NULL
;
78 enum static_blackhole_type bh_type
= 0;
80 struct zebra_vrf
*zvrf
;
82 struct static_nh_label snh_label
;
84 ret
= str2prefix(dest_str
, &p
);
86 vty_out(vty
, "%% Malformed address\n");
87 return CMD_WARNING_CONFIG_FAILED
;
92 /* Cisco like mask notation. */
94 ret
= inet_aton(mask_str
, &mask
);
96 vty_out(vty
, "%% Malformed address\n");
97 return CMD_WARNING_CONFIG_FAILED
;
99 p
.prefixlen
= ip_masklen(mask
);
103 /* srcdest routing */
105 ret
= str2prefix(src_str
, &src
);
106 if (ret
<= 0 || src
.family
!= AF_INET6
) {
107 vty_out(vty
, "%% Malformed source address\n");
108 return CMD_WARNING_CONFIG_FAILED
;
110 src_p
= (struct prefix_ipv6
*)&src
;
117 /* Apply mask for given prefix. */
120 /* Administrative distance. */
122 distance
= atoi(distance_str
);
124 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
128 tag
= strtoul(tag_str
, NULL
, 10);
131 zvrf
= zebra_vrf_lookup_by_name(vrf_id_str
);
134 vty_out(vty
, "%% vrf %s is not defined\n", vrf_id_str
);
135 return CMD_WARNING_CONFIG_FAILED
;
139 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
143 "%% MPLS not turned on in kernel, ignoring command\n");
144 return CMD_WARNING_CONFIG_FAILED
;
146 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
151 vty_out(vty
, "%% Malformed label(s)\n");
155 "%% Cannot use reserved label(s) (%d-%d)\n",
156 MPLS_MIN_RESERVED_LABEL
,
157 MPLS_MAX_RESERVED_LABEL
);
161 "%% Too many labels. Enter %d or fewer\n",
165 return CMD_WARNING_CONFIG_FAILED
;
169 /* Null0 static route. */
170 if (ifname
!= NULL
) {
171 if (strncasecmp(ifname
, "Null0", strlen(ifname
)) == 0 ||
172 strncasecmp(ifname
, "reject", strlen(ifname
)) == 0 ||
173 strncasecmp(ifname
, "blackhole", strlen(ifname
)) == 0) {
174 vty_out(vty
, "%% Nexthop interface cannot be Null0, reject or blackhole\n");
175 return CMD_WARNING_CONFIG_FAILED
;
181 switch (flag_str
[0]) {
183 bh_type
= STATIC_BLACKHOLE_REJECT
;
186 bh_type
= STATIC_BLACKHOLE_DROP
;
189 bh_type
= STATIC_BLACKHOLE_NULL
;
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 bh_type
, 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. */
343 DEFPY(ip_route_blackhole
,
344 ip_route_blackhole_cmd
,
346 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
347 <Null0|reject|blackhole>$flag \
355 "Establish static routes\n"
356 "IP destination prefix (e.g. 10.0.0.0/8)\n"
357 "IP destination prefix\n"
358 "IP destination prefix mask\n"
360 "Emit an ICMP unreachable when matched\n"
361 "Silently discard pkts when matched\n"
362 "Set tag for this route\n"
364 "Distance value for this route\n"
368 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
369 mask_str
, NULL
, NULL
, NULL
, flag
,
370 tag_str
, distance_str
, vrf
, label
);
373 DEFPY(ip_route_address_interface
,
374 ip_route_address_interface_cmd
,
376 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
386 "Establish static routes\n"
387 "IP destination prefix (e.g. 10.0.0.0/8)\n"
388 "IP destination prefix\n"
389 "IP destination prefix mask\n"
390 "IP gateway address\n"
391 "IP gateway interface name\n"
392 "Set tag for this route\n"
394 "Distance value for this route\n"
398 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
399 mask_str
, NULL
, gate_str
, ifname
, NULL
,
400 tag_str
, distance_str
, vrf
, label
);
406 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
407 <A.B.C.D$gate|INTERFACE$ifname> \
415 "Establish static routes\n"
416 "IP destination prefix (e.g. 10.0.0.0/8)\n"
417 "IP destination prefix\n"
418 "IP destination prefix mask\n"
419 "IP gateway address\n"
420 "IP gateway interface name\n"
421 "Set tag for this route\n"
423 "Distance value for this route\n"
427 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
428 mask_str
, NULL
, gate_str
, ifname
, NULL
,
429 tag_str
, distance_str
, vrf
, label
);
432 /* New RIB. Detailed information for IPv4 route. */
433 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
436 struct route_entry
*re
;
437 struct nexthop
*nexthop
;
438 char buf
[SRCDEST2STR_BUFFER
];
439 struct zebra_vrf
*zvrf
;
441 RNODE_FOREACH_RE (rn
, re
) {
442 const char *mcast_info
= "";
444 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
445 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
446 ? " using Multicast RIB"
447 : " using Unicast RIB";
450 vty_out(vty
, "Routing entry for %s%s\n",
451 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
452 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
454 vty_out(vty
, "[%d]", re
->instance
);
456 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
459 vty_out(vty
, ", tag %u", re
->tag
);
461 vty_out(vty
, ", mtu %u", re
->mtu
);
462 if (re
->vrf_id
!= VRF_DEFAULT
) {
463 zvrf
= vrf_info_lookup(re
->vrf_id
);
464 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
466 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
467 vty_out(vty
, ", best");
474 uptime
-= re
->uptime
;
475 tm
= gmtime(&uptime
);
477 vty_out(vty
, " Last update ");
479 if (uptime
< ONE_DAY_SECOND
)
480 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
481 tm
->tm_min
, tm
->tm_sec
);
482 else if (uptime
< ONE_WEEK_SECOND
)
483 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
484 tm
->tm_hour
, tm
->tm_min
);
486 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
487 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
489 vty_out(vty
, " ago\n");
491 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
494 vty_out(vty
, " %c%s",
495 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
496 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
499 nexthop
->rparent
? " " : "");
501 switch (nexthop
->type
) {
502 case NEXTHOP_TYPE_IPV4
:
503 case NEXTHOP_TYPE_IPV4_IFINDEX
:
505 inet_ntoa(nexthop
->gate
.ipv4
));
506 if (nexthop
->ifindex
)
507 vty_out(vty
, ", via %s",
508 ifindex2ifname(nexthop
->ifindex
,
511 case NEXTHOP_TYPE_IPV6
:
512 case NEXTHOP_TYPE_IPV6_IFINDEX
:
514 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
516 if (nexthop
->ifindex
)
517 vty_out(vty
, ", via %s",
518 ifindex2ifname(nexthop
->ifindex
,
521 case NEXTHOP_TYPE_IFINDEX
:
522 vty_out(vty
, " directly connected, %s",
523 ifindex2ifname(nexthop
->ifindex
,
526 case NEXTHOP_TYPE_BLACKHOLE
:
527 vty_out(vty
, " unreachable");
528 switch (nexthop
->bh_type
) {
529 case BLACKHOLE_REJECT
:
530 vty_out(vty
, " (ICMP unreachable)");
532 case BLACKHOLE_ADMINPROHIB
:
534 " (ICMP admin-prohibited)");
537 vty_out(vty
, " (blackhole)");
539 case BLACKHOLE_UNSPEC
:
546 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
547 vty_out(vty
, " (duplicate nexthop removed)");
549 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
550 vty_out(vty
, " inactive");
552 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
553 vty_out(vty
, " onlink");
555 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
556 vty_out(vty
, " (recursive)");
558 switch (nexthop
->type
) {
559 case NEXTHOP_TYPE_IPV4
:
560 case NEXTHOP_TYPE_IPV4_IFINDEX
:
561 if (nexthop
->src
.ipv4
.s_addr
) {
562 if (inet_ntop(AF_INET
,
564 addrstr
, sizeof addrstr
))
565 vty_out(vty
, ", src %s",
569 case NEXTHOP_TYPE_IPV6
:
570 case NEXTHOP_TYPE_IPV6_IFINDEX
:
571 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
573 if (inet_ntop(AF_INET6
,
575 addrstr
, sizeof addrstr
))
576 vty_out(vty
, ", src %s",
585 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
587 /* Label information */
588 if (nexthop
->nh_label
589 && nexthop
->nh_label
->num_labels
) {
590 vty_out(vty
, ", label %s",
592 nexthop
->nh_label
->num_labels
,
593 nexthop
->nh_label
->label
, buf
,
603 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
604 struct route_entry
*re
, json_object
*json
)
606 struct nexthop
*nexthop
;
608 char buf
[SRCDEST2STR_BUFFER
];
609 json_object
*json_nexthops
= NULL
;
610 json_object
*json_nexthop
= NULL
;
611 json_object
*json_route
= NULL
;
612 json_object
*json_labels
= NULL
;
617 uptime
-= re
->uptime
;
618 tm
= gmtime(&uptime
);
621 json_route
= json_object_new_object();
622 json_nexthops
= json_object_new_array();
624 json_object_string_add(json_route
, "prefix",
625 srcdest_rnode2str(rn
, buf
, sizeof buf
));
626 json_object_string_add(json_route
, "protocol",
627 zebra_route_string(re
->type
));
630 json_object_int_add(json_route
, "instance",
634 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
636 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
637 json_object_boolean_true_add(json_route
, "selected");
639 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
640 json_object_int_add(json_route
, "distance",
642 json_object_int_add(json_route
, "metric", re
->metric
);
645 if (uptime
< ONE_DAY_SECOND
)
646 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
647 tm
->tm_min
, tm
->tm_sec
);
648 else if (uptime
< ONE_WEEK_SECOND
)
649 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
650 tm
->tm_hour
, tm
->tm_min
);
652 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
653 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
656 json_object_string_add(json_route
, "uptime", buf
);
658 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
659 json_nexthop
= json_object_new_object();
661 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
662 json_object_boolean_true_add(json_nexthop
,
665 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
666 json_object_boolean_true_add(json_nexthop
,
669 switch (nexthop
->type
) {
670 case NEXTHOP_TYPE_IPV4
:
671 case NEXTHOP_TYPE_IPV4_IFINDEX
:
672 json_object_string_add(
674 inet_ntoa(nexthop
->gate
.ipv4
));
675 json_object_string_add(json_nexthop
, "afi",
678 if (nexthop
->ifindex
) {
679 json_object_int_add(json_nexthop
,
682 json_object_string_add(
683 json_nexthop
, "interfaceName",
684 ifindex2ifname(nexthop
->ifindex
,
688 case NEXTHOP_TYPE_IPV6
:
689 case NEXTHOP_TYPE_IPV6_IFINDEX
:
690 json_object_string_add(
692 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
694 json_object_string_add(json_nexthop
, "afi",
697 if (nexthop
->ifindex
) {
698 json_object_int_add(json_nexthop
,
701 json_object_string_add(
702 json_nexthop
, "interfaceName",
703 ifindex2ifname(nexthop
->ifindex
,
708 case NEXTHOP_TYPE_IFINDEX
:
709 json_object_boolean_true_add(
710 json_nexthop
, "directlyConnected");
711 json_object_int_add(json_nexthop
,
714 json_object_string_add(
715 json_nexthop
, "interfaceName",
716 ifindex2ifname(nexthop
->ifindex
,
719 case NEXTHOP_TYPE_BLACKHOLE
:
720 json_object_boolean_true_add(json_nexthop
,
722 switch (nexthop
->bh_type
) {
723 case BLACKHOLE_REJECT
:
724 json_object_boolean_true_add(
725 json_nexthop
, "reject");
727 case BLACKHOLE_ADMINPROHIB
:
728 json_object_boolean_true_add(
733 json_object_boolean_true_add(
734 json_nexthop
, "blackhole");
736 case BLACKHOLE_UNSPEC
:
744 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
745 json_object_boolean_true_add(json_nexthop
,
748 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
749 json_object_boolean_true_add(json_nexthop
,
752 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
753 json_object_boolean_true_add(json_nexthop
,
756 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
757 json_object_boolean_true_add(json_nexthop
,
760 switch (nexthop
->type
) {
761 case NEXTHOP_TYPE_IPV4
:
762 case NEXTHOP_TYPE_IPV4_IFINDEX
:
763 if (nexthop
->src
.ipv4
.s_addr
) {
764 if (inet_ntop(AF_INET
,
765 &nexthop
->src
.ipv4
, buf
,
767 json_object_string_add(
768 json_nexthop
, "source",
772 case NEXTHOP_TYPE_IPV6
:
773 case NEXTHOP_TYPE_IPV6_IFINDEX
:
774 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
776 if (inet_ntop(AF_INET6
,
777 &nexthop
->src
.ipv6
, buf
,
779 json_object_string_add(
780 json_nexthop
, "source",
788 if (nexthop
->nh_label
789 && nexthop
->nh_label
->num_labels
) {
790 json_labels
= json_object_new_array();
792 for (int label_index
= 0;
794 < nexthop
->nh_label
->num_labels
;
796 json_object_array_add(
799 nexthop
->nh_label
->label
802 json_object_object_add(json_nexthop
, "labels",
806 json_object_array_add(json_nexthops
, json_nexthop
);
809 json_object_object_add(json_route
, "nexthops", json_nexthops
);
810 json_object_array_add(json
, json_route
);
814 /* Nexthop information. */
815 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
816 if (nexthop
== re
->nexthop
) {
817 /* Prefix information. */
818 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
820 len
+= vty_out(vty
, "[%d]", re
->instance
);
823 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
826 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
829 srcdest_rnode2str(rn
, buf
, sizeof buf
));
831 /* Distance and metric display. */
832 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
833 len
+= vty_out(vty
, " [%u/%u]", re
->distance
,
836 vty_out(vty
, " %c%*c",
837 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
838 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
841 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
844 switch (nexthop
->type
) {
845 case NEXTHOP_TYPE_IPV4
:
846 case NEXTHOP_TYPE_IPV4_IFINDEX
:
847 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
848 if (nexthop
->ifindex
)
850 ifindex2ifname(nexthop
->ifindex
,
853 case NEXTHOP_TYPE_IPV6
:
854 case NEXTHOP_TYPE_IPV6_IFINDEX
:
855 vty_out(vty
, " via %s",
856 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
858 if (nexthop
->ifindex
)
860 ifindex2ifname(nexthop
->ifindex
,
864 case NEXTHOP_TYPE_IFINDEX
:
865 vty_out(vty
, " is directly connected, %s",
866 ifindex2ifname(nexthop
->ifindex
, re
->vrf_id
));
868 case NEXTHOP_TYPE_BLACKHOLE
:
869 vty_out(vty
, " unreachable");
870 switch (nexthop
->bh_type
) {
871 case BLACKHOLE_REJECT
:
872 vty_out(vty
, " (ICMP unreachable)");
874 case BLACKHOLE_ADMINPROHIB
:
875 vty_out(vty
, " (ICMP admin-prohibited)");
878 vty_out(vty
, " (blackhole)");
880 case BLACKHOLE_UNSPEC
:
887 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
888 vty_out(vty
, " inactive");
890 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
891 vty_out(vty
, " onlink");
893 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
894 vty_out(vty
, " (recursive)");
896 switch (nexthop
->type
) {
897 case NEXTHOP_TYPE_IPV4
:
898 case NEXTHOP_TYPE_IPV4_IFINDEX
:
899 if (nexthop
->src
.ipv4
.s_addr
) {
900 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
902 vty_out(vty
, ", src %s", buf
);
905 case NEXTHOP_TYPE_IPV6
:
906 case NEXTHOP_TYPE_IPV6_IFINDEX
:
907 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
908 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
910 vty_out(vty
, ", src %s", buf
);
917 /* Label information */
918 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
919 vty_out(vty
, ", label %s",
920 mpls_label2str(nexthop
->nh_label
->num_labels
,
921 nexthop
->nh_label
->label
, buf
,
925 if (uptime
< ONE_DAY_SECOND
)
926 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
927 tm
->tm_min
, tm
->tm_sec
);
928 else if (uptime
< ONE_WEEK_SECOND
)
929 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
930 tm
->tm_hour
, tm
->tm_min
);
932 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
933 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
939 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
940 safi_t safi
, bool use_fib
, u_char use_json
,
942 const struct prefix
*longer_prefix_p
,
943 bool supernets_only
, int type
,
944 u_short ospf_instance_id
)
946 struct route_table
*table
;
947 struct route_node
*rn
;
948 struct route_entry
*re
;
950 struct zebra_vrf
*zvrf
= NULL
;
952 json_object
*json
= NULL
;
953 json_object
*json_prefix
= NULL
;
956 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
958 vty_out(vty
, "{}\n");
960 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
964 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
966 vty_out(vty
, "{}\n");
968 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
972 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
975 vty_out(vty
, "{}\n");
980 json
= json_object_new_object();
982 /* Show all routes. */
983 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
984 RNODE_FOREACH_RE (rn
, re
) {
986 && !CHECK_FLAG(re
->status
,
987 ROUTE_ENTRY_SELECTED_FIB
))
990 if (tag
&& re
->tag
!= tag
)
994 && !prefix_match(longer_prefix_p
, &rn
->p
))
997 /* This can only be true when the afi is IPv4 */
998 if (supernets_only
) {
999 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1001 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1004 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1007 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1011 if (type
&& re
->type
!= type
)
1014 if (ospf_instance_id
1015 && (re
->type
!= ZEBRA_ROUTE_OSPF
1016 || re
->instance
!= ospf_instance_id
))
1021 json_prefix
= json_object_new_array();
1026 SHOW_ROUTE_V4_HEADER
);
1029 SHOW_ROUTE_V6_HEADER
);
1031 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
1032 vty_out(vty
, "\nVRF %s:\n",
1039 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
1043 prefix2str(&rn
->p
, buf
, sizeof buf
);
1044 json_object_object_add(json
, buf
, json_prefix
);
1050 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1051 json
, JSON_C_TO_STRING_PRETTY
));
1052 json_object_free(json
);
1060 "show ip nht [vrf NAME]",
1063 "IP nexthop tracking table\n"
1067 vrf_id_t vrf_id
= VRF_DEFAULT
;
1070 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1072 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1077 DEFUN (show_ip_nht_vrf_all
,
1078 show_ip_nht_vrf_all_cmd
,
1079 "show ip nht vrf all",
1082 "IP nexthop tracking table\n"
1083 VRF_ALL_CMD_HELP_STR
)
1086 struct zebra_vrf
*zvrf
;
1088 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1089 if ((zvrf
= vrf
->info
) != NULL
) {
1090 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1091 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1098 DEFUN (show_ipv6_nht
,
1100 "show ipv6 nht [vrf NAME]",
1103 "IPv6 nexthop tracking table\n"
1107 vrf_id_t vrf_id
= VRF_DEFAULT
;
1110 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1112 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1117 DEFUN (show_ipv6_nht_vrf_all
,
1118 show_ipv6_nht_vrf_all_cmd
,
1119 "show ipv6 nht vrf all",
1122 "IPv6 nexthop tracking table\n"
1123 VRF_ALL_CMD_HELP_STR
)
1126 struct zebra_vrf
*zvrf
;
1128 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1129 if ((zvrf
= vrf
->info
) != NULL
) {
1130 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1131 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1138 DEFUN (ip_nht_default_route
,
1139 ip_nht_default_route_cmd
,
1140 "ip nht resolve-via-default",
1142 "Filter Next Hop tracking route resolution\n"
1143 "Resolve via default route\n")
1145 if (zebra_rnh_ip_default_route
)
1148 zebra_rnh_ip_default_route
= 1;
1149 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1153 DEFUN (no_ip_nht_default_route
,
1154 no_ip_nht_default_route_cmd
,
1155 "no ip nht resolve-via-default",
1158 "Filter Next Hop tracking route resolution\n"
1159 "Resolve via default route\n")
1161 if (!zebra_rnh_ip_default_route
)
1164 zebra_rnh_ip_default_route
= 0;
1165 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1169 DEFUN (ipv6_nht_default_route
,
1170 ipv6_nht_default_route_cmd
,
1171 "ipv6 nht resolve-via-default",
1173 "Filter Next Hop tracking route resolution\n"
1174 "Resolve via default route\n")
1176 if (zebra_rnh_ipv6_default_route
)
1179 zebra_rnh_ipv6_default_route
= 1;
1180 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1184 DEFUN (no_ipv6_nht_default_route
,
1185 no_ipv6_nht_default_route_cmd
,
1186 "no ipv6 nht resolve-via-default",
1189 "Filter Next Hop tracking route resolution\n"
1190 "Resolve via default route\n")
1192 if (!zebra_rnh_ipv6_default_route
)
1195 zebra_rnh_ipv6_default_route
= 0;
1196 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1204 ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1207 |A.B.C.D/M$prefix longer-prefixes\
1208 |supernets-only$supernets_only\
1209 |" FRR_IP_REDIST_STR_ZEBRA
"$type_str\
1210 |ospf$type_str (1-65535)$ospf_instance_id\
1212 |ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
1215 |X:X::X:X/M$prefix longer-prefixes\
1216 |" FRR_IP6_REDIST_STR_ZEBRA
"$type_str\
1222 "IP forwarding table\n"
1223 "IP routing table\n"
1224 VRF_FULL_CMD_HELP_STR
1225 "Show only routes with tag\n"
1227 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1228 "Show route matching the specified Network/Mask pair only\n"
1229 "Show supernet entries only\n"
1230 FRR_IP_REDIST_HELP_STR_ZEBRA
1231 "Open Shortest Path First (OSPFv2)\n"
1234 "IP forwarding table\n"
1235 "IP routing table\n"
1236 VRF_FULL_CMD_HELP_STR
1237 "Show only routes with tag\n"
1240 "Show route matching the specified Network/Mask pair only\n"
1241 FRR_IP6_REDIST_HELP_STR_ZEBRA
1244 afi_t afi
= ipv4
? AFI_IP
: AFI_IP6
;
1249 type
= proto_redistnum(afi
, type_str
);
1251 vty_out(vty
, "Unknown route type\n");
1257 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1258 struct zebra_vrf
*zvrf
;
1259 struct route_table
*table
;
1261 if ((zvrf
= vrf
->info
) == NULL
1262 || (table
= zvrf
->table
[afi
][SAFI_UNICAST
]) == NULL
)
1266 vty
, zvrf_name(zvrf
), afi
, SAFI_UNICAST
, !!fib
,
1267 !!json
, tag
, prefix_str
? prefix
: NULL
,
1268 !!supernets_only
, type
, ospf_instance_id
);
1271 vrf_id_t vrf_id
= VRF_DEFAULT
;
1274 VRF_GET_ID(vrf_id
, vrf_name
);
1275 vrf
= vrf_lookup_by_id(vrf_id
);
1276 do_show_ip_route(vty
, vrf
->name
, afi
, SAFI_UNICAST
, !!fib
,
1277 !!json
, tag
, prefix_str
? prefix
: NULL
,
1278 !!supernets_only
, type
, ospf_instance_id
);
1284 DEFUN (show_ip_route_addr
,
1285 show_ip_route_addr_cmd
,
1286 "show ip route [vrf NAME] A.B.C.D",
1289 "IP routing table\n"
1291 "Network in the IP routing table to display\n")
1294 struct prefix_ipv4 p
;
1295 struct route_table
*table
;
1296 struct route_node
*rn
;
1297 vrf_id_t vrf_id
= VRF_DEFAULT
;
1299 if (strmatch(argv
[3]->text
, "vrf")) {
1300 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1301 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1303 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1307 vty_out(vty
, "%% Malformed IPv4 address\n");
1311 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1315 rn
= route_node_match(table
, (struct prefix
*)&p
);
1317 vty_out(vty
, "%% Network not in table\n");
1321 vty_show_ip_route_detail(vty
, rn
, 0);
1323 route_unlock_node(rn
);
1328 DEFUN (show_ip_route_prefix
,
1329 show_ip_route_prefix_cmd
,
1330 "show ip route [vrf NAME] A.B.C.D/M",
1333 "IP routing table\n"
1335 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1338 struct prefix_ipv4 p
;
1339 struct route_table
*table
;
1340 struct route_node
*rn
;
1341 vrf_id_t vrf_id
= VRF_DEFAULT
;
1343 if (strmatch(argv
[3]->text
, "vrf")) {
1344 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1345 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1347 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1351 vty_out(vty
, "%% Malformed IPv4 address\n");
1355 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1359 rn
= route_node_match(table
, (struct prefix
*)&p
);
1360 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1361 vty_out(vty
, "%% Network not in table\n");
1365 vty_show_ip_route_detail(vty
, rn
, 0);
1367 route_unlock_node(rn
);
1373 static void vty_show_ip_route_summary(struct vty
*vty
,
1374 struct route_table
*table
)
1376 struct route_node
*rn
;
1377 struct route_entry
*re
;
1378 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1379 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1380 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1381 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1385 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1386 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1387 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1388 RNODE_FOREACH_RE (rn
, re
) {
1389 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1390 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1392 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1394 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1396 rib_cnt
[re
->type
]++;
1398 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1399 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1402 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1404 fib_cnt
[re
->type
]++;
1408 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1409 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1411 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1412 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1413 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1414 if (i
== ZEBRA_ROUTE_BGP
) {
1415 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1416 rib_cnt
[ZEBRA_ROUTE_BGP
],
1417 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1418 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1419 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1420 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1422 vty_out(vty
, "%-20s %-20d %-20d \n",
1423 zebra_route_string(i
), rib_cnt
[i
],
1428 vty_out(vty
, "------\n");
1429 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1430 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1435 * Implementation of the ip route summary prefix command.
1437 * This command prints the primary prefixes that have been installed by various
1438 * protocols on the box.
1441 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1442 struct route_table
*table
)
1444 struct route_node
*rn
;
1445 struct route_entry
*re
;
1446 struct nexthop
*nexthop
;
1447 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1448 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1449 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1450 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1454 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1455 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1456 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1457 RNODE_FOREACH_RE (rn
, re
) {
1460 * In case of ECMP, count only once.
1463 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1464 nexthop
= nexthop
->next
) {
1466 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1467 rib_cnt
[re
->type
]++;
1468 if (CHECK_FLAG(nexthop
->flags
,
1469 NEXTHOP_FLAG_FIB
)) {
1470 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1471 fib_cnt
[re
->type
]++;
1473 if (re
->type
== ZEBRA_ROUTE_BGP
1474 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1475 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1476 if (CHECK_FLAG(nexthop
->flags
,
1478 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1483 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1484 "Prefix Routes", "FIB",
1485 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1487 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1488 if (rib_cnt
[i
] > 0) {
1489 if (i
== ZEBRA_ROUTE_BGP
) {
1490 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1491 rib_cnt
[ZEBRA_ROUTE_BGP
]
1492 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1493 fib_cnt
[ZEBRA_ROUTE_BGP
]
1494 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1495 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1496 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1497 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1499 vty_out(vty
, "%-20s %-20d %-20d \n",
1500 zebra_route_string(i
), rib_cnt
[i
],
1505 vty_out(vty
, "------\n");
1506 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1507 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1511 /* Show route summary. */
1512 DEFUN (show_ip_route_summary
,
1513 show_ip_route_summary_cmd
,
1514 "show ip route [vrf NAME] summary",
1517 "IP routing table\n"
1519 "Summary of all routes\n")
1521 struct route_table
*table
;
1522 vrf_id_t vrf_id
= VRF_DEFAULT
;
1524 if (strmatch(argv
[3]->text
, "vrf"))
1525 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1527 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1531 vty_show_ip_route_summary(vty
, table
);
1536 /* Show route summary prefix. */
1537 DEFUN (show_ip_route_summary_prefix
,
1538 show_ip_route_summary_prefix_cmd
,
1539 "show ip route [vrf NAME] summary prefix",
1542 "IP routing table\n"
1544 "Summary of all routes\n"
1547 struct route_table
*table
;
1548 vrf_id_t vrf_id
= VRF_DEFAULT
;
1550 if (strmatch(argv
[3]->text
, "vrf"))
1551 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1553 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1557 vty_show_ip_route_summary_prefix(vty
, table
);
1563 DEFUN (show_ip_route_vrf_all_addr
,
1564 show_ip_route_vrf_all_addr_cmd
,
1565 "show ip route vrf all A.B.C.D",
1568 "IP routing table\n"
1569 VRF_ALL_CMD_HELP_STR
1570 "Network in the IP routing table to display\n")
1574 struct prefix_ipv4 p
;
1575 struct route_table
*table
;
1576 struct route_node
*rn
;
1578 struct zebra_vrf
*zvrf
;
1580 ret
= str2prefix_ipv4(argv
[idx_ipv4
]->arg
, &p
);
1582 vty_out(vty
, "%% Malformed IPv4 address\n");
1586 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1587 if ((zvrf
= vrf
->info
) == NULL
1588 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1591 rn
= route_node_match(table
, (struct prefix
*)&p
);
1595 vty_show_ip_route_detail(vty
, rn
, 0);
1597 route_unlock_node(rn
);
1603 DEFUN (show_ip_route_vrf_all_prefix
,
1604 show_ip_route_vrf_all_prefix_cmd
,
1605 "show ip route vrf all A.B.C.D/M",
1608 "IP routing table\n"
1609 VRF_ALL_CMD_HELP_STR
1610 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1612 int idx_ipv4_prefixlen
= 5;
1614 struct prefix_ipv4 p
;
1615 struct route_table
*table
;
1616 struct route_node
*rn
;
1618 struct zebra_vrf
*zvrf
;
1620 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
1622 vty_out(vty
, "%% Malformed IPv4 address\n");
1626 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1627 if ((zvrf
= vrf
->info
) == NULL
1628 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1631 rn
= route_node_match(table
, (struct prefix
*)&p
);
1634 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
1635 route_unlock_node(rn
);
1639 vty_show_ip_route_detail(vty
, rn
, 0);
1641 route_unlock_node(rn
);
1647 DEFUN (show_ip_route_vrf_all_summary
,
1648 show_ip_route_vrf_all_summary_cmd
,
1649 "show ip route vrf all summary ",
1652 "IP routing table\n"
1653 VRF_ALL_CMD_HELP_STR
1654 "Summary of all routes\n")
1657 struct zebra_vrf
*zvrf
;
1659 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1660 if ((zvrf
= vrf
->info
) != NULL
)
1661 vty_show_ip_route_summary(
1662 vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1667 DEFUN (show_ip_route_vrf_all_summary_prefix
,
1668 show_ip_route_vrf_all_summary_prefix_cmd
,
1669 "show ip route vrf all summary prefix",
1672 "IP routing table\n"
1673 VRF_ALL_CMD_HELP_STR
1674 "Summary of all routes\n"
1678 struct zebra_vrf
*zvrf
;
1680 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1681 if ((zvrf
= vrf
->info
) != NULL
)
1682 vty_show_ip_route_summary_prefix(
1683 vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1688 /* Write static route configuration. */
1689 static int static_config(struct vty
*vty
, afi_t afi
, safi_t safi
,
1692 struct route_node
*rn
;
1693 struct static_route
*si
;
1694 struct route_table
*stable
;
1696 struct zebra_vrf
*zvrf
;
1697 char buf
[SRCDEST2STR_BUFFER
];
1700 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
1701 if (!(zvrf
= vrf
->info
))
1703 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1706 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1707 for (si
= rn
->info
; si
; si
= si
->next
) {
1708 vty_out(vty
, "%s %s", cmd
,
1709 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1712 case STATIC_IPV4_GATEWAY
:
1714 inet_ntoa(si
->addr
.ipv4
));
1716 case STATIC_IPV6_GATEWAY
:
1719 &si
->addr
.ipv6
, buf
,
1723 vty_out(vty
, " %s", si
->ifname
);
1725 case STATIC_BLACKHOLE
:
1726 switch (si
->bh_type
) {
1727 case STATIC_BLACKHOLE_DROP
:
1728 vty_out(vty
, " blackhole");
1730 case STATIC_BLACKHOLE_NULL
:
1731 vty_out(vty
, " Null0");
1733 case STATIC_BLACKHOLE_REJECT
:
1734 vty_out(vty
, " reject");
1738 case STATIC_IPV4_GATEWAY_IFNAME
:
1739 vty_out(vty
, " %s %s",
1741 &si
->addr
.ipv4
, buf
,
1745 case STATIC_IPV6_GATEWAY_IFNAME
:
1746 vty_out(vty
, " %s %s",
1748 &si
->addr
.ipv6
, buf
,
1755 vty_out(vty
, " tag %" ROUTE_TAG_PRI
,
1759 != ZEBRA_STATIC_DISTANCE_DEFAULT
)
1760 vty_out(vty
, " %d", si
->distance
);
1762 if (si
->vrf_id
!= VRF_DEFAULT
)
1763 vty_out(vty
, " vrf %s",
1766 /* Label information */
1767 if (si
->snh_label
.num_labels
)
1768 vty_out(vty
, " label %s",
1772 si
->snh_label
.label
,
1773 buf
, sizeof buf
, 0));
1783 DEFPY(ipv6_route_blackhole
,
1784 ipv6_route_blackhole_cmd
,
1785 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1786 <Null0|reject|blackhole>$flag \
1788 tag (1-4294967295) \
1795 "Establish static routes\n"
1796 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1797 "IPv6 source-dest route\n"
1798 "IPv6 source prefix\n"
1800 "Emit an ICMP unreachable when matched\n"
1801 "Silently discard pkts when matched\n"
1802 "Set tag for this route\n"
1804 "Distance value for this prefix\n"
1808 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1809 NULL
, from_str
, NULL
, NULL
, flag
,
1810 tag_str
, distance_str
, vrf
, label
);
1813 DEFPY(ipv6_route_address_interface
,
1814 ipv6_route_address_interface_cmd
,
1815 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1819 tag (1-4294967295) \
1826 "Establish static routes\n"
1827 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1828 "IPv6 source-dest route\n"
1829 "IPv6 source prefix\n"
1830 "IPv6 gateway address\n"
1831 "IPv6 gateway interface name\n"
1832 "Set tag for this route\n"
1834 "Distance value for this prefix\n"
1838 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1839 NULL
, from_str
, gate_str
, ifname
, NULL
,
1840 tag_str
, distance_str
, vrf
, label
);
1845 "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
1846 <X:X::X:X$gate|INTERFACE$ifname> \
1848 tag (1-4294967295) \
1855 "Establish static routes\n"
1856 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
1857 "IPv6 source-dest route\n"
1858 "IPv6 source prefix\n"
1859 "IPv6 gateway address\n"
1860 "IPv6 gateway interface name\n"
1861 "Set tag for this route\n"
1863 "Distance value for this prefix\n"
1867 return zebra_static_route(vty
, AFI_IP6
, SAFI_UNICAST
, no
, prefix_str
,
1868 NULL
, from_str
, gate_str
, ifname
, NULL
,
1869 tag_str
, distance_str
, vrf
, label
);
1872 DEFUN (show_ipv6_route_addr
,
1873 show_ipv6_route_addr_cmd
,
1874 "show ipv6 route [vrf NAME] X:X::X:X",
1877 "IPv6 routing table\n"
1882 struct prefix_ipv6 p
;
1883 struct route_table
*table
;
1884 struct route_node
*rn
;
1885 vrf_id_t vrf_id
= VRF_DEFAULT
;
1887 if (strmatch(argv
[3]->text
, "vrf")) {
1888 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1889 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1891 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1895 vty_out(vty
, "Malformed IPv6 address\n");
1899 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1903 rn
= route_node_match(table
, (struct prefix
*)&p
);
1905 vty_out(vty
, "%% Network not in table\n");
1909 vty_show_ip_route_detail(vty
, rn
, 0);
1911 route_unlock_node(rn
);
1916 DEFUN (show_ipv6_route_prefix
,
1917 show_ipv6_route_prefix_cmd
,
1918 "show ipv6 route [vrf NAME] X:X::X:X/M",
1921 "IPv6 routing table\n"
1926 struct prefix_ipv6 p
;
1927 struct route_table
*table
;
1928 struct route_node
*rn
;
1929 vrf_id_t vrf_id
= VRF_DEFAULT
;
1931 if (strmatch(argv
[3]->text
, "vrf")) {
1932 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1933 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1935 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1938 vty_out(vty
, "Malformed IPv6 prefix\n");
1942 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1946 rn
= route_node_match(table
, (struct prefix
*)&p
);
1947 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1948 vty_out(vty
, "%% Network not in table\n");
1952 vty_show_ip_route_detail(vty
, rn
, 0);
1954 route_unlock_node(rn
);
1960 /* Show route summary. */
1961 DEFUN (show_ipv6_route_summary
,
1962 show_ipv6_route_summary_cmd
,
1963 "show ipv6 route [vrf NAME] summary",
1966 "IPv6 routing table\n"
1968 "Summary of all IPv6 routes\n")
1970 struct route_table
*table
;
1971 vrf_id_t vrf_id
= VRF_DEFAULT
;
1973 if (strmatch(argv
[3]->text
, "vrf"))
1974 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1976 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1980 vty_show_ip_route_summary(vty
, table
);
1986 /* Show ipv6 route summary prefix. */
1987 DEFUN (show_ipv6_route_summary_prefix
,
1988 show_ipv6_route_summary_prefix_cmd
,
1989 "show ipv6 route [vrf NAME] summary prefix",
1992 "IPv6 routing table\n"
1994 "Summary of all IPv6 routes\n"
1997 struct route_table
*table
;
1998 vrf_id_t vrf_id
= VRF_DEFAULT
;
2000 if (strmatch(argv
[3]->text
, "vrf"))
2001 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2003 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2007 vty_show_ip_route_summary_prefix(vty
, table
);
2014 * Show IPv6 mroute command.Used to dump
2015 * the Multicast routing table.
2017 DEFUN (show_ipv6_mroute
,
2018 show_ipv6_mroute_cmd
,
2019 "show ipv6 mroute [vrf NAME]",
2022 "IPv6 Multicast routing table\n"
2025 struct route_table
*table
;
2026 struct route_node
*rn
;
2027 struct route_entry
*re
;
2029 vrf_id_t vrf_id
= VRF_DEFAULT
;
2032 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2034 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2038 /* Show all IPv6 route. */
2039 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2040 RNODE_FOREACH_RE (rn
, re
) {
2042 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2045 vty_show_ip_route(vty
, rn
, re
, NULL
);
2050 DEFUN (show_ipv6_route_vrf_all_addr
,
2051 show_ipv6_route_vrf_all_addr_cmd
,
2052 "show ipv6 route vrf all X:X::X:X",
2055 "IPv6 routing table\n"
2056 VRF_ALL_CMD_HELP_STR
2061 struct prefix_ipv6 p
;
2062 struct route_table
*table
;
2063 struct route_node
*rn
;
2065 struct zebra_vrf
*zvrf
;
2067 ret
= str2prefix_ipv6(argv
[idx_ipv6
]->arg
, &p
);
2069 vty_out(vty
, "Malformed IPv6 address\n");
2073 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2074 if ((zvrf
= vrf
->info
) == NULL
2075 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2078 rn
= route_node_match(table
, (struct prefix
*)&p
);
2082 vty_show_ip_route_detail(vty
, rn
, 0);
2084 route_unlock_node(rn
);
2090 DEFUN (show_ipv6_route_vrf_all_prefix
,
2091 show_ipv6_route_vrf_all_prefix_cmd
,
2092 "show ipv6 route vrf all X:X::X:X/M",
2095 "IPv6 routing table\n"
2096 VRF_ALL_CMD_HELP_STR
2099 int idx_ipv6_prefixlen
= 5;
2101 struct prefix_ipv6 p
;
2102 struct route_table
*table
;
2103 struct route_node
*rn
;
2105 struct zebra_vrf
*zvrf
;
2107 ret
= str2prefix_ipv6(argv
[idx_ipv6_prefixlen
]->arg
, &p
);
2109 vty_out(vty
, "Malformed IPv6 prefix\n");
2113 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
);
2121 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
2122 route_unlock_node(rn
);
2126 vty_show_ip_route_detail(vty
, rn
, 0);
2128 route_unlock_node(rn
);
2134 DEFUN (show_ipv6_route_vrf_all_summary
,
2135 show_ipv6_route_vrf_all_summary_cmd
,
2136 "show ipv6 route vrf all summary",
2139 "IPv6 routing table\n"
2140 VRF_ALL_CMD_HELP_STR
2141 "Summary of all IPv6 routes\n")
2144 struct zebra_vrf
*zvrf
;
2146 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2147 if ((zvrf
= vrf
->info
) != NULL
)
2148 vty_show_ip_route_summary(
2149 vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2154 DEFUN (show_ipv6_mroute_vrf_all
,
2155 show_ipv6_mroute_vrf_all_cmd
,
2156 "show ipv6 mroute vrf all",
2159 "IPv6 Multicast routing table\n"
2160 VRF_ALL_CMD_HELP_STR
)
2162 struct route_table
*table
;
2163 struct route_node
*rn
;
2164 struct route_entry
*re
;
2166 struct zebra_vrf
*zvrf
;
2169 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2170 if ((zvrf
= vrf
->info
) == NULL
2171 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2174 /* Show all IPv6 route. */
2175 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2176 RNODE_FOREACH_RE (rn
, re
) {
2178 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2181 vty_show_ip_route(vty
, rn
, re
, NULL
);
2187 DEFUN (show_ipv6_route_vrf_all_summary_prefix
,
2188 show_ipv6_route_vrf_all_summary_prefix_cmd
,
2189 "show ipv6 route vrf all summary prefix",
2192 "IPv6 routing table\n"
2193 VRF_ALL_CMD_HELP_STR
2194 "Summary of all IPv6 routes\n"
2198 struct zebra_vrf
*zvrf
;
2200 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2201 if ((zvrf
= vrf
->info
) != NULL
)
2202 vty_show_ip_route_summary_prefix(
2203 vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2208 DEFUN (allow_external_route_update
,
2209 allow_external_route_update_cmd
,
2210 "allow-external-route-update",
2211 "Allow FRR routes to be overwritten by external processes\n")
2218 DEFUN (no_allow_external_route_update
,
2219 no_allow_external_route_update_cmd
,
2220 "no allow-external-route-update",
2222 "Allow FRR routes to be overwritten by external processes\n")
2237 struct zebra_vrf
*zvrf
;
2239 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
2240 if (!(zvrf
= vrf
->info
))
2245 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2246 if (zvrf_id(zvrf
) == VRF_UNKNOWN
)
2247 vty_out(vty
, "inactive");
2249 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2257 DEFUN (show_evpn_vni
,
2259 "show evpn vni [json]",
2262 "VxLAN information\n"
2265 struct zebra_vrf
*zvrf
;
2266 u_char uj
= use_json(argc
, argv
);
2268 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2269 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2273 DEFUN (show_evpn_vni_vni
,
2274 show_evpn_vni_vni_cmd
,
2275 "show evpn vni " CMD_VNI_RANGE
"[json]",
2278 "VxLAN Network Identifier\n"
2282 struct zebra_vrf
*zvrf
;
2284 u_char uj
= use_json(argc
, argv
);
2286 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2287 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2288 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2292 DEFUN (show_evpn_mac_vni
,
2293 show_evpn_mac_vni_cmd
,
2294 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2298 "VxLAN Network Identifier\n"
2302 struct zebra_vrf
*zvrf
;
2304 u_char uj
= use_json(argc
, argv
);
2306 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2307 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2308 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2312 DEFUN (show_evpn_mac_vni_all
,
2313 show_evpn_mac_vni_all_cmd
,
2314 "show evpn mac vni all [json]",
2318 "VxLAN Network Identifier\n"
2322 struct zebra_vrf
*zvrf
;
2323 u_char uj
= use_json(argc
, argv
);
2325 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2326 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
2330 DEFUN (show_evpn_mac_vni_all_vtep
,
2331 show_evpn_mac_vni_all_vtep_cmd
,
2332 "show evpn mac vni all vtep A.B.C.D [json]",
2336 "VxLAN Network Identifier\n"
2339 "Remote VTEP IP address\n"
2342 struct zebra_vrf
*zvrf
;
2343 struct in_addr vtep_ip
;
2344 u_char uj
= use_json(argc
, argv
);
2346 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2348 vty_out(vty
, "%% Malformed VTEP IP address\n");
2351 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2352 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2358 DEFUN (show_evpn_mac_vni_mac
,
2359 show_evpn_mac_vni_mac_cmd
,
2360 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2364 "VxLAN Network Identifier\n"
2367 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2369 struct zebra_vrf
*zvrf
;
2373 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2374 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2375 vty_out(vty
, "%% Malformed MAC address");
2378 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2379 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2383 DEFUN (show_evpn_mac_vni_vtep
,
2384 show_evpn_mac_vni_vtep_cmd
,
2385 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2389 "VxLAN Network Identifier\n"
2392 "Remote VTEP IP address\n"
2395 struct zebra_vrf
*zvrf
;
2397 struct in_addr vtep_ip
;
2398 u_char uj
= use_json(argc
, argv
);
2400 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2401 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2403 vty_out(vty
, "%% Malformed VTEP IP address\n");
2407 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2408 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2412 DEFUN (show_evpn_neigh_vni
,
2413 show_evpn_neigh_vni_cmd
,
2414 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2417 "ARP and ND cache\n"
2418 "VxLAN Network Identifier\n"
2422 struct zebra_vrf
*zvrf
;
2424 u_char uj
= use_json(argc
, argv
);
2426 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2427 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2428 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2432 DEFUN (show_evpn_neigh_vni_all
,
2433 show_evpn_neigh_vni_all_cmd
,
2434 "show evpn arp-cache vni all [json]",
2437 "ARP and ND cache\n"
2438 "VxLAN Network Identifier\n"
2442 struct zebra_vrf
*zvrf
;
2443 u_char uj
= use_json(argc
, argv
);
2445 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2446 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2450 DEFUN (show_evpn_neigh_vni_neigh
,
2451 show_evpn_neigh_vni_neigh_cmd
,
2452 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2455 "ARP and ND cache\n"
2456 "VxLAN Network Identifier\n"
2459 "Neighbor address (IPv4 or IPv6 address)\n"
2462 struct zebra_vrf
*zvrf
;
2465 u_char uj
= use_json(argc
, argv
);
2467 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2468 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2470 vty_out(vty
, "%% Malformed Neighbor address\n");
2473 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2474 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2478 DEFUN (show_evpn_neigh_vni_vtep
,
2479 show_evpn_neigh_vni_vtep_cmd
,
2480 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2483 "ARP and ND cache\n"
2484 "VxLAN Network Identifier\n"
2487 "Remote VTEP IP address\n"
2490 struct zebra_vrf
*zvrf
;
2492 struct in_addr vtep_ip
;
2493 u_char uj
= use_json(argc
, argv
);
2495 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2496 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2498 vty_out(vty
, "%% Malformed VTEP IP address\n");
2502 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2503 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2507 /* Static ip route configuration write function. */
2508 static int zebra_ip_config(struct vty
*vty
)
2512 write
+= static_config(vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
2513 write
+= static_config(vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
2514 write
+= static_config(vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
2516 write
+= zebra_import_table_config(vty
);
2520 DEFUN (ip_zebra_import_table_distance
,
2521 ip_zebra_import_table_distance_cmd
,
2522 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2524 "import routes from non-main kernel table\n"
2525 "kernel routing table id\n"
2526 "Distance for imported routes\n"
2527 "Default distance value\n"
2528 "route-map for filtering\n"
2531 u_int32_t table_id
= 0;
2533 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2534 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2536 strmatch(argv
[argc
- 2]->text
, "route-map")
2537 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2541 if (argc
== 7 || (argc
== 5 && !rmap
))
2542 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2544 if (!is_zebra_valid_kernel_table(table_id
)) {
2546 "Invalid routing table ID, %d. Must be in range 1-252\n",
2549 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2553 if (is_zebra_main_routing_table(table_id
)) {
2555 "Invalid routing table ID, %d. Must be non-default table\n",
2558 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2562 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2564 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2569 DEFUN (no_ip_zebra_import_table
,
2570 no_ip_zebra_import_table_cmd
,
2571 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2574 "import routes from non-main kernel table\n"
2575 "kernel routing table id\n"
2576 "Distance for imported routes\n"
2577 "Default distance value\n"
2578 "route-map for filtering\n"
2581 u_int32_t table_id
= 0;
2582 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2584 if (!is_zebra_valid_kernel_table(table_id
)) {
2586 "Invalid routing table ID. Must be in range 1-252\n");
2590 if (is_zebra_main_routing_table(table_id
)) {
2592 "Invalid routing table ID, %d. Must be non-default table\n",
2597 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2600 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2603 static int config_write_protocol(struct vty
*vty
)
2606 vty_out(vty
, "allow-external-route-update\n");
2608 if (zebra_rnh_ip_default_route
)
2609 vty_out(vty
, "ip nht resolve-via-default\n");
2611 if (zebra_rnh_ipv6_default_route
)
2612 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2614 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2616 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2617 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2618 ipv4_multicast_mode
== MCAST_URIB_ONLY
2620 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2622 : ipv4_multicast_mode
2623 == MCAST_MIX_MRIB_FIRST
2625 : ipv4_multicast_mode
2626 == MCAST_MIX_DISTANCE
2630 zebra_routemap_config_write_protocol(vty
);
2635 /* IP node for static routes. */
2636 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2637 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2640 void zebra_vty_init(void)
2642 install_node(&ip_node
, zebra_ip_config
);
2643 install_node(&protocol_node
, config_write_protocol
);
2645 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2646 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2647 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
2648 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2649 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2650 install_element(CONFIG_NODE
, &ip_route_blackhole_cmd
);
2651 install_element(CONFIG_NODE
, &ip_route_address_interface_cmd
);
2652 install_element(CONFIG_NODE
, &ip_route_cmd
);
2653 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2654 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2656 install_element(VIEW_NODE
, &show_vrf_cmd
);
2657 install_element(VIEW_NODE
, &show_route_cmd
);
2658 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2659 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2660 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2661 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2662 install_element(VIEW_NODE
, &show_ip_route_addr_cmd
);
2663 install_element(VIEW_NODE
, &show_ip_route_prefix_cmd
);
2664 install_element(VIEW_NODE
, &show_ip_route_summary_cmd
);
2665 install_element(VIEW_NODE
, &show_ip_route_summary_prefix_cmd
);
2667 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2668 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2670 install_element(VIEW_NODE
, &show_ip_route_vrf_all_addr_cmd
);
2671 install_element(VIEW_NODE
, &show_ip_route_vrf_all_prefix_cmd
);
2672 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_cmd
);
2673 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_prefix_cmd
);
2675 install_element(CONFIG_NODE
, &ipv6_route_blackhole_cmd
);
2676 install_element(CONFIG_NODE
, &ipv6_route_address_interface_cmd
);
2677 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
2678 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2679 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2680 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2681 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2682 install_element(VIEW_NODE
, &show_ipv6_route_summary_cmd
);
2683 install_element(VIEW_NODE
, &show_ipv6_route_summary_prefix_cmd
);
2684 install_element(VIEW_NODE
, &show_ipv6_route_addr_cmd
);
2685 install_element(VIEW_NODE
, &show_ipv6_route_prefix_cmd
);
2686 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2688 /* Commands for VRF */
2689 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_cmd
);
2690 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_prefix_cmd
);
2691 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_addr_cmd
);
2692 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_prefix_cmd
);
2694 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2696 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2697 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2698 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2699 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2700 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2701 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2702 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2703 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2704 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2705 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2706 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);