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"
47 extern int allow_delete
;
49 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
50 safi_t safi
, bool use_fib
, u_char use_json
,
51 route_tag_t tag
, struct prefix
*longer_prefix_p
,
52 bool supernets_only
, int type
,
53 u_short ospf_instance_id
);
54 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
57 #define ONE_DAY_SECOND 60*60*24
58 #define ONE_WEEK_SECOND 60*60*24*7
60 /* VNI range as per RFC 7432 */
61 #define CMD_VNI_RANGE "(1-16777215)"
63 /* General function for static route. */
64 int zebra_static_ipv4(struct vty
*vty
, safi_t safi
, int add_cmd
,
65 const char *dest_str
, const char *mask_str
,
66 const char *gate_str
, const char *flag_str
,
67 const char *tag_str
, const char *distance_str
,
68 const char *vrf_id_str
, const char *label_str
)
77 struct zebra_vrf
*zvrf
= NULL
;
78 unsigned int ifindex
= 0;
79 const char *ifname
= NULL
;
80 u_char type
= STATIC_BLACKHOLE
;
81 struct static_nh_label snh_label
;
83 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
84 ret
= str2prefix(dest_str
, &p
);
86 vty_out(vty
, "%% Malformed address\n");
87 return CMD_WARNING_CONFIG_FAILED
;
90 /* Cisco like mask notation. */
92 ret
= inet_aton(mask_str
, &mask
);
94 vty_out(vty
, "%% Malformed address\n");
95 return CMD_WARNING_CONFIG_FAILED
;
97 p
.prefixlen
= ip_masklen(mask
);
100 /* Apply mask for given prefix. */
103 /* Administrative distance. */
105 distance
= atoi(distance_str
);
107 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
111 tag
= strtoul(tag_str
, NULL
, 10);
114 zvrf
= zebra_vrf_lookup_by_name(vrf_id_str
);
117 vty_out(vty
, "%% vrf %s is not defined\n", vrf_id_str
);
118 return CMD_WARNING_CONFIG_FAILED
;
125 "%% MPLS not turned on in kernel, ignoring command\n");
126 return CMD_WARNING_CONFIG_FAILED
;
128 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
133 vty_out(vty
, "%% Malformed label(s)\n");
137 "%% Cannot use reserved label(s) (%d-%d)\n",
138 MPLS_MIN_RESERVED_LABEL
,
139 MPLS_MAX_RESERVED_LABEL
);
143 "%% Too many labels. Enter %d or fewer\n",
147 return CMD_WARNING_CONFIG_FAILED
;
151 /* Null0 static route. */
152 if ((gate_str
!= NULL
)
153 && (strncasecmp(gate_str
, "Null0", strlen(gate_str
)) == 0)) {
155 vty_out(vty
, "%% can not have flag %s with Null0\n",
157 return CMD_WARNING_CONFIG_FAILED
;
160 static_add_route(AFI_IP
, safi
, type
, &p
, NULL
, NULL
,
161 ifindex
, ifname
, ZEBRA_FLAG_BLACKHOLE
,
162 tag
, distance
, zvrf
, &snh_label
);
164 static_delete_route(AFI_IP
, safi
, type
, &p
, NULL
, NULL
,
165 ifindex
, tag
, distance
, zvrf
,
172 switch (flag_str
[0]) {
175 SET_FLAG(flag
, ZEBRA_FLAG_REJECT
);
179 SET_FLAG(flag
, ZEBRA_FLAG_BLACKHOLE
);
182 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
183 return CMD_WARNING_CONFIG_FAILED
;
187 if (gate_str
== NULL
) {
189 static_add_route(AFI_IP
, safi
, type
, &p
, NULL
, NULL
,
190 ifindex
, ifname
, flag
, tag
, distance
,
193 static_delete_route(AFI_IP
, safi
, type
, &p
, NULL
, NULL
,
194 ifindex
, tag
, distance
, zvrf
,
200 /* When gateway is A.B.C.D format, gate is treated as nexthop
201 address other case gate is treated as interface name. */
202 ret
= inet_aton(gate_str
, &gate
);
204 struct interface
*ifp
=
205 if_lookup_by_name(gate_str
, zvrf_id(zvrf
));
207 vty_out(vty
, "%% Unknown interface: %s\n", gate_str
);
208 ifindex
= IFINDEX_DELETED
;
210 ifindex
= ifp
->ifindex
;
212 type
= STATIC_IFINDEX
;
214 type
= STATIC_IPV4_GATEWAY
;
217 static_add_route(AFI_IP
, safi
, type
, &p
, NULL
,
218 ifindex
? NULL
: (union g_addr
*)&gate
,
219 ifindex
, ifname
, flag
, tag
, distance
, zvrf
,
222 static_delete_route(AFI_IP
, safi
, type
, &p
, NULL
,
223 ifindex
? NULL
: (union g_addr
*)&gate
,
224 ifindex
, tag
, distance
, zvrf
, &snh_label
);
229 /* Static unicast routes for multicast RPF lookup. */
230 DEFUN (ip_mroute_dist
,
232 "ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
234 "Configure static unicast route into MRIB for multicast RPF lookup\n"
235 "IP destination prefix (e.g. 10.0.0.0/8)\n"
237 "Nexthop interface name\n"
240 char *destprefix
= argv
[2]->arg
;
241 char *nexthop
= argv
[3]->arg
;
242 char *distance
= (argc
== 5) ? argv
[4]->arg
: NULL
;
244 return zebra_static_ipv4(vty
, SAFI_MULTICAST
, 1, destprefix
, NULL
,
245 nexthop
, NULL
, NULL
, distance
, NULL
, NULL
);
248 DEFUN (no_ip_mroute_dist
,
249 no_ip_mroute_dist_cmd
,
250 "no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
253 "Configure static unicast route into MRIB for multicast RPF lookup\n"
254 "IP destination prefix (e.g. 10.0.0.0/8)\n"
256 "Nexthop interface name\n"
259 char *destprefix
= argv
[3]->arg
;
260 char *nexthop
= argv
[4]->arg
;
261 char *distance
= (argc
== 6) ? argv
[5]->arg
: NULL
;
263 return zebra_static_ipv4(vty
, SAFI_MULTICAST
, 0, destprefix
, NULL
,
264 nexthop
, NULL
, NULL
, distance
, NULL
, NULL
);
267 DEFUN (ip_multicast_mode
,
268 ip_multicast_mode_cmd
,
269 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
271 "Multicast options\n"
272 "RPF lookup behavior\n"
273 "Lookup in unicast RIB only\n"
274 "Lookup in multicast RIB only\n"
275 "Try multicast RIB first, fall back to unicast RIB\n"
276 "Lookup both, use entry with lower distance\n"
277 "Lookup both, use entry with longer prefix\n")
279 char *mode
= argv
[3]->text
;
281 if (strmatch(mode
, "urib-only"))
282 multicast_mode_ipv4_set(MCAST_URIB_ONLY
);
283 else if (strmatch(mode
, "mrib-only"))
284 multicast_mode_ipv4_set(MCAST_MRIB_ONLY
);
285 else if (strmatch(mode
, "mrib-then-urib"))
286 multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST
);
287 else if (strmatch(mode
, "lower-distance"))
288 multicast_mode_ipv4_set(MCAST_MIX_DISTANCE
);
289 else if (strmatch(mode
, "longer-prefix"))
290 multicast_mode_ipv4_set(MCAST_MIX_PFXLEN
);
292 vty_out(vty
, "Invalid mode specified\n");
293 return CMD_WARNING_CONFIG_FAILED
;
299 DEFUN (no_ip_multicast_mode
,
300 no_ip_multicast_mode_cmd
,
301 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
304 "Multicast options\n"
305 "RPF lookup behavior\n"
306 "Lookup in unicast RIB only\n"
307 "Lookup in multicast RIB only\n"
308 "Try multicast RIB first, fall back to unicast RIB\n"
309 "Lookup both, use entry with lower distance\n"
310 "Lookup both, use entry with longer prefix\n")
312 multicast_mode_ipv4_set(MCAST_NO_CONFIG
);
319 "show ip rpf [json]",
322 "Display RPF information for multicast source\n"
325 int uj
= use_json(argc
, argv
);
326 return do_show_ip_route(vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
,
327 false, uj
, 0, NULL
, false, -1, 0);
330 DEFUN (show_ip_rpf_addr
,
331 show_ip_rpf_addr_cmd
,
332 "show ip rpf A.B.C.D",
335 "Display RPF information for multicast source\n"
336 "IP multicast source address (e.g. 10.0.0.0)\n")
340 struct route_node
*rn
;
341 struct route_entry
*re
;
344 ret
= inet_aton(argv
[idx_ipv4
]->arg
, &addr
);
346 vty_out(vty
, "%% Malformed address\n");
350 re
= rib_match_ipv4_multicast(VRF_DEFAULT
, addr
, &rn
);
353 vty_show_ip_route_detail(vty
, rn
, 1);
355 vty_out(vty
, "%% No match for RPF lookup\n");
360 static void zebra_vty_ip_route_tdv_helper(int argc
, struct cmd_token
*argv
[],
361 int idx_curr
, char **tag
,
362 char **distance
, char **vrf
,
366 while (idx_curr
< argc
) {
367 if (strmatch(argv
[idx_curr
]->text
, "tag")) {
369 *tag
= argv
[idx_curr
+ 1]->arg
;
371 } else if (strmatch(argv
[idx_curr
]->text
, "vrf")) {
373 *vrf
= argv
[idx_curr
+ 1]->arg
;
375 } else if (strmatch(argv
[idx_curr
]->text
, "label")) {
377 *labels
= argv
[idx_curr
+ 1]->arg
;
381 *distance
= argv
[idx_curr
]->arg
;
389 /* Static route configuration. */
392 "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
394 "Establish static routes\n"
395 "IP destination prefix (e.g. 10.0.0.0/8)\n"
396 "IP gateway address\n"
397 "IP gateway interface name\n"
399 "Set tag for this route\n"
401 "Distance value for this route\n"
404 int idx_ipv4_prefixlen
= 2;
405 int idx_ipv4_ifname_null
= 3;
407 char *tag
, *distance
, *vrf
;
409 tag
= distance
= vrf
= NULL
;
410 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
413 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 1,
414 argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
415 argv
[idx_ipv4_ifname_null
]->arg
, NULL
, tag
,
416 distance
, vrf
, NULL
);
419 DEFUN (ip_route_flags
,
421 "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
423 "Establish static routes\n"
424 "IP destination prefix (e.g. 10.0.0.0/8)\n"
425 "Emit an ICMP unreachable when matched\n"
426 "Silently discard pkts when matched\n"
427 "Set tag for this route\n"
429 "Distance value for this route\n"
432 int idx_ipv4_prefixlen
= 2;
433 int idx_reject_blackhole
= 3;
435 char *tag
, *distance
, *vrf
;
437 tag
= distance
= vrf
= NULL
;
438 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
441 return zebra_static_ipv4(
442 vty
, SAFI_UNICAST
, 1, argv
[idx_ipv4_prefixlen
]->arg
, NULL
, NULL
,
443 argv
[idx_reject_blackhole
]->arg
, tag
, distance
, vrf
, NULL
);
446 /* Mask as A.B.C.D format. */
447 DEFUN (ip_route_mask
,
449 "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
451 "Establish static routes\n"
452 "IP destination prefix\n"
453 "IP destination prefix mask\n"
454 "IP gateway address\n"
455 "IP gateway interface name\n"
457 "Set tag for this route\n"
459 "Distance value for this route\n"
464 int idx_ipv4_ifname_null
= 4;
466 char *tag
, *distance
, *vrf
;
468 tag
= distance
= vrf
= NULL
;
469 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
472 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 1, argv
[idx_ipv4
]->arg
,
473 argv
[idx_ipv4_2
]->arg
,
474 argv
[idx_ipv4_ifname_null
]->arg
, NULL
, tag
,
475 distance
, vrf
, NULL
);
478 DEFUN (ip_route_mask_flags
,
479 ip_route_mask_flags_cmd
,
480 "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
482 "Establish static routes\n"
483 "IP destination prefix\n"
484 "IP destination prefix mask\n"
485 "Emit an ICMP unreachable when matched\n"
486 "Silently discard pkts when matched\n"
487 "Set tag for this route\n"
489 "Distance value for this route\n"
494 int idx_reject_blackhole
= 4;
496 char *tag
, *distance
, *vrf
;
498 tag
= distance
= vrf
= NULL
;
499 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
502 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 1, argv
[idx_ipv4
]->arg
,
503 argv
[idx_ipv4_2
]->arg
, NULL
,
504 argv
[idx_reject_blackhole
]->arg
, tag
, distance
,
510 "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
513 "Establish static routes\n"
514 "IP destination prefix (e.g. 10.0.0.0/8)\n"
515 "IP gateway address\n"
516 "IP gateway interface name\n"
518 "Tag of this route\n"
520 "Distance value for this route\n"
523 int idx_ipv4_prefixlen
= 3;
524 int idx_ipv4_ifname_null
= 4;
526 char *tag
, *distance
, *vrf
;
528 tag
= distance
= vrf
= NULL
;
529 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
532 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 0,
533 argv
[idx_ipv4_prefixlen
]->arg
, NULL
,
534 argv
[idx_ipv4_ifname_null
]->arg
, NULL
, tag
,
535 distance
, vrf
, NULL
);
538 DEFUN (no_ip_route_flags
,
539 no_ip_route_flags_cmd
,
540 "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
543 "Establish static routes\n"
544 "IP destination prefix (e.g. 10.0.0.0/8)\n"
545 "Emit an ICMP unreachable when matched\n"
546 "Silently discard pkts when matched\n"
547 "Tag of this route\n"
549 "Distance value for this route\n"
552 int idx_ipv4_prefixlen
= 3;
554 char *tag
, *distance
, *vrf
;
556 tag
= distance
= vrf
= NULL
;
557 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
560 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 0,
561 argv
[idx_ipv4_prefixlen
]->arg
, NULL
, NULL
,
562 NULL
, tag
, distance
, vrf
, NULL
);
565 DEFUN (no_ip_route_mask
,
566 no_ip_route_mask_cmd
,
567 "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
570 "Establish static routes\n"
571 "IP destination prefix\n"
572 "IP destination prefix mask\n"
573 "IP gateway address\n"
574 "IP gateway interface name\n"
576 "Tag of this route\n"
578 "Distance value for this route\n"
583 int idx_ipv4_ifname_null
= 5;
585 char *tag
, *distance
, *vrf
;
587 tag
= distance
= vrf
= NULL
;
588 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
591 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 0, argv
[idx_ipv4
]->arg
,
592 argv
[idx_ipv4_2
]->arg
,
593 argv
[idx_ipv4_ifname_null
]->arg
, NULL
, tag
,
594 distance
, vrf
, NULL
);
597 DEFUN (no_ip_route_mask_flags
,
598 no_ip_route_mask_flags_cmd
,
599 "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
602 "Establish static routes\n"
603 "IP destination prefix\n"
604 "IP destination prefix mask\n"
605 "Emit an ICMP unreachable when matched\n"
606 "Silently discard pkts when matched\n"
607 "Tag of this route\n"
609 "Distance value for this route\n"
615 char *tag
, *distance
, *vrf
;
617 tag
= distance
= vrf
= NULL
;
618 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
621 return zebra_static_ipv4(vty
, SAFI_UNICAST
, 0, argv
[idx_ipv4
]->arg
,
622 argv
[idx_ipv4_2
]->arg
, NULL
, NULL
, tag
,
623 distance
, vrf
, NULL
);
626 /* New RIB. Detailed information for IPv4 route. */
627 static void vty_show_ip_route_detail(struct vty
*vty
, struct route_node
*rn
,
630 struct route_entry
*re
;
631 struct nexthop
*nexthop
;
632 char buf
[SRCDEST2STR_BUFFER
];
633 struct zebra_vrf
*zvrf
;
635 RNODE_FOREACH_RE(rn
, re
)
637 const char *mcast_info
= "";
639 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
640 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
641 ? " using Multicast RIB"
642 : " using Unicast RIB";
645 vty_out(vty
, "Routing entry for %s%s\n",
646 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
);
647 vty_out(vty
, " Known via \"%s", zebra_route_string(re
->type
));
649 vty_out(vty
, "[%d]", re
->instance
);
651 vty_out(vty
, ", distance %u, metric %u", re
->distance
,
654 vty_out(vty
, ", tag %d", re
->tag
);
656 vty_out(vty
, ", mtu %u", re
->mtu
);
657 if (re
->vrf_id
!= VRF_DEFAULT
) {
658 zvrf
= vrf_info_lookup(re
->vrf_id
);
659 vty_out(vty
, ", vrf %s", zvrf_name(zvrf
));
661 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
662 vty_out(vty
, ", best");
664 vty_out(vty
, ", refcnt %ld", re
->refcnt
);
665 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
666 vty_out(vty
, ", blackhole");
667 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
668 vty_out(vty
, ", reject");
671 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
672 || re
->type
== ZEBRA_ROUTE_ISIS
673 || re
->type
== ZEBRA_ROUTE_NHRP
674 || re
->type
== ZEBRA_ROUTE_TABLE
675 || re
->type
== ZEBRA_ROUTE_BGP
) {
680 uptime
-= re
->uptime
;
681 tm
= gmtime(&uptime
);
683 vty_out(vty
, " Last update ");
685 if (uptime
< ONE_DAY_SECOND
)
686 vty_out(vty
, "%02d:%02d:%02d", tm
->tm_hour
,
687 tm
->tm_min
, tm
->tm_sec
);
688 else if (uptime
< ONE_WEEK_SECOND
)
689 vty_out(vty
, "%dd%02dh%02dm", tm
->tm_yday
,
690 tm
->tm_hour
, tm
->tm_min
);
692 vty_out(vty
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
693 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
695 vty_out(vty
, " ago\n");
698 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
701 vty_out(vty
, " %c%s",
702 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
705 nexthop
->rparent
? " " : "");
707 switch (nexthop
->type
) {
708 case NEXTHOP_TYPE_IPV4
:
709 case NEXTHOP_TYPE_IPV4_IFINDEX
:
711 inet_ntoa(nexthop
->gate
.ipv4
));
712 if (nexthop
->ifindex
)
713 vty_out(vty
, ", via %s",
714 ifindex2ifname(nexthop
->ifindex
,
717 case NEXTHOP_TYPE_IPV6
:
718 case NEXTHOP_TYPE_IPV6_IFINDEX
:
720 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
722 if (nexthop
->ifindex
)
723 vty_out(vty
, ", via %s",
724 ifindex2ifname(nexthop
->ifindex
,
727 case NEXTHOP_TYPE_IFINDEX
:
728 vty_out(vty
, " directly connected, %s",
729 ifindex2ifname(nexthop
->ifindex
,
732 case NEXTHOP_TYPE_BLACKHOLE
:
733 vty_out(vty
, " directly connected, Null0");
738 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
739 vty_out(vty
, " inactive");
741 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
742 vty_out(vty
, " onlink");
744 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
745 vty_out(vty
, " (recursive)");
747 switch (nexthop
->type
) {
748 case NEXTHOP_TYPE_IPV4
:
749 case NEXTHOP_TYPE_IPV4_IFINDEX
:
750 if (nexthop
->src
.ipv4
.s_addr
) {
751 if (inet_ntop(AF_INET
,
753 addrstr
, sizeof addrstr
))
754 vty_out(vty
, ", src %s",
758 case NEXTHOP_TYPE_IPV6
:
759 case NEXTHOP_TYPE_IPV6_IFINDEX
:
760 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
762 if (inet_ntop(AF_INET6
,
764 addrstr
, sizeof addrstr
))
765 vty_out(vty
, ", src %s",
773 /* Label information */
774 if (nexthop
->nh_label
775 && nexthop
->nh_label
->num_labels
) {
776 vty_out(vty
, ", label %s",
778 nexthop
->nh_label
->num_labels
,
779 nexthop
->nh_label
->label
, buf
,
789 static void vty_show_ip_route(struct vty
*vty
, struct route_node
*rn
,
790 struct route_entry
*re
, json_object
*json
)
792 struct nexthop
*nexthop
;
794 char buf
[SRCDEST2STR_BUFFER
];
795 json_object
*json_nexthops
= NULL
;
796 json_object
*json_nexthop
= NULL
;
797 json_object
*json_route
= NULL
;
798 json_object
*json_labels
= NULL
;
801 json_route
= json_object_new_object();
802 json_nexthops
= json_object_new_array();
804 json_object_string_add(json_route
, "prefix",
805 srcdest_rnode2str(rn
, buf
, sizeof buf
));
806 json_object_string_add(json_route
, "protocol",
807 zebra_route_string(re
->type
));
810 json_object_int_add(json_route
, "instance",
814 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
816 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
))
817 json_object_boolean_true_add(json_route
, "selected");
819 if (re
->type
!= ZEBRA_ROUTE_CONNECT
820 && re
->type
!= ZEBRA_ROUTE_KERNEL
) {
821 json_object_int_add(json_route
, "distance",
823 json_object_int_add(json_route
, "metric", re
->metric
);
826 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
827 json_object_boolean_true_add(json_route
, "blackhole");
829 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
830 json_object_boolean_true_add(json_route
, "reject");
832 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
833 || re
->type
== ZEBRA_ROUTE_ISIS
834 || re
->type
== ZEBRA_ROUTE_NHRP
835 || re
->type
== ZEBRA_ROUTE_TABLE
836 || re
->type
== ZEBRA_ROUTE_BGP
) {
841 uptime
-= re
->uptime
;
842 tm
= gmtime(&uptime
);
844 if (uptime
< ONE_DAY_SECOND
)
845 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
,
846 tm
->tm_min
, tm
->tm_sec
);
847 else if (uptime
< ONE_WEEK_SECOND
)
848 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
,
849 tm
->tm_hour
, tm
->tm_min
);
851 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
852 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
855 json_object_string_add(json_route
, "uptime", buf
);
858 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
859 json_nexthop
= json_object_new_object();
861 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
))
862 json_object_boolean_true_add(json_nexthop
,
865 switch (nexthop
->type
) {
866 case NEXTHOP_TYPE_IPV4
:
867 case NEXTHOP_TYPE_IPV4_IFINDEX
:
868 json_object_string_add(
870 inet_ntoa(nexthop
->gate
.ipv4
));
871 json_object_string_add(json_nexthop
, "afi",
874 if (nexthop
->ifindex
) {
875 json_object_int_add(json_nexthop
,
878 json_object_string_add(
879 json_nexthop
, "interfaceName",
880 ifindex2ifname(nexthop
->ifindex
,
884 case NEXTHOP_TYPE_IPV6
:
885 case NEXTHOP_TYPE_IPV6_IFINDEX
:
886 json_object_string_add(
888 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
,
890 json_object_string_add(json_nexthop
, "afi",
893 if (nexthop
->ifindex
) {
894 json_object_int_add(json_nexthop
,
897 json_object_string_add(
898 json_nexthop
, "interfaceName",
899 ifindex2ifname(nexthop
->ifindex
,
904 case NEXTHOP_TYPE_IFINDEX
:
905 json_object_boolean_true_add(
906 json_nexthop
, "directlyConnected");
907 json_object_int_add(json_nexthop
,
910 json_object_string_add(
911 json_nexthop
, "interfaceName",
912 ifindex2ifname(nexthop
->ifindex
,
915 case NEXTHOP_TYPE_BLACKHOLE
:
916 json_object_boolean_true_add(json_nexthop
,
923 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
924 json_object_boolean_true_add(json_nexthop
,
927 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
928 json_object_boolean_true_add(json_nexthop
,
931 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
932 json_object_boolean_true_add(json_nexthop
,
935 switch (nexthop
->type
) {
936 case NEXTHOP_TYPE_IPV4
:
937 case NEXTHOP_TYPE_IPV4_IFINDEX
:
938 if (nexthop
->src
.ipv4
.s_addr
) {
939 if (inet_ntop(AF_INET
,
940 &nexthop
->src
.ipv4
, buf
,
942 json_object_string_add(
943 json_nexthop
, "source",
947 case NEXTHOP_TYPE_IPV6
:
948 case NEXTHOP_TYPE_IPV6_IFINDEX
:
949 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
,
951 if (inet_ntop(AF_INET6
,
952 &nexthop
->src
.ipv6
, buf
,
954 json_object_string_add(
955 json_nexthop
, "source",
963 if (nexthop
->nh_label
964 && nexthop
->nh_label
->num_labels
) {
965 json_labels
= json_object_new_array();
967 for (int label_index
= 0;
969 < nexthop
->nh_label
->num_labels
;
971 json_object_array_add(
974 nexthop
->nh_label
->label
977 json_object_object_add(json_nexthop
, "labels",
981 json_object_array_add(json_nexthops
, json_nexthop
);
984 json_object_object_add(json_route
, "nexthops", json_nexthops
);
985 json_object_array_add(json
, json_route
);
989 /* Nexthop information. */
990 for (ALL_NEXTHOPS(re
->nexthop
, nexthop
)) {
991 if (nexthop
== re
->nexthop
) {
992 /* Prefix information. */
993 len
= vty_out(vty
, "%c", zebra_route_char(re
->type
));
995 len
+= vty_out(vty
, "[%d]", re
->instance
);
998 CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)
1001 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
1004 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1006 /* Distance and metric display. */
1007 if (re
->type
!= ZEBRA_ROUTE_CONNECT
1008 && re
->type
!= ZEBRA_ROUTE_KERNEL
)
1009 len
+= vty_out(vty
, " [%d/%d]", re
->distance
,
1012 vty_out(vty
, " %c%*c",
1013 CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_FIB
)
1016 len
- 3 + (2 * nexthop_level(nexthop
)), ' ');
1018 switch (nexthop
->type
) {
1019 case NEXTHOP_TYPE_IPV4
:
1020 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1021 vty_out(vty
, " via %s", inet_ntoa(nexthop
->gate
.ipv4
));
1022 if (nexthop
->ifindex
)
1023 vty_out(vty
, ", %s",
1024 ifindex2ifname(nexthop
->ifindex
,
1027 case NEXTHOP_TYPE_IPV6
:
1028 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1029 vty_out(vty
, " via %s",
1030 inet_ntop(AF_INET6
, &nexthop
->gate
.ipv6
, buf
,
1032 if (nexthop
->ifindex
)
1033 vty_out(vty
, ", %s",
1034 ifindex2ifname(nexthop
->ifindex
,
1038 case NEXTHOP_TYPE_IFINDEX
:
1039 vty_out(vty
, " is directly connected, %s",
1040 ifindex2ifname(nexthop
->ifindex
, re
->vrf_id
));
1042 case NEXTHOP_TYPE_BLACKHOLE
:
1043 vty_out(vty
, " is directly connected, Null0");
1048 if (!CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1049 vty_out(vty
, " inactive");
1051 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1052 vty_out(vty
, " onlink");
1054 if (CHECK_FLAG(nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1055 vty_out(vty
, " (recursive)");
1057 switch (nexthop
->type
) {
1058 case NEXTHOP_TYPE_IPV4
:
1059 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1060 if (nexthop
->src
.ipv4
.s_addr
) {
1061 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
,
1063 vty_out(vty
, ", src %s", buf
);
1066 case NEXTHOP_TYPE_IPV6
:
1067 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1068 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
)) {
1069 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
,
1071 vty_out(vty
, ", src %s", buf
);
1078 /* Label information */
1079 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
) {
1080 vty_out(vty
, ", label %s",
1081 mpls_label2str(nexthop
->nh_label
->num_labels
,
1082 nexthop
->nh_label
->label
, buf
,
1086 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
1087 vty_out(vty
, ", bh");
1088 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_REJECT
))
1089 vty_out(vty
, ", rej");
1091 if (re
->type
== ZEBRA_ROUTE_RIP
|| re
->type
== ZEBRA_ROUTE_OSPF
1092 || re
->type
== ZEBRA_ROUTE_ISIS
1093 || re
->type
== ZEBRA_ROUTE_NHRP
1094 || re
->type
== ZEBRA_ROUTE_TABLE
1095 || re
->type
== ZEBRA_ROUTE_BGP
) {
1099 uptime
= time(NULL
);
1100 uptime
-= re
->uptime
;
1101 tm
= gmtime(&uptime
);
1103 if (uptime
< ONE_DAY_SECOND
)
1104 vty_out(vty
, ", %02d:%02d:%02d", tm
->tm_hour
,
1105 tm
->tm_min
, tm
->tm_sec
);
1106 else if (uptime
< ONE_WEEK_SECOND
)
1107 vty_out(vty
, ", %dd%02dh%02dm", tm
->tm_yday
,
1108 tm
->tm_hour
, tm
->tm_min
);
1110 vty_out(vty
, ", %02dw%dd%02dh", tm
->tm_yday
/ 7,
1111 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7),
1118 static bool use_fib(struct cmd_token
*token
)
1120 return strncmp(token
->arg
, "route", strlen(token
->arg
));
1123 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
, afi_t afi
,
1124 safi_t safi
, bool use_fib
, u_char use_json
,
1125 route_tag_t tag
, struct prefix
*longer_prefix_p
,
1126 bool supernets_only
, int type
,
1127 u_short ospf_instance_id
)
1129 struct route_table
*table
;
1130 struct route_node
*rn
;
1131 struct route_entry
*re
;
1133 struct zebra_vrf
*zvrf
= NULL
;
1135 json_object
*json
= NULL
;
1136 json_object
*json_prefix
= NULL
;
1139 if (!(zvrf
= zebra_vrf_lookup_by_name(vrf_name
))) {
1141 vty_out(vty
, "{}\n");
1143 vty_out(vty
, "vrf %s not defined\n", vrf_name
);
1147 if (zvrf_id(zvrf
) == VRF_UNKNOWN
) {
1149 vty_out(vty
, "{}\n");
1151 vty_out(vty
, "vrf %s inactive\n", vrf_name
);
1155 table
= zebra_vrf_table(afi
, safi
, zvrf_id(zvrf
));
1158 vty_out(vty
, "{}\n");
1163 json
= json_object_new_object();
1165 /* Show all routes. */
1166 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
1167 RNODE_FOREACH_RE(rn
, re
)
1170 && !CHECK_FLAG(re
->status
,
1171 ROUTE_ENTRY_SELECTED_FIB
))
1174 if (tag
&& re
->tag
!= tag
)
1178 && !prefix_match(longer_prefix_p
, &rn
->p
))
1181 /* This can only be true when the afi is IPv4 */
1182 if (supernets_only
) {
1183 addr
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
1185 if (IN_CLASSC(addr
) && rn
->p
.prefixlen
>= 24)
1188 if (IN_CLASSB(addr
) && rn
->p
.prefixlen
>= 16)
1191 if (IN_CLASSA(addr
) && rn
->p
.prefixlen
>= 8)
1195 if (type
&& re
->type
!= type
)
1198 if (ospf_instance_id
1199 && (re
->type
!= ZEBRA_ROUTE_OSPF
1200 || re
->instance
!= ospf_instance_id
))
1205 json_prefix
= json_object_new_array();
1210 SHOW_ROUTE_V4_HEADER
);
1213 SHOW_ROUTE_V6_HEADER
);
1215 if (zvrf_id(zvrf
) != VRF_DEFAULT
)
1216 vty_out(vty
, "\nVRF %s:\n",
1223 vty_show_ip_route(vty
, rn
, re
, json_prefix
);
1227 prefix2str(&rn
->p
, buf
, sizeof buf
);
1228 json_object_object_add(json
, buf
, json_prefix
);
1234 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
1235 json
, JSON_C_TO_STRING_PRETTY
));
1236 json_object_free(json
);
1244 "show ip nht [vrf NAME]",
1247 "IP nexthop tracking table\n"
1251 vrf_id_t vrf_id
= VRF_DEFAULT
;
1254 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1256 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1261 DEFUN (show_ip_nht_vrf_all
,
1262 show_ip_nht_vrf_all_cmd
,
1263 "show ip nht vrf all",
1266 "IP nexthop tracking table\n"
1267 VRF_ALL_CMD_HELP_STR
)
1270 struct zebra_vrf
*zvrf
;
1272 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1273 if ((zvrf
= vrf
->info
) != NULL
) {
1274 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1275 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET
, vty
,
1282 DEFUN (show_ipv6_nht
,
1284 "show ipv6 nht [vrf NAME]",
1287 "IPv6 nexthop tracking table\n"
1291 vrf_id_t vrf_id
= VRF_DEFAULT
;
1294 VRF_GET_ID(vrf_id
, argv
[idx_vrf
]->arg
);
1296 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1301 DEFUN (show_ipv6_nht_vrf_all
,
1302 show_ipv6_nht_vrf_all_cmd
,
1303 "show ipv6 nht vrf all",
1306 "IPv6 nexthop tracking table\n"
1307 VRF_ALL_CMD_HELP_STR
)
1310 struct zebra_vrf
*zvrf
;
1312 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1313 if ((zvrf
= vrf
->info
) != NULL
) {
1314 vty_out(vty
, "\nVRF %s:\n", zvrf_name(zvrf
));
1315 zebra_print_rnh_table(zvrf_id(zvrf
), AF_INET6
, vty
,
1322 DEFUN (ip_nht_default_route
,
1323 ip_nht_default_route_cmd
,
1324 "ip nht resolve-via-default",
1326 "Filter Next Hop tracking route resolution\n"
1327 "Resolve via default route\n")
1329 if (zebra_rnh_ip_default_route
)
1332 zebra_rnh_ip_default_route
= 1;
1333 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1337 DEFUN (no_ip_nht_default_route
,
1338 no_ip_nht_default_route_cmd
,
1339 "no ip nht resolve-via-default",
1342 "Filter Next Hop tracking route resolution\n"
1343 "Resolve via default route\n")
1345 if (!zebra_rnh_ip_default_route
)
1348 zebra_rnh_ip_default_route
= 0;
1349 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1353 DEFUN (ipv6_nht_default_route
,
1354 ipv6_nht_default_route_cmd
,
1355 "ipv6 nht resolve-via-default",
1357 "Filter Next Hop tracking route resolution\n"
1358 "Resolve via default route\n")
1360 if (zebra_rnh_ipv6_default_route
)
1363 zebra_rnh_ipv6_default_route
= 1;
1364 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1368 DEFUN (no_ipv6_nht_default_route
,
1369 no_ipv6_nht_default_route_cmd
,
1370 "no ipv6 nht resolve-via-default",
1373 "Filter Next Hop tracking route resolution\n"
1374 "Resolve via default route\n")
1376 if (!zebra_rnh_ipv6_default_route
)
1379 zebra_rnh_ipv6_default_route
= 0;
1380 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1384 DEFUN (show_ip_route
,
1386 "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]",
1389 "IP forwarding table\n"
1390 "IP routing table\n"
1392 "Show only routes with tag\n"
1394 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1395 "Show route matching the specified Network/Mask pair only\n"
1396 "Show supernet entries only\n"
1397 FRR_IP_REDIST_HELP_STR_ZEBRA
1398 "Open Shortest Path First (OSPFv2)\n"
1402 bool uf
= use_fib(argv
[2]);
1403 struct route_table
*table
;
1405 route_tag_t tag
= 0;
1406 vrf_id_t vrf_id
= VRF_DEFAULT
;
1408 struct zebra_vrf
*zvrf
;
1409 int uj
= use_json(argc
, argv
);
1412 bool longer_prefixes
= false;
1413 bool supernets_only
= false;
1415 u_short ospf_instance_id
= 0;
1417 if (argv_find(argv
, argc
, "vrf", &idx
)) {
1418 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
1421 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
1424 if (argv_find(argv
, argc
, "tag", &idx
))
1425 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
1427 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)) {
1428 str2prefix(argv
[idx
]->arg
, &p
);
1429 longer_prefixes
= true;
1432 else if (argv_find(argv
, argc
, "supernets_only", &idx
))
1433 supernets_only
= true;
1436 if (argv_find(argv
, argc
, "kernel", &idx
))
1437 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1438 else if (argv_find(argv
, argc
, "babel", &idx
))
1439 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1440 else if (argv_find(argv
, argc
, "connected", &idx
))
1441 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1442 else if (argv_find(argv
, argc
, "static", &idx
))
1443 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1444 else if (argv_find(argv
, argc
, "rip", &idx
))
1445 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1446 else if (argv_find(argv
, argc
, "ospf", &idx
))
1447 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1448 else if (argv_find(argv
, argc
, "isis", &idx
))
1449 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1450 else if (argv_find(argv
, argc
, "bgp", &idx
))
1451 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1452 else if (argv_find(argv
, argc
, "pim", &idx
))
1453 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1454 else if (argv_find(argv
, argc
, "eigrp", &idx
))
1455 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1456 else if (argv_find(argv
, argc
, "nhrp", &idx
))
1457 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1458 else if (argv_find(argv
, argc
, "table", &idx
))
1459 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1460 else if (argv_find(argv
, argc
, "vnc", &idx
))
1461 type
= proto_redistnum(AFI_IP
, argv
[idx
]->text
);
1463 if (argv_find(argv
, argc
, "(1-65535)", &idx
))
1464 ospf_instance_id
= strtoul(argv
[idx
]->arg
, NULL
, 10);
1467 vty_out(vty
, "Unknown route type\n");
1473 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1475 if ((zvrf
= vrf
->info
) == NULL
1476 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
])
1481 vty
, zvrf_name(zvrf
), AFI_IP
, SAFI_UNICAST
, uf
,
1482 uj
, tag
, longer_prefixes
? &p
: NULL
,
1483 supernets_only
, type
, ospf_instance_id
);
1486 vrf
= vrf_lookup_by_id(vrf_id
);
1487 do_show_ip_route(vty
, vrf
->name
, AFI_IP
, SAFI_UNICAST
, uf
, uj
,
1488 tag
, longer_prefixes
? &p
: NULL
,
1489 supernets_only
, type
, ospf_instance_id
);
1494 DEFUN (show_ip_route_addr
,
1495 show_ip_route_addr_cmd
,
1496 "show ip route [vrf NAME] A.B.C.D",
1499 "IP routing table\n"
1501 "Network in the IP routing table to display\n")
1504 struct prefix_ipv4 p
;
1505 struct route_table
*table
;
1506 struct route_node
*rn
;
1507 vrf_id_t vrf_id
= VRF_DEFAULT
;
1509 if (strmatch(argv
[3]->text
, "vrf")) {
1510 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1511 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1513 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1517 vty_out(vty
, "%% Malformed IPv4 address\n");
1521 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1525 rn
= route_node_match(table
, (struct prefix
*)&p
);
1527 vty_out(vty
, "%% Network not in table\n");
1531 vty_show_ip_route_detail(vty
, rn
, 0);
1533 route_unlock_node(rn
);
1538 DEFUN (show_ip_route_prefix
,
1539 show_ip_route_prefix_cmd
,
1540 "show ip route [vrf NAME] A.B.C.D/M",
1543 "IP routing table\n"
1545 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1548 struct prefix_ipv4 p
;
1549 struct route_table
*table
;
1550 struct route_node
*rn
;
1551 vrf_id_t vrf_id
= VRF_DEFAULT
;
1553 if (strmatch(argv
[3]->text
, "vrf")) {
1554 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1555 ret
= str2prefix_ipv4(argv
[5]->arg
, &p
);
1557 ret
= str2prefix_ipv4(argv
[3]->arg
, &p
);
1561 vty_out(vty
, "%% Malformed IPv4 address\n");
1565 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1569 rn
= route_node_match(table
, (struct prefix
*)&p
);
1570 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
1571 vty_out(vty
, "%% Network not in table\n");
1575 vty_show_ip_route_detail(vty
, rn
, 0);
1577 route_unlock_node(rn
);
1583 static void vty_show_ip_route_summary(struct vty
*vty
,
1584 struct route_table
*table
)
1586 struct route_node
*rn
;
1587 struct route_entry
*re
;
1588 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1589 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1590 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1591 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1595 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1596 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1597 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1598 RNODE_FOREACH_RE(rn
, re
)
1600 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
1601 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
));
1603 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1605 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1607 rib_cnt
[re
->type
]++;
1609 if (CHECK_FLAG(re
->flags
, ZEBRA_FLAG_SELECTED
)) {
1610 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1613 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1615 fib_cnt
[re
->type
]++;
1619 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
1620 "FIB", zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1622 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1623 if ((rib_cnt
[i
] > 0) || (i
== ZEBRA_ROUTE_BGP
1624 && rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0)) {
1625 if (i
== ZEBRA_ROUTE_BGP
) {
1626 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1627 rib_cnt
[ZEBRA_ROUTE_BGP
],
1628 fib_cnt
[ZEBRA_ROUTE_BGP
]);
1629 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1630 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1631 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1633 vty_out(vty
, "%-20s %-20d %-20d \n",
1634 zebra_route_string(i
), rib_cnt
[i
],
1639 vty_out(vty
, "------\n");
1640 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1641 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1646 * Implementation of the ip route summary prefix command.
1648 * This command prints the primary prefixes that have been installed by various
1649 * protocols on the box.
1652 static void vty_show_ip_route_summary_prefix(struct vty
*vty
,
1653 struct route_table
*table
)
1655 struct route_node
*rn
;
1656 struct route_entry
*re
;
1657 struct nexthop
*nexthop
;
1658 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1659 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1660 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1661 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1665 memset(&rib_cnt
, 0, sizeof(rib_cnt
));
1666 memset(&fib_cnt
, 0, sizeof(fib_cnt
));
1667 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
1668 RNODE_FOREACH_RE(rn
, re
)
1672 * In case of ECMP, count only once.
1675 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
);
1676 nexthop
= nexthop
->next
) {
1678 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1679 rib_cnt
[re
->type
]++;
1680 if (CHECK_FLAG(nexthop
->flags
,
1681 NEXTHOP_FLAG_FIB
)) {
1682 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1683 fib_cnt
[re
->type
]++;
1685 if (re
->type
== ZEBRA_ROUTE_BGP
1686 && CHECK_FLAG(re
->flags
, ZEBRA_FLAG_IBGP
)) {
1687 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1688 if (CHECK_FLAG(nexthop
->flags
,
1690 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1695 vty_out(vty
, "%-20s %-20s %s (vrf %s)\n", "Route Source",
1696 "Prefix Routes", "FIB",
1697 zvrf_name(((rib_table_info_t
*)table
->info
)->zvrf
));
1699 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
1700 if (rib_cnt
[i
] > 0) {
1701 if (i
== ZEBRA_ROUTE_BGP
) {
1702 vty_out(vty
, "%-20s %-20d %-20d \n", "ebgp",
1703 rib_cnt
[ZEBRA_ROUTE_BGP
]
1704 - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1705 fib_cnt
[ZEBRA_ROUTE_BGP
]
1706 - fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1707 vty_out(vty
, "%-20s %-20d %-20d \n", "ibgp",
1708 rib_cnt
[ZEBRA_ROUTE_IBGP
],
1709 fib_cnt
[ZEBRA_ROUTE_IBGP
]);
1711 vty_out(vty
, "%-20s %-20d %-20d \n",
1712 zebra_route_string(i
), rib_cnt
[i
],
1717 vty_out(vty
, "------\n");
1718 vty_out(vty
, "%-20s %-20d %-20d \n", "Totals",
1719 rib_cnt
[ZEBRA_ROUTE_TOTAL
], fib_cnt
[ZEBRA_ROUTE_TOTAL
]);
1723 /* Show route summary. */
1724 DEFUN (show_ip_route_summary
,
1725 show_ip_route_summary_cmd
,
1726 "show ip route [vrf NAME] summary",
1729 "IP routing table\n"
1731 "Summary of all routes\n")
1733 struct route_table
*table
;
1734 vrf_id_t vrf_id
= VRF_DEFAULT
;
1736 if (strmatch(argv
[3]->text
, "vrf"))
1737 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1739 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1743 vty_show_ip_route_summary(vty
, table
);
1748 /* Show route summary prefix. */
1749 DEFUN (show_ip_route_summary_prefix
,
1750 show_ip_route_summary_prefix_cmd
,
1751 "show ip route [vrf NAME] summary prefix",
1754 "IP routing table\n"
1756 "Summary of all routes\n"
1759 struct route_table
*table
;
1760 vrf_id_t vrf_id
= VRF_DEFAULT
;
1762 if (strmatch(argv
[3]->text
, "vrf"))
1763 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
1765 table
= zebra_vrf_table(AFI_IP
, SAFI_UNICAST
, vrf_id
);
1769 vty_show_ip_route_summary_prefix(vty
, table
);
1775 DEFUN (show_ip_route_vrf_all_addr
,
1776 show_ip_route_vrf_all_addr_cmd
,
1777 "show ip route vrf all A.B.C.D",
1780 "IP routing table\n"
1781 VRF_ALL_CMD_HELP_STR
1782 "Network in the IP routing table to display\n")
1786 struct prefix_ipv4 p
;
1787 struct route_table
*table
;
1788 struct route_node
*rn
;
1790 struct zebra_vrf
*zvrf
;
1792 ret
= str2prefix_ipv4(argv
[idx_ipv4
]->arg
, &p
);
1794 vty_out(vty
, "%% Malformed IPv4 address\n");
1798 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1800 if ((zvrf
= vrf
->info
) == NULL
1801 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1804 rn
= route_node_match(table
, (struct prefix
*)&p
);
1808 vty_show_ip_route_detail(vty
, rn
, 0);
1810 route_unlock_node(rn
);
1816 DEFUN (show_ip_route_vrf_all_prefix
,
1817 show_ip_route_vrf_all_prefix_cmd
,
1818 "show ip route vrf all A.B.C.D/M",
1821 "IP routing table\n"
1822 VRF_ALL_CMD_HELP_STR
1823 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1825 int idx_ipv4_prefixlen
= 5;
1827 struct prefix_ipv4 p
;
1828 struct route_table
*table
;
1829 struct route_node
*rn
;
1831 struct zebra_vrf
*zvrf
;
1833 ret
= str2prefix_ipv4(argv
[idx_ipv4_prefixlen
]->arg
, &p
);
1835 vty_out(vty
, "%% Malformed IPv4 address\n");
1839 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1841 if ((zvrf
= vrf
->info
) == NULL
1842 || (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1845 rn
= route_node_match(table
, (struct prefix
*)&p
);
1848 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
1849 route_unlock_node(rn
);
1853 vty_show_ip_route_detail(vty
, rn
, 0);
1855 route_unlock_node(rn
);
1861 DEFUN (show_ip_route_vrf_all_summary
,
1862 show_ip_route_vrf_all_summary_cmd
,
1863 "show ip route vrf all summary ",
1866 "IP routing table\n"
1867 VRF_ALL_CMD_HELP_STR
1868 "Summary of all routes\n")
1871 struct zebra_vrf
*zvrf
;
1873 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1874 if ((zvrf
= vrf
->info
) != NULL
)
1875 vty_show_ip_route_summary(vty
,
1876 zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1881 DEFUN (show_ip_route_vrf_all_summary_prefix
,
1882 show_ip_route_vrf_all_summary_prefix_cmd
,
1883 "show ip route vrf all summary prefix",
1886 "IP routing table\n"
1887 VRF_ALL_CMD_HELP_STR
1888 "Summary of all routes\n"
1892 struct zebra_vrf
*zvrf
;
1894 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1895 if ((zvrf
= vrf
->info
) != NULL
)
1896 vty_show_ip_route_summary_prefix(
1897 vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1902 /* Write static route configuration. */
1903 static int static_config(struct vty
*vty
, afi_t afi
, safi_t safi
,
1906 struct route_node
*rn
;
1907 struct static_route
*si
;
1908 struct route_table
*stable
;
1910 struct zebra_vrf
*zvrf
;
1911 char buf
[SRCDEST2STR_BUFFER
];
1914 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
1916 if (!(zvrf
= vrf
->info
))
1918 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1921 for (rn
= route_top(stable
); rn
; rn
= srcdest_route_next(rn
))
1922 for (si
= rn
->info
; si
; si
= si
->next
) {
1923 vty_out(vty
, "%s %s", cmd
,
1924 srcdest_rnode2str(rn
, buf
, sizeof buf
));
1927 case STATIC_IPV4_GATEWAY
:
1929 inet_ntoa(si
->addr
.ipv4
));
1931 case STATIC_IPV6_GATEWAY
:
1934 &si
->addr
.ipv6
, buf
,
1937 case STATIC_IFINDEX
:
1938 vty_out(vty
, " %s", si
->ifname
);
1940 case STATIC_BLACKHOLE
:
1941 vty_out(vty
, " Null0");
1943 case STATIC_IPV6_GATEWAY_IFINDEX
:
1944 vty_out(vty
, " %s %s",
1946 &si
->addr
.ipv6
, buf
,
1948 ifindex2ifname(si
->ifindex
,
1953 /* flags are incompatible with STATIC_BLACKHOLE
1955 if (si
->type
!= STATIC_BLACKHOLE
) {
1956 if (CHECK_FLAG(si
->flags
,
1958 vty_out(vty
, " %s", "reject");
1960 if (CHECK_FLAG(si
->flags
,
1961 ZEBRA_FLAG_BLACKHOLE
))
1967 vty_out(vty
, " tag %" ROUTE_TAG_PRI
,
1971 != ZEBRA_STATIC_DISTANCE_DEFAULT
)
1972 vty_out(vty
, " %d", si
->distance
);
1974 if (si
->vrf_id
!= VRF_DEFAULT
)
1975 vty_out(vty
, " vrf %s",
1978 /* Label information */
1979 if (si
->snh_label
.num_labels
)
1980 vty_out(vty
, " label %s",
1984 si
->snh_label
.label
,
1985 buf
, sizeof buf
, 0));
1995 /* General fucntion for IPv6 static route. */
1996 int static_ipv6_func(struct vty
*vty
, int add_cmd
, const char *dest_str
,
1997 const char *src_str
, const char *gate_str
,
1998 const char *ifname
, const char *flag_str
,
1999 const char *tag_str
, const char *distance_str
,
2000 const char *vrf_id_str
, const char *label_str
)
2004 struct prefix p
, src
;
2005 struct prefix_ipv6
*src_p
= NULL
;
2006 struct in6_addr
*gate
= NULL
;
2007 struct in6_addr gate_addr
;
2008 u_char type
= STATIC_BLACKHOLE
;
2010 route_tag_t tag
= 0;
2011 unsigned int ifindex
= 0;
2012 struct interface
*ifp
= NULL
;
2013 struct zebra_vrf
*zvrf
;
2014 struct static_nh_label snh_label
;
2016 ret
= str2prefix(dest_str
, &p
);
2018 vty_out(vty
, "%% Malformed address\n");
2019 return CMD_WARNING_CONFIG_FAILED
;
2023 ret
= str2prefix(src_str
, &src
);
2024 if (ret
<= 0 || src
.family
!= AF_INET6
) {
2025 vty_out(vty
, "%% Malformed source address\n");
2026 return CMD_WARNING_CONFIG_FAILED
;
2028 src_p
= (struct prefix_ipv6
*)&src
;
2031 /* Apply mask for given prefix. */
2034 /* Administrative distance. */
2036 distance
= atoi(distance_str
);
2038 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
2042 tag
= strtoul(tag_str
, NULL
, 10);
2044 /* When gateway is valid IPv6 addrees, then gate is treated as
2045 nexthop address other case gate is treated as interface name. */
2046 ret
= inet_pton(AF_INET6
, gate_str
, &gate_addr
);
2049 zvrf
= zebra_vrf_lookup_by_name(vrf_id_str
);
2052 vty_out(vty
, "%% vrf %s is not defined\n", vrf_id_str
);
2053 return CMD_WARNING_CONFIG_FAILED
;
2057 memset(&snh_label
, 0, sizeof(struct static_nh_label
));
2059 if (!mpls_enabled
) {
2061 "%% MPLS not turned on in kernel, ignoring command\n");
2062 return CMD_WARNING_CONFIG_FAILED
;
2064 int rc
= mpls_str2label(label_str
, &snh_label
.num_labels
,
2069 vty_out(vty
, "%% Malformed label(s)\n");
2073 "%% Cannot use reserved label(s) (%d-%d)\n",
2074 MPLS_MIN_RESERVED_LABEL
,
2075 MPLS_MAX_RESERVED_LABEL
);
2079 "%% Too many labels. Enter %d or fewer\n",
2083 return CMD_WARNING_CONFIG_FAILED
;
2087 /* Null0 static route. */
2088 if ((gate_str
!= NULL
)
2089 && (strncasecmp(gate_str
, "Null0", strlen(gate_str
)) == 0)) {
2091 vty_out(vty
, "%% can not have flag %s with Null0\n",
2093 return CMD_WARNING_CONFIG_FAILED
;
2096 static_add_route(AFI_IP6
, SAFI_UNICAST
, type
, &p
, src_p
,
2097 NULL
, ifindex
, ifname
,
2098 ZEBRA_FLAG_BLACKHOLE
, tag
, distance
,
2101 static_delete_route(AFI_IP6
, SAFI_UNICAST
, type
, &p
,
2102 src_p
, NULL
, ifindex
, tag
, distance
,
2109 switch (flag_str
[0]) {
2112 SET_FLAG(flag
, ZEBRA_FLAG_REJECT
);
2116 SET_FLAG(flag
, ZEBRA_FLAG_BLACKHOLE
);
2119 vty_out(vty
, "%% Malformed flag %s \n", flag_str
);
2120 return CMD_WARNING_CONFIG_FAILED
;
2125 /* When ifname is specified. It must be come with gateway
2128 vty_out(vty
, "%% Malformed address\n");
2129 return CMD_WARNING_CONFIG_FAILED
;
2131 type
= STATIC_IPV6_GATEWAY_IFINDEX
;
2133 ifp
= if_lookup_by_name(ifname
, zvrf_id(zvrf
));
2135 vty_out(vty
, "%% Malformed Interface name %s\n",
2137 return CMD_WARNING_CONFIG_FAILED
;
2139 ifindex
= ifp
->ifindex
;
2142 type
= STATIC_IPV6_GATEWAY
;
2145 type
= STATIC_IFINDEX
;
2146 ifp
= if_lookup_by_name(gate_str
, zvrf_id(zvrf
));
2148 vty_out(vty
, "%% Malformed Interface name %s\n",
2150 ifindex
= IFINDEX_DELETED
;
2152 ifindex
= ifp
->ifindex
;
2158 static_add_route(AFI_IP6
, SAFI_UNICAST
, type
, &p
, src_p
,
2159 (union g_addr
*)gate
, ifindex
, ifname
, flag
,
2160 tag
, distance
, zvrf
, &snh_label
);
2162 static_delete_route(AFI_IP6
, SAFI_UNICAST
, type
, &p
, src_p
,
2163 (union g_addr
*)gate
, ifindex
, tag
,
2164 distance
, zvrf
, &snh_label
);
2171 "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2173 "Establish static routes\n"
2174 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2175 "IPv6 source-dest route\n"
2176 "IPv6 source prefix\n"
2177 "IPv6 gateway address\n"
2178 "IPv6 gateway interface name\n"
2180 "Set tag for this route\n"
2182 "Distance value for this prefix\n"
2185 int idx_ipv6_prefixlen
= 2;
2186 int idx_ipv6_ifname
;
2188 char *src
, *tag
, *distance
, *vrf
;
2190 if (strmatch(argv
[3]->text
, "from")) {
2192 idx_ipv6_ifname
= 5;
2196 idx_ipv6_ifname
= 3;
2200 tag
= distance
= vrf
= NULL
;
2201 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2204 return static_ipv6_func(vty
, 1, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2205 argv
[idx_ipv6_ifname
]->arg
, NULL
, NULL
, tag
,
2206 distance
, vrf
, NULL
);
2209 DEFUN (ipv6_route_flags
,
2210 ipv6_route_flags_cmd
,
2211 "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2213 "Establish static routes\n"
2214 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2215 "IPv6 source-dest route\n"
2216 "IPv6 source prefix\n"
2217 "IPv6 gateway address\n"
2218 "IPv6 gateway interface name\n"
2219 "Emit an ICMP unreachable when matched\n"
2220 "Silently discard pkts when matched\n"
2221 "Set tag for this route\n"
2223 "Distance value for this prefix\n"
2226 int idx_ipv6_prefixlen
= 2;
2227 int idx_ipv6_ifname
;
2228 int idx_reject_blackhole
;
2230 char *src
, *tag
, *distance
, *vrf
;
2232 if (strmatch(argv
[3]->text
, "from")) {
2234 idx_ipv6_ifname
= 5;
2235 idx_reject_blackhole
= 6;
2239 idx_ipv6_ifname
= 3;
2240 idx_reject_blackhole
= 4;
2244 tag
= distance
= vrf
= NULL
;
2245 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2248 return static_ipv6_func(vty
, 1, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2249 argv
[idx_ipv6_ifname
]->arg
, NULL
,
2250 argv
[idx_reject_blackhole
]->arg
, tag
, distance
,
2254 DEFUN (ipv6_route_ifname
,
2255 ipv6_route_ifname_cmd
,
2256 "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2258 "Establish static routes\n"
2259 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2260 "IPv6 source-dest route\n"
2261 "IPv6 source prefix\n"
2262 "IPv6 gateway address\n"
2263 "IPv6 gateway interface name\n"
2264 "Set tag for this route\n"
2266 "Distance value for this prefix\n"
2269 int idx_ipv6_prefixlen
= 2;
2271 int idx_interface
= 4;
2273 char *src
, *tag
, *distance
, *vrf
;
2275 if (strmatch(argv
[3]->text
, "from")) {
2287 tag
= distance
= vrf
= NULL
;
2288 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2291 return static_ipv6_func(vty
, 1, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2292 argv
[idx_ipv6
]->arg
, argv
[idx_interface
]->arg
,
2293 NULL
, tag
, distance
, vrf
, NULL
);
2296 DEFUN (ipv6_route_ifname_flags
,
2297 ipv6_route_ifname_flags_cmd
,
2298 "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2300 "Establish static routes\n"
2301 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2302 "IPv6 source-dest route\n"
2303 "IPv6 source prefix\n"
2304 "IPv6 gateway address\n"
2305 "IPv6 gateway interface name\n"
2306 "Emit an ICMP unreachable when matched\n"
2307 "Silently discard pkts when matched\n"
2308 "Set tag for this route\n"
2310 "Distance value for this prefix\n"
2313 int idx_ipv6_prefixlen
= 2;
2316 int idx_reject_blackhole
;
2318 char *src
, *tag
, *distance
, *vrf
;
2320 if (strmatch(argv
[3]->text
, "from")) {
2324 idx_reject_blackhole
= 7;
2330 idx_reject_blackhole
= 5;
2334 tag
= distance
= vrf
= NULL
;
2335 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2338 return static_ipv6_func(vty
, 1, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2339 argv
[idx_ipv6
]->arg
, argv
[idx_interface
]->arg
,
2340 argv
[idx_reject_blackhole
]->arg
, tag
, distance
,
2344 DEFUN (no_ipv6_route
,
2346 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2349 "Establish static routes\n"
2350 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2351 "IPv6 source-dest route\n"
2352 "IPv6 source prefix\n"
2353 "IPv6 gateway address\n"
2354 "IPv6 gateway interface name\n"
2356 "Set tag for this route\n"
2358 "Distance value for this prefix\n"
2361 int idx_ipv6_prefixlen
= 3;
2362 int idx_ipv6_ifname
;
2364 char *src
, *tag
, *distance
, *vrf
;
2366 if (strmatch(argv
[4]->text
, "from")) {
2368 idx_ipv6_ifname
= 6;
2372 idx_ipv6_ifname
= 4;
2376 tag
= distance
= vrf
= NULL
;
2377 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2380 return static_ipv6_func(vty
, 0, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2381 argv
[idx_ipv6_ifname
]->arg
, NULL
, NULL
, tag
,
2382 distance
, vrf
, NULL
);
2385 DEFUN (no_ipv6_route_flags
,
2386 no_ipv6_route_flags_cmd
,
2387 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2390 "Establish static routes\n"
2391 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2392 "IPv6 source-dest route\n"
2393 "IPv6 source prefix\n"
2394 "IPv6 gateway address\n"
2395 "IPv6 gateway interface name\n"
2396 "Emit an ICMP unreachable when matched\n"
2397 "Silently discard pkts when matched\n"
2398 "Set tag for this route\n"
2400 "Distance value for this prefix\n"
2403 int idx_ipv6_prefixlen
= 3;
2404 int idx_ipv6_ifname
;
2405 int idx_reject_blackhole
;
2407 char *src
, *tag
, *distance
, *vrf
;
2409 if (strmatch(argv
[4]->text
, "from")) {
2411 idx_ipv6_ifname
= 6;
2412 idx_reject_blackhole
= 7;
2416 idx_ipv6_ifname
= 4;
2417 idx_reject_blackhole
= 5;
2421 tag
= distance
= vrf
= NULL
;
2422 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2425 return static_ipv6_func(vty
, 0, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2426 argv
[idx_ipv6_ifname
]->arg
, NULL
,
2427 argv
[idx_reject_blackhole
]->arg
, tag
, distance
,
2431 DEFUN (no_ipv6_route_ifname
,
2432 no_ipv6_route_ifname_cmd
,
2433 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2436 "Establish static routes\n"
2437 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2438 "IPv6 source-dest route\n"
2439 "IPv6 source prefix\n"
2440 "IPv6 gateway address\n"
2441 "IPv6 gateway interface name\n"
2442 "Set tag for this route\n"
2444 "Distance value for this prefix\n"
2447 int idx_ipv6_prefixlen
= 3;
2451 char *src
, *tag
, *distance
, *vrf
;
2453 if (strmatch(argv
[4]->text
, "from")) {
2465 tag
= distance
= vrf
= NULL
;
2466 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2469 return static_ipv6_func(vty
, 0, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2470 argv
[idx_ipv6
]->arg
, argv
[idx_interface
]->arg
,
2471 NULL
, tag
, distance
, vrf
, NULL
);
2474 DEFUN (no_ipv6_route_ifname_flags
,
2475 no_ipv6_route_ifname_flags_cmd
,
2476 "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
2479 "Establish static routes\n"
2480 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2481 "IPv6 source-dest route\n"
2482 "IPv6 source prefix\n"
2483 "IPv6 gateway address\n"
2484 "IPv6 gateway interface name\n"
2485 "Emit an ICMP unreachable when matched\n"
2486 "Silently discard pkts when matched\n"
2487 "Set tag for this route\n"
2489 "Distance value for this prefix\n"
2492 int idx_ipv6_prefixlen
= 3;
2495 int idx_reject_blackhole
;
2497 char *src
, *tag
, *distance
, *vrf
;
2499 if (strmatch(argv
[4]->text
, "from")) {
2503 idx_reject_blackhole
= 8;
2509 idx_reject_blackhole
= 6;
2513 tag
= distance
= vrf
= NULL
;
2514 zebra_vty_ip_route_tdv_helper(argc
, argv
, idx_curr
, &tag
, &distance
,
2517 return static_ipv6_func(vty
, 0, argv
[idx_ipv6_prefixlen
]->arg
, src
,
2518 argv
[idx_ipv6
]->arg
, argv
[idx_interface
]->arg
,
2519 argv
[idx_reject_blackhole
]->arg
, tag
, distance
,
2523 DEFUN (show_ipv6_route
,
2524 show_ipv6_route_cmd
,
2525 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA
"] [json]",
2528 "IP forwarding table\n"
2529 "IP routing table\n"
2531 "Show only routes with tag\n"
2534 "Show route matching the specified Network/Mask pair only\n"
2535 FRR_IP6_REDIST_HELP_STR_ZEBRA
2538 bool uf
= use_fib(argv
[2]);
2539 struct route_table
*table
;
2541 route_tag_t tag
= 0;
2542 vrf_id_t vrf_id
= VRF_DEFAULT
;
2544 struct zebra_vrf
*zvrf
;
2545 int uj
= use_json(argc
, argv
);
2548 bool longer_prefixes
= false;
2549 bool supernets_only
= false;
2552 if (argv_find(argv
, argc
, "vrf", &idx
)) {
2553 if (strmatch(argv
[idx
+ 1]->arg
, "all"))
2556 VRF_GET_ID(vrf_id
, argv
[idx
+ 1]->arg
);
2559 if (argv_find(argv
, argc
, "tag", &idx
))
2560 tag
= strtoul(argv
[idx
+ 1]->arg
, NULL
, 10);
2562 else if (argv_find(argv
, argc
, "X:X::X:X/M", &idx
)) {
2563 str2prefix(argv
[idx
]->arg
, &p
);
2564 longer_prefixes
= true;
2568 if (argv_find(argv
, argc
, "kernel", &idx
))
2569 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2570 else if (argv_find(argv
, argc
, "babel", &idx
))
2571 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2572 else if (argv_find(argv
, argc
, "connected", &idx
))
2573 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2574 else if (argv_find(argv
, argc
, "static", &idx
))
2575 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2576 else if (argv_find(argv
, argc
, "ripng", &idx
))
2577 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2578 else if (argv_find(argv
, argc
, "ospf6", &idx
))
2579 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2580 else if (argv_find(argv
, argc
, "isis", &idx
))
2581 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2582 else if (argv_find(argv
, argc
, "bgp", &idx
))
2583 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2584 else if (argv_find(argv
, argc
, "nhrp", &idx
))
2585 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2586 else if (argv_find(argv
, argc
, "table", &idx
))
2587 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2588 else if (argv_find(argv
, argc
, "vnc", &idx
))
2589 type
= proto_redistnum(AFI_IP6
, argv
[idx
]->text
);
2592 vty_out(vty
, "Unknown route type\n");
2598 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2600 if ((zvrf
= vrf
->info
) == NULL
2601 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
])
2605 do_show_ip_route(vty
, zvrf_name(zvrf
), AFI_IP6
,
2606 SAFI_UNICAST
, uf
, uj
, tag
,
2607 longer_prefixes
? &p
: NULL
,
2608 supernets_only
, type
, 0);
2611 vrf
= vrf_lookup_by_id(vrf_id
);
2612 do_show_ip_route(vty
, vrf
->name
, AFI_IP6
, SAFI_UNICAST
, uf
, uj
,
2613 tag
, longer_prefixes
? &p
: NULL
,
2614 supernets_only
, type
, 0);
2619 DEFUN (show_ipv6_route_addr
,
2620 show_ipv6_route_addr_cmd
,
2621 "show ipv6 route [vrf NAME] X:X::X:X",
2624 "IPv6 routing table\n"
2629 struct prefix_ipv6 p
;
2630 struct route_table
*table
;
2631 struct route_node
*rn
;
2632 vrf_id_t vrf_id
= VRF_DEFAULT
;
2634 if (strmatch(argv
[3]->text
, "vrf")) {
2635 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2636 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
2638 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
2642 vty_out(vty
, "Malformed IPv6 address\n");
2646 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2650 rn
= route_node_match(table
, (struct prefix
*)&p
);
2652 vty_out(vty
, "%% Network not in table\n");
2656 vty_show_ip_route_detail(vty
, rn
, 0);
2658 route_unlock_node(rn
);
2663 DEFUN (show_ipv6_route_prefix
,
2664 show_ipv6_route_prefix_cmd
,
2665 "show ipv6 route [vrf NAME] X:X::X:X/M",
2668 "IPv6 routing table\n"
2673 struct prefix_ipv6 p
;
2674 struct route_table
*table
;
2675 struct route_node
*rn
;
2676 vrf_id_t vrf_id
= VRF_DEFAULT
;
2678 if (strmatch(argv
[3]->text
, "vrf")) {
2679 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2680 ret
= str2prefix_ipv6(argv
[5]->arg
, &p
);
2682 ret
= str2prefix_ipv6(argv
[3]->arg
, &p
);
2685 vty_out(vty
, "Malformed IPv6 prefix\n");
2689 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2693 rn
= route_node_match(table
, (struct prefix
*)&p
);
2694 if (!rn
|| rn
->p
.prefixlen
!= p
.prefixlen
) {
2695 vty_out(vty
, "%% Network not in table\n");
2699 vty_show_ip_route_detail(vty
, rn
, 0);
2701 route_unlock_node(rn
);
2707 /* Show route summary. */
2708 DEFUN (show_ipv6_route_summary
,
2709 show_ipv6_route_summary_cmd
,
2710 "show ipv6 route [vrf NAME] summary",
2713 "IPv6 routing table\n"
2715 "Summary of all IPv6 routes\n")
2717 struct route_table
*table
;
2718 vrf_id_t vrf_id
= VRF_DEFAULT
;
2720 if (strmatch(argv
[3]->text
, "vrf"))
2721 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2723 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2727 vty_show_ip_route_summary(vty
, table
);
2733 /* Show ipv6 route summary prefix. */
2734 DEFUN (show_ipv6_route_summary_prefix
,
2735 show_ipv6_route_summary_prefix_cmd
,
2736 "show ipv6 route [vrf NAME] summary prefix",
2739 "IPv6 routing table\n"
2741 "Summary of all IPv6 routes\n"
2744 struct route_table
*table
;
2745 vrf_id_t vrf_id
= VRF_DEFAULT
;
2747 if (strmatch(argv
[3]->text
, "vrf"))
2748 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2750 table
= zebra_vrf_table(AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2754 vty_show_ip_route_summary_prefix(vty
, table
);
2761 * Show IPv6 mroute command.Used to dump
2762 * the Multicast routing table.
2764 DEFUN (show_ipv6_mroute
,
2765 show_ipv6_mroute_cmd
,
2766 "show ipv6 mroute [vrf NAME]",
2769 "IPv6 Multicast routing table\n"
2772 struct route_table
*table
;
2773 struct route_node
*rn
;
2774 struct route_entry
*re
;
2776 vrf_id_t vrf_id
= VRF_DEFAULT
;
2779 VRF_GET_ID(vrf_id
, argv
[4]->arg
);
2781 table
= zebra_vrf_table(AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2785 /* Show all IPv6 route. */
2786 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2787 RNODE_FOREACH_RE(rn
, re
)
2790 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2793 vty_show_ip_route(vty
, rn
, re
, NULL
);
2798 DEFUN (show_ipv6_route_vrf_all_addr
,
2799 show_ipv6_route_vrf_all_addr_cmd
,
2800 "show ipv6 route vrf all X:X::X:X",
2803 "IPv6 routing table\n"
2804 VRF_ALL_CMD_HELP_STR
2809 struct prefix_ipv6 p
;
2810 struct route_table
*table
;
2811 struct route_node
*rn
;
2813 struct zebra_vrf
*zvrf
;
2815 ret
= str2prefix_ipv6(argv
[idx_ipv6
]->arg
, &p
);
2817 vty_out(vty
, "Malformed IPv6 address\n");
2821 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2823 if ((zvrf
= vrf
->info
) == NULL
2824 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2827 rn
= route_node_match(table
, (struct prefix
*)&p
);
2831 vty_show_ip_route_detail(vty
, rn
, 0);
2833 route_unlock_node(rn
);
2839 DEFUN (show_ipv6_route_vrf_all_prefix
,
2840 show_ipv6_route_vrf_all_prefix_cmd
,
2841 "show ipv6 route vrf all X:X::X:X/M",
2844 "IPv6 routing table\n"
2845 VRF_ALL_CMD_HELP_STR
2848 int idx_ipv6_prefixlen
= 5;
2850 struct prefix_ipv6 p
;
2851 struct route_table
*table
;
2852 struct route_node
*rn
;
2854 struct zebra_vrf
*zvrf
;
2856 ret
= str2prefix_ipv6(argv
[idx_ipv6_prefixlen
]->arg
, &p
);
2858 vty_out(vty
, "Malformed IPv6 prefix\n");
2862 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2864 if ((zvrf
= vrf
->info
) == NULL
2865 || (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2868 rn
= route_node_match(table
, (struct prefix
*)&p
);
2871 if (rn
->p
.prefixlen
!= p
.prefixlen
) {
2872 route_unlock_node(rn
);
2876 vty_show_ip_route_detail(vty
, rn
, 0);
2878 route_unlock_node(rn
);
2884 DEFUN (show_ipv6_route_vrf_all_summary
,
2885 show_ipv6_route_vrf_all_summary_cmd
,
2886 "show ipv6 route vrf all summary",
2889 "IPv6 routing table\n"
2890 VRF_ALL_CMD_HELP_STR
2891 "Summary of all IPv6 routes\n")
2894 struct zebra_vrf
*zvrf
;
2896 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2897 if ((zvrf
= vrf
->info
) != NULL
)
2898 vty_show_ip_route_summary(vty
,
2899 zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2904 DEFUN (show_ipv6_mroute_vrf_all
,
2905 show_ipv6_mroute_vrf_all_cmd
,
2906 "show ipv6 mroute vrf all",
2909 "IPv6 Multicast routing table\n"
2910 VRF_ALL_CMD_HELP_STR
)
2912 struct route_table
*table
;
2913 struct route_node
*rn
;
2914 struct route_entry
*re
;
2916 struct zebra_vrf
*zvrf
;
2919 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2921 if ((zvrf
= vrf
->info
) == NULL
2922 || (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2925 /* Show all IPv6 route. */
2926 for (rn
= route_top(table
); rn
; rn
= srcdest_route_next(rn
))
2927 RNODE_FOREACH_RE(rn
, re
)
2930 vty_out(vty
, SHOW_ROUTE_V6_HEADER
);
2933 vty_show_ip_route(vty
, rn
, re
, NULL
);
2939 DEFUN (show_ipv6_route_vrf_all_summary_prefix
,
2940 show_ipv6_route_vrf_all_summary_prefix_cmd
,
2941 "show ipv6 route vrf all summary prefix",
2944 "IPv6 routing table\n"
2945 VRF_ALL_CMD_HELP_STR
2946 "Summary of all IPv6 routes\n"
2950 struct zebra_vrf
*zvrf
;
2952 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2953 if ((zvrf
= vrf
->info
) != NULL
)
2954 vty_show_ip_route_summary_prefix(
2955 vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2960 DEFUN (allow_external_route_update
,
2961 allow_external_route_update_cmd
,
2962 "allow-external-route-update",
2963 "Allow FRR routes to be overwritten by external processes\n")
2970 DEFUN (no_allow_external_route_update
,
2971 no_allow_external_route_update_cmd
,
2972 "no allow-external-route-update",
2974 "Allow FRR routes to be overwritten by external processes\n")
2989 struct zebra_vrf
*zvrf
;
2991 RB_FOREACH(vrf
, vrf_name_head
, &vrfs_by_name
)
2993 if (!(zvrf
= vrf
->info
))
2998 vty_out(vty
, "vrf %s ", zvrf_name(zvrf
));
2999 if (zvrf_id(zvrf
) == VRF_UNKNOWN
)
3000 vty_out(vty
, "inactive");
3002 vty_out(vty
, "id %u table %u", zvrf_id(zvrf
),
3010 DEFUN (show_evpn_vni
,
3015 "VxLAN information\n")
3017 struct zebra_vrf
*zvrf
;
3019 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3020 zebra_vxlan_print_vnis(vty
, zvrf
);
3024 DEFUN (show_evpn_vni_vni
,
3025 show_evpn_vni_vni_cmd
,
3026 "show evpn vni " CMD_VNI_RANGE
,
3029 "VxLAN Network Identifier\n"
3032 struct zebra_vrf
*zvrf
;
3035 vni
= strtoul(argv
[3]->arg
, NULL
, 10);
3036 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3037 zebra_vxlan_print_vni(vty
, zvrf
, vni
);
3041 DEFUN (show_evpn_mac_vni
,
3042 show_evpn_mac_vni_cmd
,
3043 "show evpn mac vni " CMD_VNI_RANGE
,
3047 "VxLAN Network Identifier\n"
3050 struct zebra_vrf
*zvrf
;
3053 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3054 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3055 zebra_vxlan_print_macs_vni(vty
, zvrf
, vni
);
3059 DEFUN (show_evpn_mac_vni_all
,
3060 show_evpn_mac_vni_all_cmd
,
3061 "show evpn mac vni all",
3065 "VxLAN Network Identifier\n"
3068 struct zebra_vrf
*zvrf
;
3070 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3071 zebra_vxlan_print_macs_all_vni(vty
, zvrf
);
3075 DEFUN (show_evpn_mac_vni_all_vtep
,
3076 show_evpn_mac_vni_all_vtep_cmd
,
3077 "show evpn mac vni all vtep A.B.C.D",
3081 "VxLAN Network Identifier\n"
3084 "Remote VTEP IP address\n")
3086 struct zebra_vrf
*zvrf
;
3087 struct in_addr vtep_ip
;
3089 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3090 vty_out(vty
, "%% Malformed VTEP IP address\n");
3093 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3094 zebra_vxlan_print_macs_all_vni_vtep(vty
, zvrf
, vtep_ip
);
3100 DEFUN (show_evpn_mac_vni_mac
,
3101 show_evpn_mac_vni_mac_cmd
,
3102 "show evpn mac vni " CMD_VNI_RANGE
" mac WORD",
3106 "VxLAN Network Identifier\n"
3109 "MAC address (e.g., 00:e0:ec:20:12:62)\n")
3111 struct zebra_vrf
*zvrf
;
3115 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3116 if (!prefix_str2mac(argv
[6]->arg
, &mac
)) {
3117 vty_out(vty
, "%% Malformed MAC address");
3120 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3121 zebra_vxlan_print_specific_mac_vni(vty
, zvrf
, vni
, &mac
);
3125 DEFUN (show_evpn_mac_vni_vtep
,
3126 show_evpn_mac_vni_vtep_cmd
,
3127 "show evpn mac vni " CMD_VNI_RANGE
" vtep A.B.C.D",
3131 "VxLAN Network Identifier\n"
3134 "Remote VTEP IP address\n")
3136 struct zebra_vrf
*zvrf
;
3138 struct in_addr vtep_ip
;
3140 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3141 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3142 vty_out(vty
, "%% Malformed VTEP IP address\n");
3146 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3147 zebra_vxlan_print_macs_vni_vtep(vty
, zvrf
, vni
, vtep_ip
);
3151 DEFUN (show_evpn_neigh_vni
,
3152 show_evpn_neigh_vni_cmd
,
3153 "show evpn arp-cache vni " CMD_VNI_RANGE
,
3156 "ARP and ND cache\n"
3157 "VxLAN Network Identifier\n"
3160 struct zebra_vrf
*zvrf
;
3163 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3164 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3165 zebra_vxlan_print_neigh_vni(vty
, zvrf
, vni
);
3169 DEFUN (show_evpn_neigh_vni_all
,
3170 show_evpn_neigh_vni_all_cmd
,
3171 "show evpn arp-cache vni all",
3174 "ARP and ND cache\n"
3175 "VxLAN Network Identifier\n"
3178 struct zebra_vrf
*zvrf
;
3180 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3181 zebra_vxlan_print_neigh_all_vni(vty
, zvrf
);
3185 DEFUN (show_evpn_neigh_vni_neigh
,
3186 show_evpn_neigh_vni_neigh_cmd
,
3187 "show evpn arp-cache vni " CMD_VNI_RANGE
" ip WORD",
3190 "ARP and ND cache\n"
3191 "VxLAN Network Identifier\n"
3194 "Neighbor address (IPv4 or IPv6 address)\n")
3196 struct zebra_vrf
*zvrf
;
3200 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3201 if (str2ipaddr(argv
[6]->arg
, &ip
) != 0) {
3202 vty_out(vty
, "%% Malformed Neighbor address\n");
3205 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3206 zebra_vxlan_print_specific_neigh_vni(vty
, zvrf
, vni
, &ip
);
3210 DEFUN (show_evpn_neigh_vni_vtep
,
3211 show_evpn_neigh_vni_vtep_cmd
,
3212 "show evpn arp-cache vni " CMD_VNI_RANGE
" vtep A.B.C.D",
3215 "ARP and ND cache\n"
3216 "VxLAN Network Identifier\n"
3219 "Remote VTEP IP address\n")
3221 struct zebra_vrf
*zvrf
;
3223 struct in_addr vtep_ip
;
3225 vni
= strtoul(argv
[4]->arg
, NULL
, 10);
3226 if (!inet_aton(argv
[6]->arg
, &vtep_ip
)) {
3227 vty_out(vty
, "%% Malformed VTEP IP address\n");
3231 zvrf
= vrf_info_lookup(VRF_DEFAULT
);
3232 zebra_vxlan_print_neigh_vni_vtep(vty
, zvrf
, vni
, vtep_ip
);
3236 /* Static ip route configuration write function. */
3237 static int zebra_ip_config(struct vty
*vty
)
3241 write
+= static_config(vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
3242 write
+= static_config(vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
3243 write
+= static_config(vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
3245 write
+= zebra_import_table_config(vty
);
3249 DEFUN (ip_zebra_import_table_distance
,
3250 ip_zebra_import_table_distance_cmd
,
3251 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
3253 "import routes from non-main kernel table\n"
3254 "kernel routing table id\n"
3255 "Distance for imported routes\n"
3256 "Default distance value\n"
3257 "route-map for filtering\n"
3260 u_int32_t table_id
= 0;
3262 table_id
= strtoul(argv
[2]->arg
, NULL
, 10);
3263 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
3265 strmatch(argv
[argc
- 2]->text
, "route-map")
3266 ? XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
)
3270 if (argc
== 7 || (argc
== 5 && !rmap
))
3271 distance
= strtoul(argv
[4]->arg
, NULL
, 10);
3273 if (!is_zebra_valid_kernel_table(table_id
)) {
3275 "Invalid routing table ID, %d. Must be in range 1-252\n",
3280 if (is_zebra_main_routing_table(table_id
)) {
3282 "Invalid routing table ID, %d. Must be non-default table\n",
3287 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
3289 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3294 DEFUN (no_ip_zebra_import_table
,
3295 no_ip_zebra_import_table_cmd
,
3296 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3299 "import routes from non-main kernel table\n"
3300 "kernel routing table id\n"
3301 "Distance for imported routes\n"
3302 "Default distance value\n"
3303 "route-map for filtering\n"
3306 u_int32_t table_id
= 0;
3307 table_id
= strtoul(argv
[3]->arg
, NULL
, 10);
3309 if (!is_zebra_valid_kernel_table(table_id
)) {
3311 "Invalid routing table ID. Must be in range 1-252\n");
3315 if (is_zebra_main_routing_table(table_id
)) {
3317 "Invalid routing table ID, %d. Must be non-default table\n",
3322 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
3325 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
3328 static int config_write_protocol(struct vty
*vty
)
3331 vty_out(vty
, "allow-external-route-update\n");
3333 if (zebra_rnh_ip_default_route
)
3334 vty_out(vty
, "ip nht resolve-via-default\n");
3336 if (zebra_rnh_ipv6_default_route
)
3337 vty_out(vty
, "ipv6 nht resolve-via-default\n");
3339 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get();
3341 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3342 vty_out(vty
, "ip multicast rpf-lookup-mode %s\n",
3343 ipv4_multicast_mode
== MCAST_URIB_ONLY
3345 : ipv4_multicast_mode
== MCAST_MRIB_ONLY
3347 : ipv4_multicast_mode
3348 == MCAST_MIX_MRIB_FIRST
3350 : ipv4_multicast_mode
3351 == MCAST_MIX_DISTANCE
3355 zebra_routemap_config_write_protocol(vty
);
3360 /* IP node for static routes. */
3361 static struct cmd_node ip_node
= {IP_NODE
, "", 1};
3362 static struct cmd_node protocol_node
= {PROTOCOL_NODE
, "", 1};
3365 void zebra_vty_init(void)
3367 install_node(&ip_node
, zebra_ip_config
);
3368 install_node(&protocol_node
, config_write_protocol
);
3370 install_element(CONFIG_NODE
, &allow_external_route_update_cmd
);
3371 install_element(CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3372 install_element(CONFIG_NODE
, &ip_mroute_dist_cmd
);
3373 install_element(CONFIG_NODE
, &no_ip_mroute_dist_cmd
);
3374 install_element(CONFIG_NODE
, &ip_multicast_mode_cmd
);
3375 install_element(CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3376 install_element(CONFIG_NODE
, &ip_route_cmd
);
3377 install_element(CONFIG_NODE
, &ip_route_flags_cmd
);
3378 install_element(CONFIG_NODE
, &ip_route_mask_cmd
);
3379 install_element(CONFIG_NODE
, &ip_route_mask_flags_cmd
);
3380 install_element(CONFIG_NODE
, &no_ip_route_cmd
);
3381 install_element(CONFIG_NODE
, &no_ip_route_mask_cmd
);
3382 install_element(CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3383 install_element(CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3385 install_element(VIEW_NODE
, &show_vrf_cmd
);
3386 install_element(VIEW_NODE
, &show_ip_route_cmd
);
3387 install_element(VIEW_NODE
, &show_ip_nht_cmd
);
3388 install_element(VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
3389 install_element(VIEW_NODE
, &show_ipv6_nht_cmd
);
3390 install_element(VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
3391 install_element(VIEW_NODE
, &show_ip_route_addr_cmd
);
3392 install_element(VIEW_NODE
, &show_ip_route_prefix_cmd
);
3393 install_element(VIEW_NODE
, &show_ip_route_summary_cmd
);
3394 install_element(VIEW_NODE
, &show_ip_route_summary_prefix_cmd
);
3396 install_element(VIEW_NODE
, &show_ip_rpf_cmd
);
3397 install_element(VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3399 /* Commands for VRF */
3401 install_element(CONFIG_NODE
, &no_ip_route_flags_cmd
);
3402 install_element(CONFIG_NODE
, &no_ip_route_mask_flags_cmd
);
3404 install_element(VIEW_NODE
, &show_ip_route_vrf_all_addr_cmd
);
3405 install_element(VIEW_NODE
, &show_ip_route_vrf_all_prefix_cmd
);
3406 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_cmd
);
3407 install_element(VIEW_NODE
, &show_ip_route_vrf_all_summary_prefix_cmd
);
3409 install_element(CONFIG_NODE
, &ipv6_route_cmd
);
3410 install_element(CONFIG_NODE
, &ipv6_route_flags_cmd
);
3411 install_element(CONFIG_NODE
, &ipv6_route_ifname_cmd
);
3412 install_element(CONFIG_NODE
, &ipv6_route_ifname_flags_cmd
);
3413 install_element(CONFIG_NODE
, &no_ipv6_route_cmd
);
3414 install_element(CONFIG_NODE
, &no_ipv6_route_flags_cmd
);
3415 install_element(CONFIG_NODE
, &no_ipv6_route_ifname_cmd
);
3416 install_element(CONFIG_NODE
, &no_ipv6_route_ifname_flags_cmd
);
3417 install_element(CONFIG_NODE
, &ip_nht_default_route_cmd
);
3418 install_element(CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3419 install_element(CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3420 install_element(CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3421 install_element(VIEW_NODE
, &show_ipv6_route_cmd
);
3422 install_element(VIEW_NODE
, &show_ipv6_route_summary_cmd
);
3423 install_element(VIEW_NODE
, &show_ipv6_route_summary_prefix_cmd
);
3424 install_element(VIEW_NODE
, &show_ipv6_route_addr_cmd
);
3425 install_element(VIEW_NODE
, &show_ipv6_route_prefix_cmd
);
3426 install_element(VIEW_NODE
, &show_ipv6_mroute_cmd
);
3428 /* Commands for VRF */
3429 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_cmd
);
3430 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_summary_prefix_cmd
);
3431 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_addr_cmd
);
3432 install_element(VIEW_NODE
, &show_ipv6_route_vrf_all_prefix_cmd
);
3434 install_element(VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);
3436 install_element(VIEW_NODE
, &show_evpn_vni_cmd
);
3437 install_element(VIEW_NODE
, &show_evpn_vni_vni_cmd
);
3438 install_element(VIEW_NODE
, &show_evpn_mac_vni_cmd
);
3439 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_cmd
);
3440 install_element(VIEW_NODE
, &show_evpn_mac_vni_all_vtep_cmd
);
3441 install_element(VIEW_NODE
, &show_evpn_mac_vni_mac_cmd
);
3442 install_element(VIEW_NODE
, &show_evpn_mac_vni_vtep_cmd
);
3443 install_element(VIEW_NODE
, &show_evpn_neigh_vni_cmd
);
3444 install_element(VIEW_NODE
, &show_evpn_neigh_vni_all_cmd
);
3445 install_element(VIEW_NODE
, &show_evpn_neigh_vni_neigh_cmd
);
3446 install_element(VIEW_NODE
, &show_evpn_neigh_vni_vtep_cmd
);