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
;
77 enum static_blackhole_type bh_type
= 0;
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)) {
171 bh_type
= STATIC_BLACKHOLE_NULL
;
177 switch (flag_str
[0]) {
179 bh_type
= STATIC_BLACKHOLE_REJECT
;
182 bh_type
= STATIC_BLACKHOLE_DROP
;
185 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
186 return CMD_WARNING_CONFIG_FAILED
;
191 if (inet_pton(afi2family(afi
), gate_str
, &gate
) != 1) {
192 vty_out(vty
, "%% Malformed nexthop address %s\n",
194 return CMD_WARNING_CONFIG_FAILED
;
199 if (gate_str
== NULL
&& ifname
== NULL
)
200 type
= STATIC_BLACKHOLE
;
201 else if (gate_str
&& ifname
) {
203 type
= STATIC_IPV4_GATEWAY_IFNAME
;
205 type
= STATIC_IPV6_GATEWAY_IFNAME
;
207 type
= STATIC_IFNAME
;
210 type
= STATIC_IPV4_GATEWAY
;
212 type
= STATIC_IPV6_GATEWAY
;
216 static_add_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
217 bh_type
, tag
, distance
, zvrf
, &snh_label
);
219 static_delete_route(afi
, safi
, type
, &p
, src_p
, gatep
, ifname
,
220 tag
, distance
, zvrf
, &snh_label
);
225 /* Static unicast routes for multicast RPF lookup. */
226 DEFPY (ip_mroute_dist
,
228 "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
231 "Configure static unicast route into MRIB for multicast RPF lookup\n"
232 "IP destination prefix (e.g. 10.0.0.0/8)\n"
234 "Nexthop interface name\n"
237 return zebra_static_route(vty
, AFI_IP
, SAFI_MULTICAST
, no
, prefix_str
,
238 NULL
, NULL
, gate_str
, ifname
, NULL
, NULL
,
239 distance_str
, NULL
, NULL
);
242 DEFUN (ip_multicast_mode
,
243 ip_multicast_mode_cmd
,
244 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
246 "Multicast options\n"
247 "RPF lookup behavior\n"
248 "Lookup in unicast RIB only\n"
249 "Lookup in multicast RIB only\n"
250 "Try multicast RIB first, fall back to unicast RIB\n"
251 "Lookup both, use entry with lower distance\n"
252 "Lookup both, use entry with longer prefix\n")
254 char *mode
= argv
[3]->text
;
256 if (strmatch(mode
, "urib-only"))
257 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
258 else if (strmatch(mode
, "mrib-only"))
259 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
260 else if (strmatch(mode
, "mrib-then-urib"))
261 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
262 else if (strmatch(mode
, "lower-distance"))
263 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
264 else if (strmatch(mode
, "longer-prefix"))
265 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
267 vty_out(vty
, "Invalid mode specified\n");
268 return CMD_WARNING_CONFIG_FAILED
;
274 DEFUN (no_ip_multicast_mode
,
275 no_ip_multicast_mode_cmd
,
276 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
279 "Multicast options\n"
280 "RPF lookup behavior\n"
281 "Lookup in unicast RIB only\n"
282 "Lookup in multicast RIB only\n"
283 "Try multicast RIB first, fall back to unicast RIB\n"
284 "Lookup both, use entry with lower distance\n"
285 "Lookup both, use entry with longer prefix\n")
287 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
294 "show ip rpf [json]",
297 "Display RPF information for multicast source\n"
300 int uj
= use_json(argc
, argv
);
301 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
302 false, uj
, 0, NULL
, false, -1, 0);
305 DEFUN (show_ip_rpf_addr
,
306 show_ip_rpf_addr_cmd
,
307 "show ip rpf A.B.C.D",
310 "Display RPF information for multicast source\n"
311 "IP multicast source address (e.g. 10.0.0.0)\n")
315 struct route_node
*rn
;
316 struct route_entry
*re
;
319 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
321 vty_out(vty
, "%% Malformed address\n");
325 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
328 vty_show_ip_route_detail(vty
, rn
, 1);
330 vty_out(vty
, "%% No match for RPF lookup\n");
335 /* Static route configuration. */
336 DEFPY(ip_route
, ip_route_cmd
,
338 <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
340 {A.B.C.D$gate|INTERFACE$ifname}\
342 |<reject|blackhole>$flag\
351 "Establish static routes\n"
352 "IP destination prefix (e.g. 10.0.0.0/8)\n"
353 "IP destination prefix\n"
354 "IP destination prefix mask\n"
355 "IP gateway address\n"
356 "IP gateway interface name\n"
358 "Emit an ICMP unreachable when matched\n"
359 "Silently discard pkts when matched\n"
360 "Set tag for this route\n"
362 "Distance value for this route\n"
366 return zebra_static_route(vty
, AFI_IP
, SAFI_UNICAST
, no
, prefix
,
367 mask_str
, NULL
, gate_str
, ifname
, flag
,
368 tag_str
, distance_str
, vrf
, label
);
372 /* New RIB. Detailed information for IPv4 route. */
373 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
376 struct route_entry
*re
;
377 struct nexthop
*nexthop
;
378 char buf
[SRCDEST2STR_BUFFER
];
379 struct zebra_vrf
*zvrf
;
381 RNODE_FOREACH_RE(rn
, re
)
383 const char *mcast_info
= "";
385 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
386 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
387 ? " using Multicast RIB"
388 : " using Unicast RIB";
391 vty_out(vty
, "Routing entry for %s%s\n",
392 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
393 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
395 vty_out(vty
, "[%d]", re
->instance
);
397 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
400 vty_out(vty
, ", tag %d", re
->tag
);
402 vty_out(vty
, ", mtu %u", re
->mtu
);
403 if (re
->vrf_id
!= VRF_DEFAULT
) {
404 zvrf
= vrf_info_lookup(re
->vrf_id
);
405 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
407 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
408 vty_out(vty
, ", best");
415 uptime
-= re
->uptime
;
416 tm
= gmtime(&uptime
);
418 vty_out(vty
, " Last update ");
420 if (uptime
< ONE_DAY_SECOND
)
421 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
422 tm
->tm_min
, tm
->tm_sec
);
423 else if (uptime
< ONE_WEEK_SECOND
)
424 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
425 tm
->tm_hour
, tm
->tm_min
);
427 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
428 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
430 vty_out(vty
, " ago\n");
432 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
435 vty_out(vty
, " %c%s",
436 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
437 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
440 nexthop
->rparent
? " " : "");
442 switch (nexthop
->type
) {
443 case NEXTHOP_TYPE_IPV4
:
444 case NEXTHOP_TYPE_IPV4_IFINDEX
:
446 inet_ntoa(nexthop
->gate
.ipv4
));
447 if (nexthop
->ifindex
)
448 vty_out(vty
, ", via %s",
449 ifindex2ifname(nexthop
->ifindex
,
452 case NEXTHOP_TYPE_IPV6
:
453 case NEXTHOP_TYPE_IPV6_IFINDEX
:
455 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
457 if (nexthop
->ifindex
)
458 vty_out(vty
, ", via %s",
459 ifindex2ifname(nexthop
->ifindex
,
462 case NEXTHOP_TYPE_IFINDEX
:
463 vty_out(vty
, " directly connected, %s",
464 ifindex2ifname(nexthop
->ifindex
,
467 case NEXTHOP_TYPE_BLACKHOLE
:
468 vty_out(vty
, " unreachable");
469 switch (nexthop
->bh_type
) {
470 case BLACKHOLE_REJECT
:
471 vty_out(vty
, " (ICMP unreachable)");
473 case BLACKHOLE_ADMINPROHIB
:
475 " (ICMP admin-prohibited)");
478 vty_out(vty
, " (blackhole)");
480 case BLACKHOLE_UNSPEC
:
487 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
488 vty_out(vty
, " (duplicate nexthop removed)");
490 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
491 vty_out(vty
, " inactive");
493 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
494 vty_out(vty
, " onlink");
496 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
497 vty_out(vty
, " (recursive)");
499 switch (nexthop
->type
) {
500 case NEXTHOP_TYPE_IPV4
:
501 case NEXTHOP_TYPE_IPV4_IFINDEX
:
502 if (nexthop
->src
.ipv4
.s_addr
) {
503 if (inet_ntop(AF_INET
,
505 addrstr
, sizeof addrstr
))
506 vty_out(vty
, ", src %s",
510 case NEXTHOP_TYPE_IPV6
:
511 case NEXTHOP_TYPE_IPV6_IFINDEX
:
512 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
514 if (inet_ntop(AF_INET6
,
516 addrstr
, sizeof addrstr
))
517 vty_out(vty
, ", src %s",
526 vty_out(vty
, ", mtu %u", re
->nexthop_mtu
);
528 /* Label information */
529 if (nexthop
->nh_label
530 && nexthop
->nh_label
->num_labels
) {
531 vty_out(vty
, ", label %s",
533 nexthop
->nh_label
->num_labels
,
534 nexthop
->nh_label
->label
, buf
,
544 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
545 struct route_entry
*re
, json_object
*json
)
547 struct nexthop
*nexthop
;
549 char buf
[SRCDEST2STR_BUFFER
];
550 json_object
*json_nexthops
= NULL
;
551 json_object
*json_nexthop
= NULL
;
552 json_object
*json_route
= NULL
;
553 json_object
*json_labels
= NULL
;
558 uptime
-= re
->uptime
;
559 tm
= gmtime(&uptime
);
562 json_route
= json_object_new_object();
563 json_nexthops
= json_object_new_array();
565 json_object_string_add(json_route
, "prefix",
566 srcdest_rnode2str(rn
, buf
, sizeof buf
));
567 json_object_string_add(json_route
, "protocol",
568 zebra_route_string(re
->type
));
571 json_object_int_add(json_route
, "instance",
575 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
577 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
578 json_object_boolean_true_add(json_route
, "selected");
580 if (re
->type
!= ZEBRA_ROUTE_CONNECT
) {
581 json_object_int_add(json_route
, "distance",
583 json_object_int_add(json_route
, "metric", re
->metric
);
586 if (uptime
< ONE_DAY_SECOND
)
587 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
588 tm
->tm_min
, tm
->tm_sec
);
589 else if (uptime
< ONE_WEEK_SECOND
)
590 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
591 tm
->tm_hour
, tm
->tm_min
);
593 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
594 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
597 json_object_string_add(json_route
, "uptime", buf
);
599 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
600 json_nexthop
= json_object_new_object();
602 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
603 json_object_boolean_true_add(json_nexthop
,
606 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
607 json_object_boolean_true_add(json_nexthop
,
610 switch (nexthop
->type
) {
611 case NEXTHOP_TYPE_IPV4
:
612 case NEXTHOP_TYPE_IPV4_IFINDEX
:
613 json_object_string_add(
615 inet_ntoa(nexthop
->gate
.ipv4
));
616 json_object_string_add(json_nexthop
, "afi",
619 if (nexthop
->ifindex
) {
620 json_object_int_add(json_nexthop
,
623 json_object_string_add(
624 json_nexthop
, "interfaceName",
625 ifindex2ifname(nexthop
->ifindex
,
629 case NEXTHOP_TYPE_IPV6
:
630 case NEXTHOP_TYPE_IPV6_IFINDEX
:
631 json_object_string_add(
633 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
635 json_object_string_add(json_nexthop
, "afi",
638 if (nexthop
->ifindex
) {
639 json_object_int_add(json_nexthop
,
642 json_object_string_add(
643 json_nexthop
, "interfaceName",
644 ifindex2ifname(nexthop
->ifindex
,
649 case NEXTHOP_TYPE_IFINDEX
:
650 json_object_boolean_true_add(
651 json_nexthop
, "directlyConnected");
652 json_object_int_add(json_nexthop
,
655 json_object_string_add(
656 json_nexthop
, "interfaceName",
657 ifindex2ifname(nexthop
->ifindex
,
660 case NEXTHOP_TYPE_BLACKHOLE
:
661 json_object_boolean_true_add(json_nexthop
,
663 switch (nexthop
->bh_type
) {
664 case BLACKHOLE_REJECT
:
665 json_object_boolean_true_add(
666 json_nexthop
, "reject");
668 case BLACKHOLE_ADMINPROHIB
:
669 json_object_boolean_true_add(
674 json_object_boolean_true_add(
675 json_nexthop
, "blackhole");
677 case BLACKHOLE_UNSPEC
:
685 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
))
686 json_object_boolean_true_add(json_nexthop
,
689 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
690 json_object_boolean_true_add(json_nexthop
,
693 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
694 json_object_boolean_true_add(json_nexthop
,
697 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
698 json_object_boolean_true_add(json_nexthop
,
701 switch (nexthop
->type
) {
702 case NEXTHOP_TYPE_IPV4
:
703 case NEXTHOP_TYPE_IPV4_IFINDEX
:
704 if (nexthop
->src
.ipv4
.s_addr
) {
705 if (inet_ntop(AF_INET
,
706 &nexthop
->src
.ipv4
, buf
,
708 json_object_string_add(
709 json_nexthop
, "source",
713 case NEXTHOP_TYPE_IPV6
:
714 case NEXTHOP_TYPE_IPV6_IFINDEX
:
715 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
717 if (inet_ntop(AF_INET6
,
718 &nexthop
->src
.ipv6
, buf
,
720 json_object_string_add(
721 json_nexthop
, "source",
729 if (nexthop
->nh_label
730 && nexthop
->nh_label
->num_labels
) {
731 json_labels
= json_object_new_array();
733 for (int label_index
= 0;
735 < nexthop
->nh_label
->num_labels
;
737 json_object_array_add(
740 nexthop
->nh_label
->label
743 json_object_object_add(json_nexthop
, "labels",
747 json_object_array_add(json_nexthops
, json_nexthop
);
750 json_object_object_add(json_route
, "nexthops", json_nexthops
);
751 json_object_array_add(json
, json_route
);
755 /* Nexthop information. */
756 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
757 if (nexthop
== re
->nexthop
) {
758 /* Prefix information. */
759 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
761 len
+= vty_out(vty
, "[%d]", re
->instance
);
764 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
767 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
770 srcdest_rnode2str(rn
, buf
, sizeof buf
));
772 /* Distance and metric display. */
773 if (re
->type
!= ZEBRA_ROUTE_CONNECT
)
774 len
+= vty_out(vty
, " [%d/%d]", re
->distance
,
777 vty_out(vty
, " %c%*c",
778 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
779 ? CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_DUPLICATE
)
782 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
785 switch (nexthop
->type
) {
786 case NEXTHOP_TYPE_IPV4
:
787 case NEXTHOP_TYPE_IPV4_IFINDEX
:
788 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
789 if (nexthop
->ifindex
)
791 ifindex2ifname(nexthop
->ifindex
,
794 case NEXTHOP_TYPE_IPV6
:
795 case NEXTHOP_TYPE_IPV6_IFINDEX
:
796 vty_out(vty
, " via %s",
797 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
799 if (nexthop
->ifindex
)
801 ifindex2ifname(nexthop
->ifindex
,
805 case NEXTHOP_TYPE_IFINDEX
:
806 vty_out(vty
, " is directly connected, %s",
807 ifindex2ifname(nexthop
->ifindex
, re
->vrf_id
));
809 case NEXTHOP_TYPE_BLACKHOLE
:
810 vty_out(vty
, " unreachable");
811 switch (nexthop
->bh_type
) {
812 case BLACKHOLE_REJECT
:
813 vty_out(vty
, " (ICMP unreachable)");
815 case BLACKHOLE_ADMINPROHIB
:
816 vty_out(vty
, " (ICMP admin-prohibited)");
819 vty_out(vty
, " (blackhole)");
821 case BLACKHOLE_UNSPEC
:
828 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
829 vty_out(vty
, " inactive");
831 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
832 vty_out(vty
, " onlink");
834 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
835 vty_out(vty
, " (recursive)");
837 switch (nexthop
->type
) {
838 case NEXTHOP_TYPE_IPV4
:
839 case NEXTHOP_TYPE_IPV4_IFINDEX
:
840 if (nexthop
->src
.ipv4
.s_addr
) {
841 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
843 vty_out(vty
, ", src %s", buf
);
846 case NEXTHOP_TYPE_IPV6
:
847 case NEXTHOP_TYPE_IPV6_IFINDEX
:
848 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
849 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
851 vty_out(vty
, ", src %s", buf
);
858 /* Label information */
859 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
860 vty_out(vty
, ", label %s",
861 mpls_label2str(nexthop
->nh_label
->num_labels
,
862 nexthop
->nh_label
->label
, buf
,
866 if (uptime
< ONE_DAY_SECOND
)
867 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
868 tm
->tm_min
, tm
->tm_sec
);
869 else if (uptime
< ONE_WEEK_SECOND
)
870 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
871 tm
->tm_hour
, tm
->tm_min
);
873 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
874 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
880 static bool use_fib(struct cmd_token
*token
)
882 return strncmp(token
->arg
, "route", strlen(token
->arg
));
885 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
886 safi_t safi
, bool use_fib
, u_char use_json
,
887 route_tag_t tag
, struct prefix
*longer_prefix_p
,
888 bool supernets_only
, int type
,
889 u_short ospf_instance_id
)
891 struct route_table
*table
;
892 struct route_node
*rn
;
893 struct route_entry
*re
;
895 struct zebra_vrf
*zvrf
= NULL
;
897 json_object
*json
= NULL
;
898 json_object
*json_prefix
= NULL
;
901 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
903 vty_out(vty
, "{}\n");
905 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
909 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
911 vty_out(vty
, "{}\n");
913 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
917 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
920 vty_out(vty
, "{}\n");
925 json
= json_object_new_object();
927 /* Show all routes. */
928 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
929 RNODE_FOREACH_RE(rn
, re
)
932 && !CHECK_FLAG(re
->status
,
933 ROUTE_ENTRY_SELECTED_FIB
))
936 if (tag
&& re
->tag
!= tag
)
940 && !prefix_match(longer_prefix_p
, &rn
->p
))
943 /* This can only be true when the afi is IPv4 */
944 if (supernets_only
) {
945 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
947 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
950 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
953 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
957 if (type
&& re
->type
!= type
)
961 && (re
->type
!= ZEBRA_ROUTE_OSPF
962 || re
->instance
!= ospf_instance_id
))
967 json_prefix
= json_object_new_array();
972 SHOW_ROUTE_V4_HEADER
);
975 SHOW_ROUTE_V6_HEADER
);
977 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
978 vty_out(vty
, "\nVRF %s:\n",
985 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
989 prefix2str(&rn
->p
, buf
, sizeof buf
);
990 json_object_object_add(json
, buf
, json_prefix
);
996 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
997 json
, JSON_C_TO_STRING_PRETTY
));
998 json_object_free(json
);
1006 "show ip nht [vrf NAME]",
1009 "IP nexthop tracking table\n"
1013 vrf_id_t vrf_id
= VRF_DEFAULT
;
1016 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1018 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1023 DEFUN (show_ip_nht_vrf_all
,
1024 show_ip_nht_vrf_all_cmd
,
1025 "show ip nht vrf all",
1028 "IP nexthop tracking table\n"
1029 VRF_ALL_CMD_HELP_STR
)
1032 struct zebra_vrf
*zvrf
;
1034 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1035 if ((zvrf
= vrf
->info
) != NULL
) {
1036 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1037 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1044 DEFUN (show_ipv6_nht
,
1046 "show ipv6 nht [vrf NAME]",
1049 "IPv6 nexthop tracking table\n"
1053 vrf_id_t vrf_id
= VRF_DEFAULT
;
1056 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1058 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1063 DEFUN (show_ipv6_nht_vrf_all
,
1064 show_ipv6_nht_vrf_all_cmd
,
1065 "show ipv6 nht vrf all",
1068 "IPv6 nexthop tracking table\n"
1069 VRF_ALL_CMD_HELP_STR
)
1072 struct zebra_vrf
*zvrf
;
1074 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1075 if ((zvrf
= vrf
->info
) != NULL
) {
1076 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1077 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1084 DEFUN (ip_nht_default_route
,
1085 ip_nht_default_route_cmd
,
1086 "ip nht resolve-via-default",
1088 "Filter Next Hop tracking route resolution\n"
1089 "Resolve via default route\n")
1091 if (zebra_rnh_ip_default_route
)
1094 zebra_rnh_ip_default_route
= 1;
1095 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1099 DEFUN (no_ip_nht_default_route
,
1100 no_ip_nht_default_route_cmd
,
1101 "no ip nht resolve-via-default",
1104 "Filter Next Hop tracking route resolution\n"
1105 "Resolve via default route\n")
1107 if (!zebra_rnh_ip_default_route
)
1110 zebra_rnh_ip_default_route
= 0;
1111 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1115 DEFUN (ipv6_nht_default_route
,
1116 ipv6_nht_default_route_cmd
,
1117 "ipv6 nht resolve-via-default",
1119 "Filter Next Hop tracking route resolution\n"
1120 "Resolve via default route\n")
1122 if (zebra_rnh_ipv6_default_route
)
1125 zebra_rnh_ipv6_default_route
= 1;
1126 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1130 DEFUN (no_ipv6_nht_default_route
,
1131 no_ipv6_nht_default_route_cmd
,
1132 "no ipv6 nht resolve-via-default",
1135 "Filter Next Hop tracking route resolution\n"
1136 "Resolve via default route\n")
1138 if (!zebra_rnh_ipv6_default_route
)
1141 zebra_rnh_ipv6_default_route
= 0;
1142 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1146 DEFUN (show_ip_route
,
1148 "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]",
1151 "IP forwarding table\n"
1152 "IP routing table\n"
1154 "Show only routes with tag\n"
1156 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1157 "Show route matching the specified Network/Mask pair only\n"
1158 "Show supernet entries only\n"
1159 FRR_IP_REDIST_HELP_STR_ZEBRA
1160 "Open Shortest Path First (OSPFv2)\n"
1164 bool uf
= use_fib(argv
[2]);
1165 struct route_table
*table
;
1167 route_tag_t tag
= 0;
1168 vrf_id_t vrf_id
= VRF_DEFAULT
;
1170 struct zebra_vrf
*zvrf
;
1171 int uj
= use_json(argc
, argv
);
1174 bool longer_prefixes
= false;
1175 bool supernets_only
= false;
1177 u_short ospf_instance_id
= 0;
1179 if (argv_find(argv
, argc
, "vrf", &idx
)) {
1180 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
1183 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
1186 if (argv_find(argv
, argc
, "tag", &idx
))
1187 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
1189 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)) {
1190 if (str2prefix(argv
[idx
]->arg
, &p
) <= 0) {
1191 vty_out(vty
, "%% Malformed prefix\n");
1194 longer_prefixes
= true;
1197 else if (argv_find(argv
, argc
, "supernets_only", &idx
))
1198 supernets_only
= true;
1201 if (argv_find(argv
, argc
, "kernel", &idx
))
1202 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1203 else if (argv_find(argv
, argc
, "babel", &idx
))
1204 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1205 else if (argv_find(argv
, argc
, "connected", &idx
))
1206 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1207 else if (argv_find(argv
, argc
, "static", &idx
))
1208 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1209 else if (argv_find(argv
, argc
, "rip", &idx
))
1210 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1211 else if (argv_find(argv
, argc
, "ospf", &idx
))
1212 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1213 else if (argv_find(argv
, argc
, "isis", &idx
))
1214 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1215 else if (argv_find(argv
, argc
, "bgp", &idx
))
1216 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1217 else if (argv_find(argv
, argc
, "pim", &idx
))
1218 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1219 else if (argv_find(argv
, argc
, "eigrp", &idx
))
1220 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1221 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1222 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1223 else if (argv_find(argv
, argc
, "table", &idx
))
1224 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1225 else if (argv_find(argv
, argc
, "vnc", &idx
))
1226 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1228 if (argv_find(argv
, argc
, "(1-65535)", &idx
))
1229 ospf_instance_id
= strtoul(argv
[idx
]->arg
, NULL
, 10);
1232 vty_out(vty
, "Unknown route type\n");
1238 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1240 if ((zvrf
= vrf
->info
) == NULL
1241 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
1246 vty
, zvrf_name(zvrf
), AFI_IP
, SAFI_UNICAST
, uf
,
1247 uj
, tag
, longer_prefixes
? &p
: NULL
,
1248 supernets_only
, type
, ospf_instance_id
);
1251 vrf
= vrf_lookup_by_id(vrf_id
);
1252 do_show_ip_route(vty
, vrf
->name
, AFI_IP
, SAFI_UNICAST
, uf
, uj
,
1253 tag
, longer_prefixes
? &p
: NULL
,
1254 supernets_only
, type
, ospf_instance_id
);
1259 DEFUN (show_ip_route_addr
,
1260 show_ip_route_addr_cmd
,
1261 "show ip route [vrf NAME] A.B.C.D",
1264 "IP routing table\n"
1266 "Network in the IP routing table to display\n")
1269 struct prefix_ipv4 p
;
1270 struct route_table
*table
;
1271 struct route_node
*rn
;
1272 vrf_id_t vrf_id
= VRF_DEFAULT
;
1274 if (strmatch(argv
[3]->text
, "vrf")) {
1275 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1276 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1278 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1282 vty_out(vty
, "%% Malformed IPv4 address\n");
1286 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1290 rn
= route_node_match(table
, (struct prefix
*)&p
);
1292 vty_out(vty
, "%% Network not in table\n");
1296 vty_show_ip_route_detail(vty
, rn
, 0);
1298 route_unlock_node(rn
);
1303 DEFUN (show_ip_route_prefix
,
1304 show_ip_route_prefix_cmd
,
1305 "show ip route [vrf NAME] A.B.C.D/M",
1308 "IP routing table\n"
1310 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1313 struct prefix_ipv4 p
;
1314 struct route_table
*table
;
1315 struct route_node
*rn
;
1316 vrf_id_t vrf_id
= VRF_DEFAULT
;
1318 if (strmatch(argv
[3]->text
, "vrf")) {
1319 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1320 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1322 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1326 vty_out(vty
, "%% Malformed IPv4 address\n");
1330 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1334 rn
= route_node_match(table
, (struct prefix
*)&p
);
1335 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1336 vty_out(vty
, "%% Network not in table\n");
1340 vty_show_ip_route_detail(vty
, rn
, 0);
1342 route_unlock_node(rn
);
1348 static void vty_show_ip_route_summary(struct vty
*vty
,
1349 struct route_table
*table
)
1351 struct route_node
*rn
;
1352 struct route_entry
*re
;
1353 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1354 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1355 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1356 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1360 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1361 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1362 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1363 RNODE_FOREACH_RE(rn
, re
)
1365 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1366 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1368 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1370 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1372 rib_cnt
[re
->type
]++;
1374 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1375 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1378 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1380 fib_cnt
[re
->type
]++;
1384 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1385 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1387 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1388 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1389 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1390 if (i
== ZEBRA_ROUTE_BGP
) {
1391 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1392 rib_cnt
[ZEBRA_ROUTE_BGP
],
1393 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1394 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1395 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1396 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1398 vty_out(vty
, "%-20s %-20d %-20d \n",
1399 zebra_route_string(i
), rib_cnt
[i
],
1404 vty_out(vty
, "------\n");
1405 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1406 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1411 * Implementation of the ip route summary prefix command.
1413 * This command prints the primary prefixes that have been installed by various
1414 * protocols on the box.
1417 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1418 struct route_table
*table
)
1420 struct route_node
*rn
;
1421 struct route_entry
*re
;
1422 struct nexthop
*nexthop
;
1423 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1424 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1425 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1426 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1430 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1431 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1432 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1433 RNODE_FOREACH_RE(rn
, re
)
1437 * In case of ECMP, count only once.
1440 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1441 nexthop
= nexthop
->next
) {
1443 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1444 rib_cnt
[re
->type
]++;
1445 if (CHECK_FLAG(nexthop
->flags
,
1446 NEXTHOP_FLAG_FIB
)) {
1447 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1448 fib_cnt
[re
->type
]++;
1450 if (re
->type
== ZEBRA_ROUTE_BGP
1451 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1452 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1453 if (CHECK_FLAG(nexthop
->flags
,
1455 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1460 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1461 "Prefix Routes", "FIB",
1462 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1464 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1465 if (rib_cnt
[i
] > 0) {
1466 if (i
== ZEBRA_ROUTE_BGP
) {
1467 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1468 rib_cnt
[ZEBRA_ROUTE_BGP
]
1469 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1470 fib_cnt
[ZEBRA_ROUTE_BGP
]
1471 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1472 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1473 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1474 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1476 vty_out(vty
, "%-20s %-20d %-20d \n",
1477 zebra_route_string(i
), rib_cnt
[i
],
1482 vty_out(vty
, "------\n");
1483 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1484 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1488 /* Show route summary. */
1489 DEFUN (show_ip_route_summary
,
1490 show_ip_route_summary_cmd
,
1491 "show ip route [vrf NAME] summary",
1494 "IP routing table\n"
1496 "Summary of all routes\n")
1498 struct route_table
*table
;
1499 vrf_id_t vrf_id
= VRF_DEFAULT
;
1501 if (strmatch(argv
[3]->text
, "vrf"))
1502 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1504 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1508 vty_show_ip_route_summary(vty
, table
);
1513 /* Show route summary prefix. */
1514 DEFUN (show_ip_route_summary_prefix
,
1515 show_ip_route_summary_prefix_cmd
,
1516 "show ip route [vrf NAME] summary prefix",
1519 "IP routing table\n"
1521 "Summary of all routes\n"
1524 struct route_table
*table
;
1525 vrf_id_t vrf_id
= VRF_DEFAULT
;
1527 if (strmatch(argv
[3]->text
, "vrf"))
1528 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1530 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1534 vty_show_ip_route_summary_prefix(vty
, table
);
1540 DEFUN (show_ip_route_vrf_all_addr
,
1541 show_ip_route_vrf_all_addr_cmd
,
1542 "show ip route vrf all A.B.C.D",
1545 "IP routing table\n"
1546 VRF_ALL_CMD_HELP_STR
1547 "Network in the IP routing table to display\n")
1551 struct prefix_ipv4 p
;
1552 struct route_table
*table
;
1553 struct route_node
*rn
;
1555 struct zebra_vrf
*zvrf
;
1557 ret
= str2prefix_ipv4(argv
[idx_ipv4
]->arg
, &p
);
1559 vty_out(vty
, "%% Malformed IPv4 address\n");
1563 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1565 if ((zvrf
= vrf
->info
) == NULL
1566 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1569 rn
= route_node_match(table
, (struct prefix
*)&p
);
1573 vty_show_ip_route_detail(vty
, rn
, 0);
1575 route_unlock_node(rn
);
1581 DEFUN (show_ip_route_vrf_all_prefix
,
1582 show_ip_route_vrf_all_prefix_cmd
,
1583 "show ip route vrf all A.B.C.D/M",
1586 "IP routing table\n"
1587 VRF_ALL_CMD_HELP_STR
1588 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1590 int idx_ipv4_prefixlen
= 5;
1592 struct prefix_ipv4 p
;
1593 struct route_table
*table
;
1594 struct route_node
*rn
;
1596 struct zebra_vrf
*zvrf
;
1598 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
1600 vty_out(vty
, "%% Malformed IPv4 address\n");
1604 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1606 if ((zvrf
= vrf
->info
) == NULL
1607 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1610 rn
= route_node_match(table
, (struct prefix
*)&p
);
1613 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
1614 route_unlock_node(rn
);
1618 vty_show_ip_route_detail(vty
, rn
, 0);
1620 route_unlock_node(rn
);
1626 DEFUN (show_ip_route_vrf_all_summary
,
1627 show_ip_route_vrf_all_summary_cmd
,
1628 "show ip route vrf all summary ",
1631 "IP routing table\n"
1632 VRF_ALL_CMD_HELP_STR
1633 "Summary of all routes\n")
1636 struct zebra_vrf
*zvrf
;
1638 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1639 if ((zvrf
= vrf
->info
) != NULL
)
1640 vty_show_ip_route_summary(vty
,
1641 zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1646 DEFUN (show_ip_route_vrf_all_summary_prefix
,
1647 show_ip_route_vrf_all_summary_prefix_cmd
,
1648 "show ip route vrf all summary prefix",
1651 "IP routing table\n"
1652 VRF_ALL_CMD_HELP_STR
1653 "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_prefix(
1662 vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1667 /* Write static route configuration. */
1668 static int static_config(struct vty
*vty
, afi_t afi
, safi_t safi
,
1671 struct route_node
*rn
;
1672 struct static_route
*si
;
1673 struct route_table
*stable
;
1675 struct zebra_vrf
*zvrf
;
1676 char buf
[SRCDEST2STR_BUFFER
];
1679 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1681 if (!(zvrf
= vrf
->info
))
1683 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1686 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1687 for (si
= rn
->info
; si
; si
= si
->next
) {
1688 vty_out(vty
, "%s %s", cmd
,
1689 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1692 case STATIC_IPV4_GATEWAY
:
1694 inet_ntoa(si
->addr
.ipv4
));
1696 case STATIC_IPV6_GATEWAY
:
1699 &si
->addr
.ipv6
, buf
,
1703 vty_out(vty
, " %s", si
->ifname
);
1705 case STATIC_BLACKHOLE
:
1706 switch (si
->bh_type
) {
1707 case STATIC_BLACKHOLE_DROP
:
1708 vty_out(vty
, " blackhole");
1710 case STATIC_BLACKHOLE_NULL
:
1711 vty_out(vty
, " Null0");
1713 case STATIC_BLACKHOLE_REJECT
:
1714 vty_out(vty
, " reject");
1718 case STATIC_IPV4_GATEWAY_IFNAME
:
1719 vty_out(vty
, " %s %s",
1721 &si
->addr
.ipv4
, buf
,
1725 case STATIC_IPV6_GATEWAY_IFNAME
:
1726 vty_out(vty
, " %s %s",
1728 &si
->addr
.ipv6
, buf
,
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 if (str2prefix(argv
[idx
]->arg
, &p
) <= 0) {
1840 vty_out(vty
, "%% Malformed prefix\n");
1843 longer_prefixes
= true;
1847 if (argv_find(argv
, argc
, "kernel", &idx
))
1848 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1849 else if (argv_find(argv
, argc
, "babel", &idx
))
1850 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1851 else if (argv_find(argv
, argc
, "connected", &idx
))
1852 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1853 else if (argv_find(argv
, argc
, "static", &idx
))
1854 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1855 else if (argv_find(argv
, argc
, "ripng", &idx
))
1856 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1857 else if (argv_find(argv
, argc
, "ospf6", &idx
))
1858 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1859 else if (argv_find(argv
, argc
, "isis", &idx
))
1860 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1861 else if (argv_find(argv
, argc
, "bgp", &idx
))
1862 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1863 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1864 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1865 else if (argv_find(argv
, argc
, "table", &idx
))
1866 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1867 else if (argv_find(argv
, argc
, "vnc", &idx
))
1868 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
1871 vty_out(vty
, "Unknown route type\n");
1877 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1879 if ((zvrf
= vrf
->info
) == NULL
1880 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
])
1884 do_show_ip_route(vty
, zvrf_name(zvrf
), AFI_IP6
,
1885 SAFI_UNICAST
, uf
, uj
, tag
,
1886 longer_prefixes
? &p
: NULL
,
1887 supernets_only
, type
, 0);
1890 vrf
= vrf_lookup_by_id(vrf_id
);
1891 do_show_ip_route(vty
, vrf
->name
, AFI_IP6
, SAFI_UNICAST
, uf
, uj
,
1892 tag
, longer_prefixes
? &p
: NULL
,
1893 supernets_only
, type
, 0);
1898 DEFUN (show_ipv6_route_addr
,
1899 show_ipv6_route_addr_cmd
,
1900 "show ipv6 route [vrf NAME] X:X::X:X",
1903 "IPv6 routing table\n"
1908 struct prefix_ipv6 p
;
1909 struct route_table
*table
;
1910 struct route_node
*rn
;
1911 vrf_id_t vrf_id
= VRF_DEFAULT
;
1913 if (strmatch(argv
[3]->text
, "vrf")) {
1914 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1915 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1917 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1921 vty_out(vty
, "Malformed IPv6 address\n");
1925 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1929 rn
= route_node_match(table
, (struct prefix
*)&p
);
1931 vty_out(vty
, "%% Network not in table\n");
1935 vty_show_ip_route_detail(vty
, rn
, 0);
1937 route_unlock_node(rn
);
1942 DEFUN (show_ipv6_route_prefix
,
1943 show_ipv6_route_prefix_cmd
,
1944 "show ipv6 route [vrf NAME] X:X::X:X/M",
1947 "IPv6 routing table\n"
1952 struct prefix_ipv6 p
;
1953 struct route_table
*table
;
1954 struct route_node
*rn
;
1955 vrf_id_t vrf_id
= VRF_DEFAULT
;
1957 if (strmatch(argv
[3]->text
, "vrf")) {
1958 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1959 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
1961 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
1964 vty_out(vty
, "Malformed IPv6 prefix\n");
1968 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
1972 rn
= route_node_match(table
, (struct prefix
*)&p
);
1973 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1974 vty_out(vty
, "%% Network not in table\n");
1978 vty_show_ip_route_detail(vty
, rn
, 0);
1980 route_unlock_node(rn
);
1986 /* Show route summary. */
1987 DEFUN (show_ipv6_route_summary
,
1988 show_ipv6_route_summary_cmd
,
1989 "show ipv6 route [vrf NAME] summary",
1992 "IPv6 routing table\n"
1994 "Summary of all IPv6 routes\n")
1996 struct route_table
*table
;
1997 vrf_id_t vrf_id
= VRF_DEFAULT
;
1999 if (strmatch(argv
[3]->text
, "vrf"))
2000 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2002 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2006 vty_show_ip_route_summary(vty
, table
);
2012 /* Show ipv6 route summary prefix. */
2013 DEFUN (show_ipv6_route_summary_prefix
,
2014 show_ipv6_route_summary_prefix_cmd
,
2015 "show ipv6 route [vrf NAME] summary prefix",
2018 "IPv6 routing table\n"
2020 "Summary of all IPv6 routes\n"
2023 struct route_table
*table
;
2024 vrf_id_t vrf_id
= VRF_DEFAULT
;
2026 if (strmatch(argv
[3]->text
, "vrf"))
2027 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2029 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2033 vty_show_ip_route_summary_prefix(vty
, table
);
2040 * Show IPv6 mroute command.Used to dump
2041 * the Multicast routing table.
2043 DEFUN (show_ipv6_mroute
,
2044 show_ipv6_mroute_cmd
,
2045 "show ipv6 mroute [vrf NAME]",
2048 "IPv6 Multicast routing table\n"
2051 struct route_table
*table
;
2052 struct route_node
*rn
;
2053 struct route_entry
*re
;
2055 vrf_id_t vrf_id
= VRF_DEFAULT
;
2058 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2060 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2064 /* Show all IPv6 route. */
2065 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2066 RNODE_FOREACH_RE(rn
, re
)
2069 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2072 vty_show_ip_route(vty
, rn
, re
, NULL
);
2077 DEFUN (show_ipv6_route_vrf_all_addr
,
2078 show_ipv6_route_vrf_all_addr_cmd
,
2079 "show ipv6 route vrf all X:X::X:X",
2082 "IPv6 routing table\n"
2083 VRF_ALL_CMD_HELP_STR
2088 struct prefix_ipv6 p
;
2089 struct route_table
*table
;
2090 struct route_node
*rn
;
2092 struct zebra_vrf
*zvrf
;
2094 ret
= str2prefix_ipv6(argv
[idx_ipv6
]->arg
, &p
);
2096 vty_out(vty
, "Malformed IPv6 address\n");
2100 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2102 if ((zvrf
= vrf
->info
) == NULL
2103 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2106 rn
= route_node_match(table
, (struct prefix
*)&p
);
2110 vty_show_ip_route_detail(vty
, rn
, 0);
2112 route_unlock_node(rn
);
2118 DEFUN (show_ipv6_route_vrf_all_prefix
,
2119 show_ipv6_route_vrf_all_prefix_cmd
,
2120 "show ipv6 route vrf all X:X::X:X/M",
2123 "IPv6 routing table\n"
2124 VRF_ALL_CMD_HELP_STR
2127 int idx_ipv6_prefixlen
= 5;
2129 struct prefix_ipv6 p
;
2130 struct route_table
*table
;
2131 struct route_node
*rn
;
2133 struct zebra_vrf
*zvrf
;
2135 ret
= str2prefix_ipv6(argv
[idx_ipv6_prefixlen
]->arg
, &p
);
2137 vty_out(vty
, "Malformed IPv6 prefix\n");
2141 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2143 if ((zvrf
= vrf
->info
) == NULL
2144 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2147 rn
= route_node_match(table
, (struct prefix
*)&p
);
2150 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
2151 route_unlock_node(rn
);
2155 vty_show_ip_route_detail(vty
, rn
, 0);
2157 route_unlock_node(rn
);
2163 DEFUN (show_ipv6_route_vrf_all_summary
,
2164 show_ipv6_route_vrf_all_summary_cmd
,
2165 "show ipv6 route vrf all summary",
2168 "IPv6 routing table\n"
2169 VRF_ALL_CMD_HELP_STR
2170 "Summary of all IPv6 routes\n")
2173 struct zebra_vrf
*zvrf
;
2175 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2176 if ((zvrf
= vrf
->info
) != NULL
)
2177 vty_show_ip_route_summary(vty
,
2178 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2183 DEFUN (show_ipv6_mroute_vrf_all
,
2184 show_ipv6_mroute_vrf_all_cmd
,
2185 "show ipv6 mroute vrf all",
2188 "IPv6 Multicast routing table\n"
2189 VRF_ALL_CMD_HELP_STR
)
2191 struct route_table
*table
;
2192 struct route_node
*rn
;
2193 struct route_entry
*re
;
2195 struct zebra_vrf
*zvrf
;
2198 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2200 if ((zvrf
= vrf
->info
) == NULL
2201 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2204 /* Show all IPv6 route. */
2205 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2206 RNODE_FOREACH_RE(rn
, re
)
2209 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2212 vty_show_ip_route(vty
, rn
, re
, NULL
);
2218 DEFUN (show_ipv6_route_vrf_all_summary_prefix
,
2219 show_ipv6_route_vrf_all_summary_prefix_cmd
,
2220 "show ipv6 route vrf all summary prefix",
2223 "IPv6 routing table\n"
2224 VRF_ALL_CMD_HELP_STR
2225 "Summary of all IPv6 routes\n"
2229 struct zebra_vrf
*zvrf
;
2231 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2232 if ((zvrf
= vrf
->info
) != NULL
)
2233 vty_show_ip_route_summary_prefix(
2234 vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2239 DEFUN (allow_external_route_update
,
2240 allow_external_route_update_cmd
,
2241 "allow-external-route-update",
2242 "Allow FRR routes to be overwritten by external processes\n")
2249 DEFUN (no_allow_external_route_update
,
2250 no_allow_external_route_update_cmd
,
2251 "no allow-external-route-update",
2253 "Allow FRR routes to be overwritten by external processes\n")
2268 struct zebra_vrf
*zvrf
;
2270 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2272 if (!(zvrf
= vrf
->info
))
2277 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2278 if (zvrf_id(zvrf
) == VRF_UNKNOWN
)
2279 vty_out(vty
, "inactive");
2281 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
2289 DEFUN (show_evpn_vni
,
2291 "show evpn vni [json]",
2294 "VxLAN information\n"
2297 struct zebra_vrf
*zvrf
;
2298 u_char uj
= use_json(argc
, argv
);
2300 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2301 zebra_vxlan_print_vnis(vty
, zvrf
, uj
);
2305 DEFUN (show_evpn_vni_vni
,
2306 show_evpn_vni_vni_cmd
,
2307 "show evpn vni " CMD_VNI_RANGE
"[json]",
2310 "VxLAN Network Identifier\n"
2314 struct zebra_vrf
*zvrf
;
2316 u_char uj
= use_json(argc
, argv
);
2318 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
2319 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2320 zebra_vxlan_print_vni(vty
, zvrf
, vni
, uj
);
2324 DEFUN (show_evpn_mac_vni
,
2325 show_evpn_mac_vni_cmd
,
2326 "show evpn mac vni " CMD_VNI_RANGE
"[json]",
2330 "VxLAN Network Identifier\n"
2334 struct zebra_vrf
*zvrf
;
2336 u_char uj
= use_json(argc
, argv
);
2338 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2339 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2340 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
, uj
);
2344 DEFUN (show_evpn_mac_vni_all
,
2345 show_evpn_mac_vni_all_cmd
,
2346 "show evpn mac vni all [json]",
2350 "VxLAN Network Identifier\n"
2354 struct zebra_vrf
*zvrf
;
2355 u_char uj
= use_json(argc
, argv
);
2357 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2358 zebra_vxlan_print_macs_all_vni(vty
, zvrf
, uj
);
2362 DEFUN (show_evpn_mac_vni_all_vtep
,
2363 show_evpn_mac_vni_all_vtep_cmd
,
2364 "show evpn mac vni all vtep A.B.C.D [json]",
2368 "VxLAN Network Identifier\n"
2371 "Remote VTEP IP address\n"
2374 struct zebra_vrf
*zvrf
;
2375 struct in_addr vtep_ip
;
2376 u_char uj
= use_json(argc
, argv
);
2378 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2380 vty_out(vty
, "%% Malformed VTEP IP address\n");
2383 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2384 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
, uj
);
2390 DEFUN (show_evpn_mac_vni_mac
,
2391 show_evpn_mac_vni_mac_cmd
,
2392 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
2396 "VxLAN Network Identifier\n"
2399 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
2401 struct zebra_vrf
*zvrf
;
2405 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2406 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
2407 vty_out(vty
, "%% Malformed MAC address");
2410 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2411 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
2415 DEFUN (show_evpn_mac_vni_vtep
,
2416 show_evpn_mac_vni_vtep_cmd
,
2417 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D" "[json]",
2421 "VxLAN Network Identifier\n"
2424 "Remote VTEP IP address\n"
2427 struct zebra_vrf
*zvrf
;
2429 struct in_addr vtep_ip
;
2430 u_char uj
= use_json(argc
, argv
);
2432 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2433 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2435 vty_out(vty
, "%% Malformed VTEP IP address\n");
2439 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2440 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2444 DEFUN (show_evpn_neigh_vni
,
2445 show_evpn_neigh_vni_cmd
,
2446 "show evpn arp-cache vni " CMD_VNI_RANGE
"[json]",
2449 "ARP and ND cache\n"
2450 "VxLAN Network Identifier\n"
2454 struct zebra_vrf
*zvrf
;
2456 u_char uj
= use_json(argc
, argv
);
2458 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2459 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2460 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
, uj
);
2464 DEFUN (show_evpn_neigh_vni_all
,
2465 show_evpn_neigh_vni_all_cmd
,
2466 "show evpn arp-cache vni all [json]",
2469 "ARP and ND cache\n"
2470 "VxLAN Network Identifier\n"
2474 struct zebra_vrf
*zvrf
;
2475 u_char uj
= use_json(argc
, argv
);
2477 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2478 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
, uj
);
2482 DEFUN (show_evpn_neigh_vni_neigh
,
2483 show_evpn_neigh_vni_neigh_cmd
,
2484 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD [json]",
2487 "ARP and ND cache\n"
2488 "VxLAN Network Identifier\n"
2491 "Neighbor address (IPv4 or IPv6 address)\n"
2494 struct zebra_vrf
*zvrf
;
2497 u_char uj
= use_json(argc
, argv
);
2499 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2500 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
2502 vty_out(vty
, "%% Malformed Neighbor address\n");
2505 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2506 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
, uj
);
2510 DEFUN (show_evpn_neigh_vni_vtep
,
2511 show_evpn_neigh_vni_vtep_cmd
,
2512 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D [json]",
2515 "ARP and ND cache\n"
2516 "VxLAN Network Identifier\n"
2519 "Remote VTEP IP address\n"
2522 struct zebra_vrf
*zvrf
;
2524 struct in_addr vtep_ip
;
2525 u_char uj
= use_json(argc
, argv
);
2527 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
2528 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
2530 vty_out(vty
, "%% Malformed VTEP IP address\n");
2534 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
2535 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
, uj
);
2539 /* Static ip route configuration write function. */
2540 static int zebra_ip_config(struct vty
*vty
)
2544 write
+= static_config(vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
2545 write
+= static_config(vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
2546 write
+= static_config(vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
2548 write
+= zebra_import_table_config(vty
);
2552 DEFUN (ip_zebra_import_table_distance
,
2553 ip_zebra_import_table_distance_cmd
,
2554 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
2556 "import routes from non-main kernel table\n"
2557 "kernel routing table id\n"
2558 "Distance for imported routes\n"
2559 "Default distance value\n"
2560 "route-map for filtering\n"
2563 u_int32_t table_id
= 0;
2565 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
2566 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
2568 strmatch(argv
[argc
- 2]->text
, "route-map")
2569 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
2573 if (argc
== 7 || (argc
== 5 && !rmap
))
2574 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
2576 if (!is_zebra_valid_kernel_table(table_id
)) {
2578 "Invalid routing table ID, %d. Must be in range 1-252\n",
2581 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2585 if (is_zebra_main_routing_table(table_id
)) {
2587 "Invalid routing table ID, %d. Must be non-default table\n",
2590 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2594 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
2596 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
2601 DEFUN (no_ip_zebra_import_table
,
2602 no_ip_zebra_import_table_cmd
,
2603 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
2606 "import routes from non-main kernel table\n"
2607 "kernel routing table id\n"
2608 "Distance for imported routes\n"
2609 "Default distance value\n"
2610 "route-map for filtering\n"
2613 u_int32_t table_id
= 0;
2614 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
2616 if (!is_zebra_valid_kernel_table(table_id
)) {
2618 "Invalid routing table ID. Must be in range 1-252\n");
2622 if (is_zebra_main_routing_table(table_id
)) {
2624 "Invalid routing table ID, %d. Must be non-default table\n",
2629 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
2632 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
2635 static int config_write_protocol(struct vty
*vty
)
2638 vty_out(vty
, "allow-external-route-update\n");
2640 if (zebra_rnh_ip_default_route
)
2641 vty_out(vty
, "ip nht resolve-via-default\n");
2643 if (zebra_rnh_ipv6_default_route
)
2644 vty_out(vty
, "ipv6 nht resolve-via-default\n");
2646 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
2648 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
2649 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
2650 ipv4_multicast_mode
== MCAST_URIB_ONLY
2652 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
2654 : ipv4_multicast_mode
2655 == MCAST_MIX_MRIB_FIRST
2657 : ipv4_multicast_mode
2658 == MCAST_MIX_DISTANCE
2662 zebra_routemap_config_write_protocol(vty
);
2667 /* IP node for static routes. */
2668 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
2669 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
2672 void zebra_vty_init(void)
2674 install_node(&ip_node
, zebra_ip_config
);
2675 install_node(&protocol_node
, config_write_protocol
);
2677 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
2678 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
2679 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
2680 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
2681 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
2682 install_element(CONFIG_NODE
, &ip_route_cmd
);
2683 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
2684 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
2686 install_element(VIEW_NODE
, &show_vrf_cmd
);
2687 install_element(VIEW_NODE
, &show_ip_route_cmd
);
2688 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
2689 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
2690 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
2691 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
2692 install_element(VIEW_NODE
, &show_ip_route_addr_cmd
);
2693 install_element(VIEW_NODE
, &show_ip_route_prefix_cmd
);
2694 install_element(VIEW_NODE
, &show_ip_route_summary_cmd
);
2695 install_element(VIEW_NODE
, &show_ip_route_summary_prefix_cmd
);
2697 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
2698 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
2700 install_element(VIEW_NODE
, &show_ip_route_vrf_all_addr_cmd
);
2701 install_element(VIEW_NODE
, &show_ip_route_vrf_all_prefix_cmd
);
2702 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_cmd
);
2703 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_prefix_cmd
);
2705 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
2706 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
2707 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
2708 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
2709 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
2710 install_element(VIEW_NODE
, &show_ipv6_route_cmd
);
2711 install_element(VIEW_NODE
, &show_ipv6_route_summary_cmd
);
2712 install_element(VIEW_NODE
, &show_ipv6_route_summary_prefix_cmd
);
2713 install_element(VIEW_NODE
, &show_ipv6_route_addr_cmd
);
2714 install_element(VIEW_NODE
, &show_ipv6_route_prefix_cmd
);
2715 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
2717 /* Commands for VRF */
2718 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_cmd
);
2719 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_prefix_cmd
);
2720 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_addr_cmd
);
2721 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_prefix_cmd
);
2723 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
2725 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
2726 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
2727 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
2728 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
2729 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
2730 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
2731 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
2732 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
2733 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
2734 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
2735 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);