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"
36 #include "zebra/zserv.h"
37 #include "zebra/zebra_vrf.h"
38 #include "zebra/zebra_mpls.h"
39 #include "zebra/zebra_rnh.h"
40 #include "zebra/redistribute.h"
41 #include "zebra/zebra_routemap.h"
42 #include "zebra/zebra_static.h"
45 extern int allow_delete
;
47 static int do_show_ip_route(struct vty
*vty
, const char *vrf_name
,
48 afi_t afi
, safi_t safi
, bool use_fib
, u_char use_json
,
49 route_tag_t tag
, struct prefix
*longer_prefix_p
,
50 bool supernets_only
, int type
, u_short ospf_instance_id
);
51 static void vty_show_ip_route_detail (struct vty
*vty
, struct route_node
*rn
,
54 #define ONE_DAY_SECOND 60*60*24
55 #define ONE_WEEK_SECOND 60*60*24*7
57 /* General function for static route. */
59 zebra_static_ipv4 (struct vty
*vty
, safi_t safi
, int add_cmd
,
60 const char *dest_str
, const char *mask_str
,
61 const char *gate_str
, const char *flag_str
,
62 const char *tag_str
, const char *distance_str
,
63 const char *vrf_id_str
, const char *label_str
)
72 struct zebra_vrf
*zvrf
= NULL
;
73 unsigned int ifindex
= 0;
74 const char *ifname
= NULL
;
75 u_char type
= STATIC_BLACKHOLE
;
76 struct static_nh_label snh_label
;
78 memset (&snh_label
, 0, sizeof (struct static_nh_label
));
79 ret
= str2prefix (dest_str
, &p
);
82 vty_out (vty
, "%% Malformed address%s", VTY_NEWLINE
);
86 /* Cisco like mask notation. */
89 ret
= inet_aton (mask_str
, &mask
);
92 vty_out (vty
, "%% Malformed address%s", VTY_NEWLINE
);
95 p
.prefixlen
= ip_masklen (mask
);
98 /* Apply mask for given prefix. */
101 /* Administrative distance. */
103 distance
= atoi (distance_str
);
105 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
109 VTY_GET_INTEGER_RANGE("tag", tag
, tag_str
, 0, 4294967295);
112 zvrf
= zebra_vrf_lookup_by_name (vrf_id_str
);
116 vty_out (vty
, "%% vrf %s is not defined%s", vrf_id_str
, VTY_NEWLINE
);
125 vty_out (vty
, "%% MPLS not turned on in kernel, ignoring command%s",
129 int rc
= mpls_str2label (label_str
, &snh_label
.num_labels
,
135 vty_out (vty
, "%% Malformed label(s)%s", VTY_NEWLINE
);
138 vty_out (vty
, "%% Cannot use reserved label(s) (%d-%d)%s",
139 MPLS_MIN_RESERVED_LABEL
, MPLS_MAX_RESERVED_LABEL
,
143 vty_out (vty
, "%% Too many labels. Enter %d or fewer%s",
144 MPLS_MAX_LABELS
, VTY_NEWLINE
);
151 /* Null0 static route. */
152 if ((gate_str
!= NULL
) && (strncasecmp (gate_str
, "Null0", strlen (gate_str
)) == 0))
156 vty_out (vty
, "%% can not have flag %s with Null0%s", flag_str
, VTY_NEWLINE
);
160 static_add_route (AFI_IP
, safi
, type
, &p
, NULL
, NULL
, ifindex
, ifname
,
161 ZEBRA_FLAG_BLACKHOLE
, tag
, distance
, zvrf
, &snh_label
);
163 static_delete_route (AFI_IP
, safi
, type
, &p
, NULL
, NULL
, ifindex
, tag
,
164 distance
, zvrf
, &snh_label
);
170 switch(flag_str
[0]) {
173 SET_FLAG (flag
, ZEBRA_FLAG_REJECT
);
177 SET_FLAG (flag
, ZEBRA_FLAG_BLACKHOLE
);
180 vty_out (vty
, "%% Malformed flag %s %s", flag_str
, VTY_NEWLINE
);
185 if (gate_str
== NULL
)
188 static_add_route (AFI_IP
, safi
, type
, &p
, NULL
, NULL
, ifindex
, ifname
, flag
,
189 tag
, distance
, zvrf
, &snh_label
);
191 static_delete_route (AFI_IP
, safi
, type
, &p
, NULL
, NULL
, ifindex
, tag
, distance
,
197 /* When gateway is A.B.C.D format, gate is treated as nexthop
198 address other case gate is treated as interface name. */
199 ret
= inet_aton (gate_str
, &gate
);
202 struct interface
*ifp
= if_lookup_by_name (gate_str
, zvrf_id (zvrf
));
205 vty_out (vty
, "%% Unknown interface: %s%s", gate_str
, VTY_NEWLINE
);
206 ifindex
= IFINDEX_DELETED
;
209 ifindex
= ifp
->ifindex
;
211 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
, ifindex
, ifname
,
219 flag
, tag
, distance
, zvrf
, &snh_label
);
221 static_delete_route (AFI_IP
, safi
, type
, &p
, NULL
,
222 ifindex
? NULL
: (union g_addr
*)&gate
, ifindex
, tag
,
223 distance
, zvrf
, &snh_label
);
228 /* Static unicast routes for multicast RPF lookup. */
229 DEFUN (ip_mroute_dist
,
231 "ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
233 "Configure static unicast route into MRIB for multicast RPF lookup\n"
234 "IP destination prefix (e.g. 10.0.0.0/8)\n"
236 "Nexthop interface name\n"
239 char *destprefix
= argv
[2]->arg
;
240 char *nexthop
= argv
[3]->arg
;
241 char *distance
= (argc
== 5) ? argv
[4]->arg
: NULL
;
243 return zebra_static_ipv4 (vty
, SAFI_MULTICAST
, 1, destprefix
, NULL
, nexthop
, NULL
, NULL
, distance
, NULL
, NULL
);
246 DEFUN (no_ip_mroute_dist
,
247 no_ip_mroute_dist_cmd
,
248 "no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
251 "Configure static unicast route into MRIB for multicast RPF lookup\n"
252 "IP destination prefix (e.g. 10.0.0.0/8)\n"
254 "Nexthop interface name\n"
257 char *destprefix
= argv
[3]->arg
;
258 char *nexthop
= argv
[4]->arg
;
259 char *distance
= (argc
== 6) ? argv
[5]->arg
: NULL
;
261 return zebra_static_ipv4 (vty
, SAFI_MULTICAST
, 0, destprefix
, NULL
, nexthop
, NULL
, NULL
, distance
, NULL
, NULL
);
264 DEFUN (ip_multicast_mode
,
265 ip_multicast_mode_cmd
,
266 "ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
268 "Multicast options\n"
269 "RPF lookup behavior\n"
270 "Lookup in unicast RIB only\n"
271 "Lookup in multicast RIB only\n"
272 "Try multicast RIB first, fall back to unicast RIB\n"
273 "Lookup both, use entry with lower distance\n"
274 "Lookup both, use entry with longer prefix\n")
276 char *mode
= argv
[3]->text
;
278 if (strmatch (mode
, "urib-only"))
279 multicast_mode_ipv4_set (MCAST_URIB_ONLY
);
280 else if (strmatch (mode
, "mrib-only"))
281 multicast_mode_ipv4_set (MCAST_MRIB_ONLY
);
282 else if (strmatch (mode
, "mrib-then-urib"))
283 multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST
);
284 else if (strmatch (mode
, "lower-distance"))
285 multicast_mode_ipv4_set (MCAST_MIX_DISTANCE
);
286 else if (strmatch (mode
, "longer-prefix"))
287 multicast_mode_ipv4_set (MCAST_MIX_PFXLEN
);
290 vty_out (vty
, "Invalid mode specified%s", VTY_NEWLINE
);
297 DEFUN (no_ip_multicast_mode
,
298 no_ip_multicast_mode_cmd
,
299 "no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
302 "Multicast options\n"
303 "RPF lookup behavior\n"
304 "Lookup in unicast RIB only\n"
305 "Lookup in multicast RIB only\n"
306 "Try multicast RIB first, fall back to unicast RIB\n"
307 "Lookup both, use entry with lower distance\n"
308 "Lookup both, use entry with longer prefix\n")
310 multicast_mode_ipv4_set (MCAST_NO_CONFIG
);
317 "show ip rpf [json]",
320 "Display RPF information for multicast source\n"
323 int uj
= use_json(argc
, argv
);
324 return do_show_ip_route (vty
, VRF_DEFAULT_NAME
, AFI_IP
, SAFI_MULTICAST
, false, uj
, 0, NULL
, false, -1, 0);
327 DEFUN (show_ip_rpf_addr
,
328 show_ip_rpf_addr_cmd
,
329 "show ip rpf A.B.C.D",
332 "Display RPF information for multicast source\n"
333 "IP multicast source address (e.g. 10.0.0.0)\n")
337 struct route_node
*rn
;
338 struct route_entry
*re
;
341 ret
= inet_aton (argv
[idx_ipv4
]->arg
, &addr
);
344 vty_out (vty
, "%% Malformed address%s", VTY_NEWLINE
);
348 re
= rib_match_ipv4_multicast (VRF_DEFAULT
, addr
, &rn
);
351 vty_show_ip_route_detail (vty
, rn
, 1);
353 vty_out (vty
, "%% No match for RPF lookup%s", VTY_NEWLINE
);
359 zebra_vty_ip_route_tdv_helper (int argc
, struct cmd_token
*argv
[],
360 int idx_curr
, char **tag
,
361 char **distance
, char **vrf
, char **labels
)
364 while (idx_curr
< argc
)
366 if (strmatch (argv
[idx_curr
]->text
, "tag"))
369 *tag
= argv
[idx_curr
+1]->arg
;
372 else if (strmatch (argv
[idx_curr
]->text
, "vrf"))
375 *vrf
= argv
[idx_curr
+1]->arg
;
378 else if (strmatch (argv
[idx_curr
]->text
, "label"))
381 *labels
= argv
[idx_curr
+1]->arg
;
387 *distance
= argv
[idx_curr
]->arg
;
395 /* Static route configuration. */
398 "ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
400 "Establish static routes\n"
401 "IP destination prefix (e.g. 10.0.0.0/8)\n"
402 "IP gateway address\n"
403 "IP gateway interface name\n"
405 "Set tag for this route\n"
407 "Distance value for this route\n"
410 int idx_ipv4_prefixlen
= 2;
411 int idx_ipv4_ifname_null
= 3;
413 char *tag
, *distance
, *vrf
;
415 tag
= distance
= vrf
= NULL
;
416 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
418 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 1,
419 argv
[idx_ipv4_prefixlen
]->arg
,
421 argv
[idx_ipv4_ifname_null
]->arg
,
423 tag
, distance
, vrf
, NULL
);
426 DEFUN (ip_route_flags
,
428 "ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
430 "Establish static routes\n"
431 "IP destination prefix (e.g. 10.0.0.0/8)\n"
432 "Emit an ICMP unreachable when matched\n"
433 "Silently discard pkts when matched\n"
434 "Set tag for this route\n"
436 "Distance value for this route\n"
440 int idx_ipv4_prefixlen
= 2;
441 int idx_reject_blackhole
= 3;
443 char *tag
, *distance
, *vrf
;
445 tag
= distance
= vrf
= NULL
;
446 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
448 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 1,
449 argv
[idx_ipv4_prefixlen
]->arg
,
452 argv
[idx_reject_blackhole
]->arg
,
453 tag
, distance
, vrf
, NULL
);
456 /* Mask as A.B.C.D format. */
457 DEFUN (ip_route_mask
,
459 "ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
461 "Establish static routes\n"
462 "IP destination prefix\n"
463 "IP destination prefix mask\n"
464 "IP gateway address\n"
465 "IP gateway interface name\n"
467 "Set tag for this route\n"
469 "Distance value for this route\n"
475 int idx_ipv4_ifname_null
= 4;
477 char *tag
, *distance
, *vrf
;
479 tag
= distance
= vrf
= NULL
;
480 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
482 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 1,
484 argv
[idx_ipv4_2
]->arg
,
485 argv
[idx_ipv4_ifname_null
]->arg
,
486 NULL
, tag
, distance
, vrf
, NULL
);
489 DEFUN (ip_route_mask_flags
,
490 ip_route_mask_flags_cmd
,
491 "ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
493 "Establish static routes\n"
494 "IP destination prefix\n"
495 "IP destination prefix mask\n"
496 "Emit an ICMP unreachable when matched\n"
497 "Silently discard pkts when matched\n"
498 "Set tag for this route\n"
500 "Distance value for this route\n"
506 int idx_reject_blackhole
= 4;
508 char *tag
, *distance
, *vrf
;
510 tag
= distance
= vrf
= NULL
;
511 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
513 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 1,
515 argv
[idx_ipv4_2
]->arg
,
517 argv
[idx_reject_blackhole
]->arg
,
518 tag
, distance
, vrf
, NULL
);
523 "no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
526 "Establish static routes\n"
527 "IP destination prefix (e.g. 10.0.0.0/8)\n"
528 "IP gateway address\n"
529 "IP gateway interface name\n"
531 "Tag of this route\n"
533 "Distance value for this route\n"
537 int idx_ipv4_prefixlen
= 3;
538 int idx_ipv4_ifname_null
= 4;
540 char *tag
, *distance
, *vrf
;
542 tag
= distance
= vrf
= NULL
;
543 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
545 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 0,
546 argv
[idx_ipv4_prefixlen
]->arg
,
548 argv
[idx_ipv4_ifname_null
]->arg
,
550 tag
, distance
, vrf
, NULL
);
553 DEFUN (no_ip_route_flags
,
554 no_ip_route_flags_cmd
,
555 "no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
558 "Establish static routes\n"
559 "IP destination prefix (e.g. 10.0.0.0/8)\n"
560 "Emit an ICMP unreachable when matched\n"
561 "Silently discard pkts when matched\n"
562 "Tag of this route\n"
564 "Distance value for this route\n"
568 int idx_ipv4_prefixlen
= 3;
570 char *tag
, *distance
, *vrf
;
572 tag
= distance
= vrf
= NULL
;
573 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
575 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 0,
576 argv
[idx_ipv4_prefixlen
]->arg
,
578 tag
, distance
, vrf
, NULL
);
581 DEFUN (no_ip_route_mask
,
582 no_ip_route_mask_cmd
,
583 "no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
586 "Establish static routes\n"
587 "IP destination prefix\n"
588 "IP destination prefix mask\n"
589 "IP gateway address\n"
590 "IP gateway interface name\n"
592 "Tag of this route\n"
594 "Distance value for this route\n"
600 int idx_ipv4_ifname_null
= 5;
602 char *tag
, *distance
, *vrf
;
604 tag
= distance
= vrf
= NULL
;
605 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
607 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 0,
609 argv
[idx_ipv4_2
]->arg
,
610 argv
[idx_ipv4_ifname_null
]->arg
,
612 tag
, distance
, vrf
, NULL
);
615 DEFUN (no_ip_route_mask_flags
,
616 no_ip_route_mask_flags_cmd
,
617 "no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
620 "Establish static routes\n"
621 "IP destination prefix\n"
622 "IP destination prefix mask\n"
623 "Emit an ICMP unreachable when matched\n"
624 "Silently discard pkts when matched\n"
625 "Tag of this route\n"
627 "Distance value for this route\n"
634 char *tag
, *distance
, *vrf
;
636 tag
= distance
= vrf
= NULL
;
637 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
639 return zebra_static_ipv4 (vty
, SAFI_UNICAST
, 0,
641 argv
[idx_ipv4_2
]->arg
,
643 tag
, distance
, vrf
, NULL
);
646 /* New RIB. Detailed information for IPv4 route. */
648 vty_show_ip_route_detail (struct vty
*vty
, struct route_node
*rn
, int mcast
)
650 struct route_entry
*re
;
651 struct nexthop
*nexthop
, *tnexthop
;
653 char buf
[SRCDEST2STR_BUFFER
];
654 struct zebra_vrf
*zvrf
;
656 RNODE_FOREACH_RE (rn
, re
)
658 const char *mcast_info
= "";
661 rib_table_info_t
*info
= srcdest_rnode_table_info(rn
);
662 mcast_info
= (info
->safi
== SAFI_MULTICAST
)
663 ? " using Multicast RIB"
664 : " using Unicast RIB";
667 vty_out (vty
, "Routing entry for %s%s%s",
668 srcdest_rnode2str(rn
, buf
, sizeof(buf
)), mcast_info
,
670 vty_out (vty
, " Known via \"%s", zebra_route_string (re
->type
));
672 vty_out (vty
, "[%d]", re
->instance
);
674 vty_out (vty
, ", distance %u, metric %u", re
->distance
, re
->metric
);
676 vty_out (vty
, ", tag %d", re
->tag
);
678 vty_out (vty
, ", mtu %u", re
->mtu
);
679 if (re
->vrf_id
!= VRF_DEFAULT
)
681 zvrf
= vrf_info_lookup(re
->vrf_id
);
682 vty_out (vty
, ", vrf %s", zvrf_name (zvrf
));
684 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_SELECTED
))
685 vty_out (vty
, ", best");
687 vty_out (vty
, ", refcnt %ld", re
->refcnt
);
688 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
689 vty_out (vty
, ", blackhole");
690 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_REJECT
))
691 vty_out (vty
, ", reject");
692 vty_out (vty
, "%s", VTY_NEWLINE
);
694 if (re
->type
== ZEBRA_ROUTE_RIP
695 || re
->type
== ZEBRA_ROUTE_OSPF
696 || re
->type
== ZEBRA_ROUTE_ISIS
697 || re
->type
== ZEBRA_ROUTE_NHRP
698 || re
->type
== ZEBRA_ROUTE_TABLE
699 || re
->type
== ZEBRA_ROUTE_BGP
)
704 uptime
= time (NULL
);
705 uptime
-= re
->uptime
;
706 tm
= gmtime (&uptime
);
708 vty_out (vty
, " Last update ");
710 if (uptime
< ONE_DAY_SECOND
)
711 vty_out (vty
, "%02d:%02d:%02d",
712 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
713 else if (uptime
< ONE_WEEK_SECOND
)
714 vty_out (vty
, "%dd%02dh%02dm",
715 tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
717 vty_out (vty
, "%02dw%dd%02dh",
719 tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
720 vty_out (vty
, " ago%s", VTY_NEWLINE
);
723 for (ALL_NEXTHOPS_RO(re
->nexthop
, nexthop
, tnexthop
, recursing
))
727 vty_out (vty
, " %c%s",
728 CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
) ? '*' : ' ',
729 recursing
? " " : "");
731 switch (nexthop
->type
)
733 case NEXTHOP_TYPE_IPV4
:
734 case NEXTHOP_TYPE_IPV4_IFINDEX
:
735 vty_out (vty
, " %s", inet_ntoa (nexthop
->gate
.ipv4
));
736 if (nexthop
->ifindex
)
737 vty_out (vty
, ", via %s",
738 ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
740 case NEXTHOP_TYPE_IPV6
:
741 case NEXTHOP_TYPE_IPV6_IFINDEX
:
743 inet_ntop (AF_INET6
, &nexthop
->gate
.ipv6
, buf
, sizeof buf
));
744 if (nexthop
->ifindex
)
745 vty_out (vty
, ", via %s",
746 ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
748 case NEXTHOP_TYPE_IFINDEX
:
749 vty_out (vty
, " directly connected, %s",
750 ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
752 case NEXTHOP_TYPE_BLACKHOLE
:
753 vty_out (vty
, " directly connected, Null0");
758 if (! CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
759 vty_out (vty
, " inactive");
761 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
762 vty_out (vty
, " onlink");
764 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
765 vty_out (vty
, " (recursive)");
767 switch (nexthop
->type
)
769 case NEXTHOP_TYPE_IPV4
:
770 case NEXTHOP_TYPE_IPV4_IFINDEX
:
771 if (nexthop
->src
.ipv4
.s_addr
)
773 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, addrstr
,
775 vty_out (vty
, ", src %s", addrstr
);
778 case NEXTHOP_TYPE_IPV6
:
779 case NEXTHOP_TYPE_IPV6_IFINDEX
:
780 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
))
782 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, addrstr
,
784 vty_out (vty
, ", src %s", addrstr
);
791 /* Label information */
792 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
)
794 vty_out (vty
, ", label %s",
795 mpls_label2str (nexthop
->nh_label
->num_labels
,
796 nexthop
->nh_label
->label
, buf
, sizeof buf
, 1));
799 vty_out (vty
, "%s", VTY_NEWLINE
);
801 vty_out (vty
, "%s", VTY_NEWLINE
);
806 vty_show_ip_route (struct vty
*vty
, struct route_node
*rn
, struct route_entry
*re
,
809 struct nexthop
*nexthop
, *tnexthop
;
812 char buf
[SRCDEST2STR_BUFFER
];
813 json_object
*json_nexthops
= NULL
;
814 json_object
*json_nexthop
= NULL
;
815 json_object
*json_route
= NULL
;
816 json_object
*json_labels
= NULL
;
820 json_route
= json_object_new_object();
821 json_nexthops
= json_object_new_array();
823 json_object_string_add(json_route
, "prefix", srcdest_rnode2str (rn
, buf
, sizeof buf
));
824 json_object_string_add(json_route
, "protocol", zebra_route_string(re
->type
));
827 json_object_int_add(json_route
, "instance", re
->instance
);
830 json_object_int_add(json_route
, "vrfId", re
->vrf_id
);
832 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_SELECTED
))
833 json_object_boolean_true_add(json_route
, "selected");
835 if (re
->type
!= ZEBRA_ROUTE_CONNECT
&& re
->type
!= ZEBRA_ROUTE_KERNEL
)
837 json_object_int_add(json_route
, "distance", re
->distance
);
838 json_object_int_add(json_route
, "metric", re
->metric
);
841 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
842 json_object_boolean_true_add(json_route
, "blackhole");
844 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_REJECT
))
845 json_object_boolean_true_add(json_route
, "reject");
847 if (re
->type
== ZEBRA_ROUTE_RIP
848 || re
->type
== ZEBRA_ROUTE_OSPF
849 || re
->type
== ZEBRA_ROUTE_ISIS
850 || re
->type
== ZEBRA_ROUTE_NHRP
851 || re
->type
== ZEBRA_ROUTE_TABLE
852 || re
->type
== ZEBRA_ROUTE_BGP
)
857 uptime
= time (NULL
);
858 uptime
-= re
->uptime
;
859 tm
= gmtime (&uptime
);
861 if (uptime
< ONE_DAY_SECOND
)
862 sprintf(buf
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
863 else if (uptime
< ONE_WEEK_SECOND
)
864 sprintf(buf
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
866 sprintf(buf
, "%02dw%dd%02dh", tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
868 json_object_string_add(json_route
, "uptime", buf
);
871 for (ALL_NEXTHOPS_RO(re
->nexthop
, nexthop
, tnexthop
, recursing
))
873 json_nexthop
= json_object_new_object();
875 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
876 json_object_boolean_true_add(json_nexthop
, "fib");
878 switch (nexthop
->type
)
880 case NEXTHOP_TYPE_IPV4
:
881 case NEXTHOP_TYPE_IPV4_IFINDEX
:
882 json_object_string_add(json_nexthop
, "ip", inet_ntoa (nexthop
->gate
.ipv4
));
883 json_object_string_add(json_nexthop
, "afi", "ipv4");
885 if (nexthop
->ifindex
)
887 json_object_int_add(json_nexthop
, "interfaceIndex", nexthop
->ifindex
);
888 json_object_string_add(json_nexthop
, "interfaceName", ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
891 case NEXTHOP_TYPE_IPV6
:
892 case NEXTHOP_TYPE_IPV6_IFINDEX
:
893 json_object_string_add(json_nexthop
, "ip", inet_ntop (AF_INET6
, &nexthop
->gate
.ipv6
, buf
, sizeof buf
));
894 json_object_string_add(json_nexthop
, "afi", "ipv6");
896 if (nexthop
->ifindex
)
898 json_object_int_add(json_nexthop
, "interfaceIndex", nexthop
->ifindex
);
899 json_object_string_add(json_nexthop
, "interfaceName", ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
903 case NEXTHOP_TYPE_IFINDEX
:
904 json_object_boolean_true_add(json_nexthop
, "directlyConnected");
905 json_object_int_add(json_nexthop
, "interfaceIndex", nexthop
->ifindex
);
906 json_object_string_add(json_nexthop
, "interfaceName", ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
908 case NEXTHOP_TYPE_BLACKHOLE
:
909 json_object_boolean_true_add(json_nexthop
, "blackhole");
915 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
916 json_object_boolean_true_add(json_nexthop
, "active");
918 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
919 json_object_boolean_true_add(json_nexthop
, "onLink");
921 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
922 json_object_boolean_true_add(json_nexthop
, "recursive");
924 switch (nexthop
->type
)
926 case NEXTHOP_TYPE_IPV4
:
927 case NEXTHOP_TYPE_IPV4_IFINDEX
:
928 if (nexthop
->src
.ipv4
.s_addr
)
930 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
, sizeof buf
))
931 json_object_string_add(json_nexthop
, "source", buf
);
934 case NEXTHOP_TYPE_IPV6
:
935 case NEXTHOP_TYPE_IPV6_IFINDEX
:
936 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
))
938 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
, sizeof buf
))
939 json_object_string_add(json_nexthop
, "source", buf
);
946 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
)
948 json_labels
= json_object_new_array();
950 for (int label_index
= 0; label_index
< nexthop
->nh_label
->num_labels
; label_index
++)
951 json_object_array_add(json_labels
, json_object_new_int(nexthop
->nh_label
->label
[label_index
]));
953 json_object_object_add(json_nexthop
, "labels", json_labels
);
956 json_object_array_add(json_nexthops
, json_nexthop
);
959 json_object_object_add(json_route
, "nexthops", json_nexthops
);
960 json_object_array_add(json
, json_route
);
964 /* Nexthop information. */
965 for (ALL_NEXTHOPS_RO(re
->nexthop
, nexthop
, tnexthop
, recursing
))
967 if (nexthop
== re
->nexthop
)
969 /* Prefix information. */
970 len
= vty_out (vty
, "%c", zebra_route_char (re
->type
));
972 len
+= vty_out (vty
, "[%d]", re
->instance
);
973 len
+= vty_out (vty
, "%c%c %s",
974 CHECK_FLAG (re
->flags
, ZEBRA_FLAG_SELECTED
)
976 CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)
978 srcdest_rnode2str (rn
, buf
, sizeof buf
));
980 /* Distance and metric display. */
981 if (re
->type
!= ZEBRA_ROUTE_CONNECT
982 && re
->type
!= ZEBRA_ROUTE_KERNEL
)
983 len
+= vty_out (vty
, " [%d/%d]", re
->distance
,
987 vty_out (vty
, " %c%*c",
988 CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
)
990 len
- 3 + (2 * recursing
), ' ');
992 switch (nexthop
->type
)
994 case NEXTHOP_TYPE_IPV4
:
995 case NEXTHOP_TYPE_IPV4_IFINDEX
:
996 vty_out (vty
, " via %s", inet_ntoa (nexthop
->gate
.ipv4
));
997 if (nexthop
->ifindex
)
998 vty_out (vty
, ", %s",
999 ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
1001 case NEXTHOP_TYPE_IPV6
:
1002 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1003 vty_out (vty
, " via %s",
1004 inet_ntop (AF_INET6
, &nexthop
->gate
.ipv6
, buf
, sizeof buf
));
1005 if (nexthop
->ifindex
)
1006 vty_out (vty
, ", %s",
1007 ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
1010 case NEXTHOP_TYPE_IFINDEX
:
1011 vty_out (vty
, " is directly connected, %s",
1012 ifindex2ifname (nexthop
->ifindex
, re
->vrf_id
));
1014 case NEXTHOP_TYPE_BLACKHOLE
:
1015 vty_out (vty
, " is directly connected, Null0");
1020 if (! CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ACTIVE
))
1021 vty_out (vty
, " inactive");
1023 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_ONLINK
))
1024 vty_out (vty
, " onlink");
1026 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_RECURSIVE
))
1027 vty_out (vty
, " (recursive)");
1029 switch (nexthop
->type
)
1031 case NEXTHOP_TYPE_IPV4
:
1032 case NEXTHOP_TYPE_IPV4_IFINDEX
:
1033 if (nexthop
->src
.ipv4
.s_addr
)
1035 if (inet_ntop(AF_INET
, &nexthop
->src
.ipv4
, buf
, sizeof buf
))
1036 vty_out (vty
, ", src %s", buf
);
1039 case NEXTHOP_TYPE_IPV6
:
1040 case NEXTHOP_TYPE_IPV6_IFINDEX
:
1041 if (!IPV6_ADDR_SAME(&nexthop
->src
.ipv6
, &in6addr_any
))
1043 if (inet_ntop(AF_INET6
, &nexthop
->src
.ipv6
, buf
, sizeof buf
))
1044 vty_out (vty
, ", src %s", buf
);
1051 /* Label information */
1052 if (nexthop
->nh_label
&& nexthop
->nh_label
->num_labels
)
1054 vty_out (vty
, ", label %s",
1055 mpls_label2str (nexthop
->nh_label
->num_labels
,
1056 nexthop
->nh_label
->label
, buf
, sizeof buf
, 1));
1059 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_BLACKHOLE
))
1060 vty_out (vty
, ", bh");
1061 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_REJECT
))
1062 vty_out (vty
, ", rej");
1064 if (re
->type
== ZEBRA_ROUTE_RIP
1065 || re
->type
== ZEBRA_ROUTE_OSPF
1066 || re
->type
== ZEBRA_ROUTE_ISIS
1067 || re
->type
== ZEBRA_ROUTE_NHRP
1068 || re
->type
== ZEBRA_ROUTE_TABLE
1069 || re
->type
== ZEBRA_ROUTE_BGP
)
1074 uptime
= time (NULL
);
1075 uptime
-= re
->uptime
;
1076 tm
= gmtime (&uptime
);
1078 if (uptime
< ONE_DAY_SECOND
)
1079 vty_out (vty
, ", %02d:%02d:%02d",
1080 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
1081 else if (uptime
< ONE_WEEK_SECOND
)
1082 vty_out (vty
, ", %dd%02dh%02dm",
1083 tm
->tm_yday
, tm
->tm_hour
, tm
->tm_min
);
1085 vty_out (vty
, ", %02dw%dd%02dh",
1087 tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
1089 vty_out (vty
, "%s", VTY_NEWLINE
);
1094 use_fib (struct cmd_token
*token
)
1096 return strncmp(token
->arg
, "route", strlen(token
->arg
));
1100 do_show_ip_route (struct vty
*vty
, const char *vrf_name
, afi_t afi
, safi_t safi
,
1101 bool use_fib
, u_char use_json
, route_tag_t tag
,
1102 struct prefix
*longer_prefix_p
, bool supernets_only
,
1103 int type
, u_short ospf_instance_id
)
1105 struct route_table
*table
;
1106 struct route_node
*rn
;
1107 struct route_entry
*re
;
1109 struct zebra_vrf
*zvrf
= NULL
;
1111 json_object
*json
= NULL
;
1112 json_object
*json_prefix
= NULL
;
1115 if (!(zvrf
= zebra_vrf_lookup_by_name (vrf_name
)))
1118 vty_out (vty
, "{}%s", VTY_NEWLINE
);
1120 vty_out (vty
, "vrf %s not defined%s", vrf_name
, VTY_NEWLINE
);
1124 if (zvrf_id (zvrf
) == VRF_UNKNOWN
)
1127 vty_out (vty
, "{}%s", VTY_NEWLINE
);
1129 vty_out (vty
, "vrf %s inactive%s", vrf_name
, VTY_NEWLINE
);
1133 table
= zebra_vrf_table (afi
, safi
, zvrf_id (zvrf
));
1137 vty_out (vty
, "{}%s", VTY_NEWLINE
);
1142 json
= json_object_new_object();
1144 /* Show all routes. */
1145 for (rn
= route_top (table
); rn
; rn
= route_next (rn
))
1147 RNODE_FOREACH_RE (rn
, re
)
1149 if (use_fib
&& !CHECK_FLAG(re
->status
, ROUTE_ENTRY_SELECTED_FIB
))
1152 if (tag
&& re
->tag
!= tag
)
1155 if (longer_prefix_p
&& ! prefix_match (longer_prefix_p
, &rn
->p
))
1158 /* This can only be true when the afi is IPv4 */
1161 addr
= ntohl (rn
->p
.u
.prefix4
.s_addr
);
1163 if (IN_CLASSC (addr
) && rn
->p
.prefixlen
>= 24)
1166 if (IN_CLASSB (addr
) && rn
->p
.prefixlen
>= 16)
1169 if (IN_CLASSA (addr
) && rn
->p
.prefixlen
>= 8)
1173 if (type
&& re
->type
!= type
)
1176 if (ospf_instance_id
&& (re
->type
!= ZEBRA_ROUTE_OSPF
|| re
->instance
!= ospf_instance_id
))
1182 json_prefix
= json_object_new_array();
1189 vty_out (vty
, SHOW_ROUTE_V4_HEADER
);
1191 vty_out (vty
, SHOW_ROUTE_V6_HEADER
);
1193 if (zvrf_id (zvrf
) != VRF_DEFAULT
)
1194 vty_out (vty
, "%sVRF %s:%s", VTY_NEWLINE
, zvrf_name (zvrf
), VTY_NEWLINE
);
1200 vty_show_ip_route (vty
, rn
, re
, json_prefix
);
1205 prefix2str (&rn
->p
, buf
, sizeof buf
);
1206 json_object_object_add(json
, buf
, json_prefix
);
1213 vty_out (vty
, "%s%s", json_object_to_json_string_ext(json
, JSON_C_TO_STRING_PRETTY
), VTY_NEWLINE
);
1214 json_object_free(json
);
1222 "show ip nht [vrf NAME]",
1225 "IP nexthop tracking table\n"
1229 vrf_id_t vrf_id
= VRF_DEFAULT
;
1232 VRF_GET_ID (vrf_id
, argv
[idx_vrf
]->arg
);
1234 zebra_print_rnh_table(vrf_id
, AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1239 DEFUN (show_ip_nht_vrf_all
,
1240 show_ip_nht_vrf_all_cmd
,
1241 "show ip nht vrf all",
1244 "IP nexthop tracking table\n"
1245 VRF_ALL_CMD_HELP_STR
)
1248 struct zebra_vrf
*zvrf
;
1250 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1251 if ((zvrf
= vrf
->info
) != NULL
)
1253 vty_out (vty
, "%sVRF %s:%s", VTY_NEWLINE
, zvrf_name (zvrf
), VTY_NEWLINE
);
1254 zebra_print_rnh_table(zvrf_id (zvrf
), AF_INET
, vty
, RNH_NEXTHOP_TYPE
);
1260 DEFUN (show_ipv6_nht
,
1262 "show ipv6 nht [vrf NAME]",
1265 "IPv6 nexthop tracking table\n"
1269 vrf_id_t vrf_id
= VRF_DEFAULT
;
1272 VRF_GET_ID (vrf_id
, argv
[idx_vrf
]->arg
);
1274 zebra_print_rnh_table(vrf_id
, AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1279 DEFUN (show_ipv6_nht_vrf_all
,
1280 show_ipv6_nht_vrf_all_cmd
,
1281 "show ipv6 nht vrf all",
1284 "IPv6 nexthop tracking table\n"
1285 VRF_ALL_CMD_HELP_STR
)
1288 struct zebra_vrf
*zvrf
;
1290 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1291 if ((zvrf
= vrf
->info
) != NULL
)
1293 vty_out (vty
, "%sVRF %s:%s", VTY_NEWLINE
, zvrf_name (zvrf
), VTY_NEWLINE
);
1294 zebra_print_rnh_table(zvrf_id (zvrf
), AF_INET6
, vty
, RNH_NEXTHOP_TYPE
);
1300 DEFUN (ip_nht_default_route
,
1301 ip_nht_default_route_cmd
,
1302 "ip nht resolve-via-default",
1304 "Filter Next Hop tracking route resolution\n"
1305 "Resolve via default route\n")
1307 if (zebra_rnh_ip_default_route
)
1310 zebra_rnh_ip_default_route
= 1;
1311 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1315 DEFUN (no_ip_nht_default_route
,
1316 no_ip_nht_default_route_cmd
,
1317 "no ip nht resolve-via-default",
1320 "Filter Next Hop tracking route resolution\n"
1321 "Resolve via default route\n")
1323 if (!zebra_rnh_ip_default_route
)
1326 zebra_rnh_ip_default_route
= 0;
1327 zebra_evaluate_rnh(0, AF_INET
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1331 DEFUN (ipv6_nht_default_route
,
1332 ipv6_nht_default_route_cmd
,
1333 "ipv6 nht resolve-via-default",
1335 "Filter Next Hop tracking route resolution\n"
1336 "Resolve via default route\n")
1338 if (zebra_rnh_ipv6_default_route
)
1341 zebra_rnh_ipv6_default_route
= 1;
1342 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1346 DEFUN (no_ipv6_nht_default_route
,
1347 no_ipv6_nht_default_route_cmd
,
1348 "no ipv6 nht resolve-via-default",
1351 "Filter Next Hop tracking route resolution\n"
1352 "Resolve via default route\n")
1354 if (!zebra_rnh_ipv6_default_route
)
1357 zebra_rnh_ipv6_default_route
= 0;
1358 zebra_evaluate_rnh(0, AF_INET6
, 1, RNH_NEXTHOP_TYPE
, NULL
);
1362 // dwalton one "show ip route" to rule them all
1363 DEFUN (show_ip_route
,
1365 "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]",
1368 "IP forwarding table\n"
1369 "IP routing table\n"
1371 "Show only routes with tag\n"
1373 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1374 "Show route matching the specified Network/Mask pair only\n"
1375 "Show supernet entries only\n"
1376 FRR_IP_REDIST_HELP_STR_ZEBRA
1377 "Open Shortest Path First (OSPFv2)\n"
1381 bool uf
= use_fib(argv
[2]);
1382 struct route_table
*table
;
1384 route_tag_t tag
= 0;
1385 vrf_id_t vrf_id
= VRF_DEFAULT
;
1387 struct zebra_vrf
*zvrf
;
1388 int uj
= use_json(argc
, argv
);
1391 bool longer_prefixes
= false;
1392 bool supernets_only
= false;
1394 u_short ospf_instance_id
= 0;
1396 if (argv_find (argv
, argc
, "vrf", &idx
))
1398 if (strmatch(argv
[idx
+1]->arg
, "all"))
1401 VRF_GET_ID (vrf_id
, argv
[idx
+1]->arg
);
1404 if (argv_find (argv
, argc
, "tag", &idx
))
1405 VTY_GET_INTEGER_RANGE("tag", tag
, argv
[idx
+1]->arg
, 0, 4294967295);
1407 else if (argv_find (argv
, argc
, "A.B.C.D/M", &idx
))
1409 str2prefix (argv
[idx
]->arg
, &p
);
1410 longer_prefixes
= true;
1413 else if (argv_find (argv
, argc
, "supernets_only", &idx
))
1414 supernets_only
= true;
1418 if (argv_find (argv
, argc
, "kernel", &idx
))
1419 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1420 else if (argv_find (argv
, argc
, "babel", &idx
))
1421 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1422 else if (argv_find (argv
, argc
, "connected", &idx
))
1423 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1424 else if (argv_find (argv
, argc
, "static", &idx
))
1425 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1426 else if (argv_find (argv
, argc
, "rip", &idx
))
1427 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1428 else if (argv_find (argv
, argc
, "ospf", &idx
))
1429 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1430 else if (argv_find (argv
, argc
, "isis", &idx
))
1431 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1432 else if (argv_find (argv
, argc
, "bgp", &idx
))
1433 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1434 else if (argv_find (argv
, argc
, "pim", &idx
))
1435 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1436 else if (argv_find (argv
, argc
, "eigrp", &idx
))
1437 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1438 else if (argv_find (argv
, argc
, "nhrp", &idx
))
1439 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1440 else if (argv_find (argv
, argc
, "table", &idx
))
1441 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1442 else if (argv_find (argv
, argc
, "vnc", &idx
))
1443 type
= proto_redistnum (AFI_IP
, argv
[idx
]->text
);
1445 if (argv_find (argv
, argc
, "(1-65535)", &idx
))
1446 VTY_GET_INTEGER ("Instance", ospf_instance_id
, argv
[idx
]->arg
);
1450 vty_out (vty
, "Unknown route type%s", VTY_NEWLINE
);
1457 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1459 if ((zvrf
= vrf
->info
) == NULL
||
1460 (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1463 do_show_ip_route (vty
, zvrf_name (zvrf
), AFI_IP
, SAFI_UNICAST
, uf
, uj
, tag
,
1464 longer_prefixes
? &p
: NULL
, supernets_only
, type
, ospf_instance_id
);
1469 vrf
= vrf_lookup_by_id (vrf_id
);
1470 do_show_ip_route (vty
, vrf
->name
, AFI_IP
, SAFI_UNICAST
, uf
, uj
, tag
,
1471 longer_prefixes
? &p
: NULL
, supernets_only
, type
, ospf_instance_id
);
1476 DEFUN (show_ip_route_addr
,
1477 show_ip_route_addr_cmd
,
1478 "show ip route [vrf NAME] A.B.C.D",
1481 "IP routing table\n"
1483 "Network in the IP routing table to display\n")
1486 struct prefix_ipv4 p
;
1487 struct route_table
*table
;
1488 struct route_node
*rn
;
1489 vrf_id_t vrf_id
= VRF_DEFAULT
;
1491 if (strmatch(argv
[3]->text
, "vrf"))
1493 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
1494 ret
= str2prefix_ipv4 (argv
[5]->arg
, &p
);
1498 ret
= str2prefix_ipv4 (argv
[3]->arg
, &p
);
1503 vty_out (vty
, "%% Malformed IPv4 address%s", VTY_NEWLINE
);
1507 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, vrf_id
);
1511 rn
= route_node_match (table
, (struct prefix
*) &p
);
1514 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
1518 vty_show_ip_route_detail (vty
, rn
, 0);
1520 route_unlock_node (rn
);
1525 DEFUN (show_ip_route_prefix
,
1526 show_ip_route_prefix_cmd
,
1527 "show ip route [vrf NAME] A.B.C.D/M",
1530 "IP routing table\n"
1532 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1535 struct prefix_ipv4 p
;
1536 struct route_table
*table
;
1537 struct route_node
*rn
;
1538 vrf_id_t vrf_id
= VRF_DEFAULT
;
1540 if (strmatch(argv
[3]->text
, "vrf"))
1542 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
1543 ret
= str2prefix_ipv4 (argv
[5]->arg
, &p
);
1547 ret
= str2prefix_ipv4 (argv
[3]->arg
, &p
);
1552 vty_out (vty
, "%% Malformed IPv4 address%s", VTY_NEWLINE
);
1556 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, vrf_id
);
1560 rn
= route_node_match (table
, (struct prefix
*) &p
);
1561 if (! rn
|| rn
->p
.prefixlen
!= p
.prefixlen
)
1563 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
1567 vty_show_ip_route_detail (vty
, rn
, 0);
1569 route_unlock_node (rn
);
1576 vty_show_ip_route_summary (struct vty
*vty
, struct route_table
*table
)
1578 struct route_node
*rn
;
1579 struct route_entry
*re
;
1580 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1581 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1582 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1583 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1587 memset (&rib_cnt
, 0, sizeof(rib_cnt
));
1588 memset (&fib_cnt
, 0, sizeof(fib_cnt
));
1589 for (rn
= route_top (table
); rn
; rn
= srcdest_route_next (rn
))
1590 RNODE_FOREACH_RE (rn
, re
)
1592 is_ibgp
= (re
->type
== ZEBRA_ROUTE_BGP
&&
1593 CHECK_FLAG (re
->flags
, ZEBRA_FLAG_IBGP
));
1595 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1597 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1599 rib_cnt
[re
->type
]++;
1601 if (CHECK_FLAG (re
->flags
, ZEBRA_FLAG_SELECTED
))
1603 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1606 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1608 fib_cnt
[re
->type
]++;
1612 vty_out (vty
, "%-20s %-20s %s (vrf %s)%s",
1613 "Route Source", "Routes", "FIB",
1614 zvrf_name (((rib_table_info_t
*)table
->info
)->zvrf
),
1617 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1619 if ((rib_cnt
[i
] > 0) ||
1620 (i
== ZEBRA_ROUTE_BGP
&& rib_cnt
[ZEBRA_ROUTE_IBGP
] > 0))
1622 if (i
== ZEBRA_ROUTE_BGP
)
1624 vty_out (vty
, "%-20s %-20d %-20d %s", "ebgp",
1625 rib_cnt
[ZEBRA_ROUTE_BGP
], fib_cnt
[ZEBRA_ROUTE_BGP
],
1627 vty_out (vty
, "%-20s %-20d %-20d %s", "ibgp",
1628 rib_cnt
[ZEBRA_ROUTE_IBGP
], fib_cnt
[ZEBRA_ROUTE_IBGP
],
1632 vty_out (vty
, "%-20s %-20d %-20d %s", zebra_route_string(i
),
1633 rib_cnt
[i
], fib_cnt
[i
], VTY_NEWLINE
);
1637 vty_out (vty
, "------%s", VTY_NEWLINE
);
1638 vty_out (vty
, "%-20s %-20d %-20d %s", "Totals", rib_cnt
[ZEBRA_ROUTE_TOTAL
],
1639 fib_cnt
[ZEBRA_ROUTE_TOTAL
], VTY_NEWLINE
);
1640 vty_out (vty
, "%s", VTY_NEWLINE
);
1644 * Implementation of the ip route summary prefix command.
1646 * This command prints the primary prefixes that have been installed by various
1647 * protocols on the box.
1651 vty_show_ip_route_summary_prefix (struct vty
*vty
, struct route_table
*table
)
1653 struct route_node
*rn
;
1654 struct route_entry
*re
;
1655 struct nexthop
*nexthop
;
1656 #define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
1657 #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
1658 u_int32_t rib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1659 u_int32_t fib_cnt
[ZEBRA_ROUTE_TOTAL
+ 1];
1663 memset (&rib_cnt
, 0, sizeof(rib_cnt
));
1664 memset (&fib_cnt
, 0, sizeof(fib_cnt
));
1665 for (rn
= route_top (table
); rn
; rn
= srcdest_route_next (rn
))
1666 RNODE_FOREACH_RE (rn
, re
)
1670 * In case of ECMP, count only once.
1673 for (nexthop
= re
->nexthop
; (!cnt
&& nexthop
); nexthop
= nexthop
->next
)
1676 rib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1677 rib_cnt
[re
->type
]++;
1678 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1680 fib_cnt
[ZEBRA_ROUTE_TOTAL
]++;
1681 fib_cnt
[re
->type
]++;
1683 if (re
->type
== ZEBRA_ROUTE_BGP
&&
1684 CHECK_FLAG (re
->flags
, ZEBRA_FLAG_IBGP
))
1686 rib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1687 if (CHECK_FLAG (nexthop
->flags
, NEXTHOP_FLAG_FIB
))
1688 fib_cnt
[ZEBRA_ROUTE_IBGP
]++;
1693 vty_out (vty
, "%-20s %-20s %s (vrf %s)%s",
1694 "Route Source", "Prefix Routes", "FIB",
1695 zvrf_name (((rib_table_info_t
*)table
->info
)->zvrf
),
1698 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
1702 if (i
== ZEBRA_ROUTE_BGP
)
1704 vty_out (vty
, "%-20s %-20d %-20d %s", "ebgp",
1705 rib_cnt
[ZEBRA_ROUTE_BGP
] - rib_cnt
[ZEBRA_ROUTE_IBGP
],
1706 fib_cnt
[ZEBRA_ROUTE_BGP
] - fib_cnt
[ZEBRA_ROUTE_IBGP
],
1708 vty_out (vty
, "%-20s %-20d %-20d %s", "ibgp",
1709 rib_cnt
[ZEBRA_ROUTE_IBGP
], fib_cnt
[ZEBRA_ROUTE_IBGP
],
1713 vty_out (vty
, "%-20s %-20d %-20d %s", zebra_route_string(i
),
1714 rib_cnt
[i
], fib_cnt
[i
], VTY_NEWLINE
);
1718 vty_out (vty
, "------%s", VTY_NEWLINE
);
1719 vty_out (vty
, "%-20s %-20d %-20d %s", "Totals", rib_cnt
[ZEBRA_ROUTE_TOTAL
],
1720 fib_cnt
[ZEBRA_ROUTE_TOTAL
], VTY_NEWLINE
);
1721 vty_out (vty
, "%s", VTY_NEWLINE
);
1724 /* Show route summary. */
1725 DEFUN (show_ip_route_summary
,
1726 show_ip_route_summary_cmd
,
1727 "show ip route [vrf NAME] summary",
1730 "IP routing table\n"
1732 "Summary of all routes\n")
1734 struct route_table
*table
;
1735 vrf_id_t vrf_id
= VRF_DEFAULT
;
1737 if (strmatch(argv
[3]->text
, "vrf"))
1738 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
1740 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, vrf_id
);
1744 vty_show_ip_route_summary (vty
, table
);
1749 /* Show route summary prefix. */
1750 DEFUN (show_ip_route_summary_prefix
,
1751 show_ip_route_summary_prefix_cmd
,
1752 "show ip route [vrf NAME] summary prefix",
1755 "IP routing table\n"
1757 "Summary of all routes\n"
1760 struct route_table
*table
;
1761 vrf_id_t vrf_id
= VRF_DEFAULT
;
1763 if (strmatch(argv
[3]->text
, "vrf"))
1764 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
1766 table
= zebra_vrf_table (AFI_IP
, SAFI_UNICAST
, vrf_id
);
1770 vty_show_ip_route_summary_prefix (vty
, table
);
1776 DEFUN (show_ip_route_vrf_all_addr
,
1777 show_ip_route_vrf_all_addr_cmd
,
1778 "show ip route vrf all A.B.C.D",
1781 "IP routing table\n"
1782 VRF_ALL_CMD_HELP_STR
1783 "Network in the IP routing table to display\n")
1787 struct prefix_ipv4 p
;
1788 struct route_table
*table
;
1789 struct route_node
*rn
;
1791 struct zebra_vrf
*zvrf
;
1793 ret
= str2prefix_ipv4 (argv
[idx_ipv4
]->arg
, &p
);
1796 vty_out (vty
, "%% Malformed IPv4 address%s", VTY_NEWLINE
);
1800 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1802 if ((zvrf
= vrf
->info
) == NULL
||
1803 (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1806 rn
= route_node_match (table
, (struct prefix
*) &p
);
1810 vty_show_ip_route_detail (vty
, rn
, 0);
1812 route_unlock_node (rn
);
1818 DEFUN (show_ip_route_vrf_all_prefix
,
1819 show_ip_route_vrf_all_prefix_cmd
,
1820 "show ip route vrf all A.B.C.D/M",
1823 "IP routing table\n"
1824 VRF_ALL_CMD_HELP_STR
1825 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
1827 int idx_ipv4_prefixlen
= 5;
1829 struct prefix_ipv4 p
;
1830 struct route_table
*table
;
1831 struct route_node
*rn
;
1833 struct zebra_vrf
*zvrf
;
1835 ret
= str2prefix_ipv4 (argv
[idx_ipv4_prefixlen
]->arg
, &p
);
1838 vty_out (vty
, "%% Malformed IPv4 address%s", VTY_NEWLINE
);
1842 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1844 if ((zvrf
= vrf
->info
) == NULL
||
1845 (table
= zvrf
->table
[AFI_IP
][SAFI_UNICAST
]) == NULL
)
1848 rn
= route_node_match (table
, (struct prefix
*) &p
);
1851 if (rn
->p
.prefixlen
!= p
.prefixlen
)
1853 route_unlock_node (rn
);
1857 vty_show_ip_route_detail (vty
, rn
, 0);
1859 route_unlock_node (rn
);
1865 DEFUN (show_ip_route_vrf_all_summary
,
1866 show_ip_route_vrf_all_summary_cmd
,
1867 "show ip route vrf all summary ",
1870 "IP routing table\n"
1871 VRF_ALL_CMD_HELP_STR
1872 "Summary of all routes\n")
1875 struct zebra_vrf
*zvrf
;
1877 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1878 if ((zvrf
= vrf
->info
) != NULL
)
1879 vty_show_ip_route_summary (vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1884 DEFUN (show_ip_route_vrf_all_summary_prefix
,
1885 show_ip_route_vrf_all_summary_prefix_cmd
,
1886 "show ip route vrf all summary prefix",
1889 "IP routing table\n"
1890 VRF_ALL_CMD_HELP_STR
1891 "Summary of all routes\n"
1895 struct zebra_vrf
*zvrf
;
1897 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1898 if ((zvrf
= vrf
->info
) != NULL
)
1899 vty_show_ip_route_summary_prefix (vty
, zvrf
->table
[AFI_IP
][SAFI_UNICAST
]);
1904 /* Write static route configuration. */
1906 static_config (struct vty
*vty
, afi_t afi
, safi_t safi
, const char *cmd
)
1908 struct route_node
*rn
;
1909 struct static_route
*si
;
1910 struct route_table
*stable
;
1912 struct zebra_vrf
*zvrf
;
1913 char buf
[SRCDEST2STR_BUFFER
];
1916 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
1918 if (!(zvrf
= vrf
->info
))
1920 if ((stable
= zvrf
->stable
[afi
][safi
]) == NULL
)
1923 for (rn
= route_top (stable
); rn
; rn
= srcdest_route_next (rn
))
1924 for (si
= rn
->info
; si
; si
= si
->next
)
1926 vty_out (vty
, "%s %s", cmd
, srcdest_rnode2str (rn
, buf
, sizeof buf
));
1930 case STATIC_IPV4_GATEWAY
:
1931 vty_out (vty
, " %s", inet_ntoa (si
->addr
.ipv4
));
1933 case STATIC_IPV6_GATEWAY
:
1934 vty_out (vty
, " %s", inet_ntop (AF_INET6
, &si
->addr
.ipv6
, buf
, sizeof buf
));
1936 case STATIC_IFINDEX
:
1937 vty_out (vty
, " %s", si
->ifname
);
1939 case STATIC_BLACKHOLE
:
1940 vty_out (vty
, " Null0");
1942 case STATIC_IPV6_GATEWAY_IFINDEX
:
1943 vty_out (vty
, " %s %s",
1944 inet_ntop (AF_INET6
, &si
->addr
.ipv6
, buf
, sizeof buf
),
1945 ifindex2ifname (si
->ifindex
, si
->vrf_id
));
1949 /* flags are incompatible with STATIC_BLACKHOLE */
1950 if (si
->type
!= STATIC_BLACKHOLE
)
1952 if (CHECK_FLAG(si
->flags
, ZEBRA_FLAG_REJECT
))
1953 vty_out (vty
, " %s", "reject");
1955 if (CHECK_FLAG(si
->flags
, ZEBRA_FLAG_BLACKHOLE
))
1956 vty_out (vty
, " %s", "blackhole");
1960 vty_out (vty
, " tag %"ROUTE_TAG_PRI
, si
->tag
);
1962 if (si
->distance
!= ZEBRA_STATIC_DISTANCE_DEFAULT
)
1963 vty_out (vty
, " %d", si
->distance
);
1965 if (si
->vrf_id
!= VRF_DEFAULT
)
1966 vty_out (vty
, " vrf %s", zvrf_name (zvrf
));
1968 /* Label information */
1969 if (si
->snh_label
.num_labels
)
1970 vty_out (vty
, " label %s",
1971 mpls_label2str (si
->snh_label
.num_labels
,
1972 si
->snh_label
.label
, buf
, sizeof buf
, 0));
1974 vty_out (vty
, "%s", VTY_NEWLINE
);
1982 /* General fucntion for IPv6 static route. */
1984 static_ipv6_func (struct vty
*vty
, int add_cmd
, const char *dest_str
,
1985 const char *src_str
,
1986 const char *gate_str
, const char *ifname
,
1987 const char *flag_str
, const char *tag_str
,
1988 const char *distance_str
, const char *vrf_id_str
,
1989 const char *label_str
)
1993 struct prefix p
, src
;
1994 struct prefix_ipv6
*src_p
= NULL
;
1995 struct in6_addr
*gate
= NULL
;
1996 struct in6_addr gate_addr
;
1997 u_char type
= STATIC_BLACKHOLE
;
1999 route_tag_t tag
= 0;
2000 unsigned int ifindex
= 0;
2001 struct interface
*ifp
= NULL
;
2002 struct zebra_vrf
*zvrf
;
2003 struct static_nh_label snh_label
;
2005 ret
= str2prefix (dest_str
, &p
);
2008 vty_out (vty
, "%% Malformed address%s", VTY_NEWLINE
);
2014 ret
= str2prefix (src_str
, &src
);
2015 if (ret
<= 0 || src
.family
!= AF_INET6
)
2017 vty_out (vty
, "%% Malformed source address%s", VTY_NEWLINE
);
2020 src_p
= (struct prefix_ipv6
*)&src
;
2023 /* Apply mask for given prefix. */
2026 /* Administrative distance. */
2028 distance
= atoi (distance_str
);
2030 distance
= ZEBRA_STATIC_DISTANCE_DEFAULT
;
2034 VTY_GET_INTEGER_RANGE("tag", tag
, tag_str
, 0, 4294967295);
2036 /* When gateway is valid IPv6 addrees, then gate is treated as
2037 nexthop address other case gate is treated as interface name. */
2038 ret
= inet_pton (AF_INET6
, gate_str
, &gate_addr
);
2041 zvrf
= zebra_vrf_lookup_by_name (vrf_id_str
);
2045 vty_out (vty
, "%% vrf %s is not defined%s", vrf_id_str
, VTY_NEWLINE
);
2050 memset (&snh_label
, 0, sizeof (struct static_nh_label
));
2055 vty_out (vty
, "%% MPLS not turned on in kernel, ignoring command%s",
2059 int rc
= mpls_str2label (label_str
, &snh_label
.num_labels
,
2065 vty_out (vty
, "%% Malformed label(s)%s", VTY_NEWLINE
);
2068 vty_out (vty
, "%% Cannot use reserved label(s) (%d-%d)%s",
2069 MPLS_MIN_RESERVED_LABEL
, MPLS_MAX_RESERVED_LABEL
,
2073 vty_out (vty
, "%% Too many labels. Enter %d or fewer%s",
2074 MPLS_MAX_LABELS
, VTY_NEWLINE
);
2081 /* Null0 static route. */
2082 if ((gate_str
!= NULL
) && (strncasecmp (gate_str
, "Null0", strlen (gate_str
)) == 0))
2086 vty_out (vty
, "%% can not have flag %s with Null0%s", flag_str
, VTY_NEWLINE
);
2090 static_add_route (AFI_IP6
, SAFI_UNICAST
, type
, &p
, NULL
, NULL
, ifindex
, ifname
,
2091 ZEBRA_FLAG_BLACKHOLE
, tag
, distance
, zvrf
, &snh_label
);
2093 static_delete_route (AFI_IP6
, SAFI_UNICAST
, type
, &p
, NULL
, NULL
, ifindex
, tag
,
2094 distance
, zvrf
, &snh_label
);
2100 switch(flag_str
[0]) {
2103 SET_FLAG (flag
, ZEBRA_FLAG_REJECT
);
2107 SET_FLAG (flag
, ZEBRA_FLAG_BLACKHOLE
);
2110 vty_out (vty
, "%% Malformed flag %s %s", flag_str
, VTY_NEWLINE
);
2117 /* When ifname is specified. It must be come with gateway
2121 vty_out (vty
, "%% Malformed address%s", VTY_NEWLINE
);
2124 type
= STATIC_IPV6_GATEWAY_IFINDEX
;
2126 ifp
= if_lookup_by_name (ifname
, zvrf_id (zvrf
));
2129 vty_out (vty
, "%% Malformed Interface name %s%s", ifname
, VTY_NEWLINE
);
2132 ifindex
= ifp
->ifindex
;
2138 type
= STATIC_IPV6_GATEWAY
;
2143 type
= STATIC_IFINDEX
;
2144 ifp
= if_lookup_by_name (gate_str
, zvrf_id (zvrf
));
2147 vty_out (vty
, "%% Malformed Interface name %s%s", gate_str
, VTY_NEWLINE
);
2148 ifindex
= IFINDEX_DELETED
;
2151 ifindex
= ifp
->ifindex
;
2157 static_add_route (AFI_IP6
, SAFI_UNICAST
, type
, &p
, src_p
, (union g_addr
*)gate
,
2158 ifindex
, ifname
, flag
, tag
, distance
, zvrf
, &snh_label
);
2160 static_delete_route (AFI_IP6
, SAFI_UNICAST
, type
, &p
, src_p
, (union g_addr
*)gate
,
2161 ifindex
, tag
, distance
, zvrf
, &snh_label
);
2168 "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]",
2170 "Establish static routes\n"
2171 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2172 "IPv6 source-dest route\n"
2173 "IPv6 source prefix\n"
2174 "IPv6 gateway address\n"
2175 "IPv6 gateway interface name\n"
2177 "Set tag for this route\n"
2179 "Distance value for this prefix\n"
2183 int idx_ipv6_prefixlen
= 2;
2184 int idx_ipv6_ifname
;
2186 char *src
, *tag
, *distance
, *vrf
;
2188 if (!strcmp(argv
[3]->text
, "from"))
2191 idx_ipv6_ifname
= 5;
2197 idx_ipv6_ifname
= 3;
2201 tag
= distance
= vrf
= NULL
;
2202 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2204 return static_ipv6_func (vty
, 1,
2205 argv
[idx_ipv6_prefixlen
]->arg
,
2207 argv
[idx_ipv6_ifname
]->arg
,
2209 tag
, distance
, vrf
, NULL
);
2212 DEFUN (ipv6_route_flags
,
2213 ipv6_route_flags_cmd
,
2214 "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]",
2216 "Establish static routes\n"
2217 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2218 "IPv6 source-dest route\n"
2219 "IPv6 source prefix\n"
2220 "IPv6 gateway address\n"
2221 "IPv6 gateway interface name\n"
2222 "Emit an ICMP unreachable when matched\n"
2223 "Silently discard pkts when matched\n"
2224 "Silently discard pkts when matched\n"
2225 "Set tag for this route\n"
2227 "Distance value for this prefix\n"
2231 int idx_ipv6_prefixlen
= 2;
2232 int idx_ipv6_ifname
;
2233 int idx_reject_blackhole
;
2235 char *src
, *tag
, *distance
, *vrf
;
2237 if (!strcmp(argv
[3]->text
, "from"))
2240 idx_ipv6_ifname
= 5;
2241 idx_reject_blackhole
= 6;
2247 idx_ipv6_ifname
= 3;
2248 idx_reject_blackhole
= 4;
2252 tag
= distance
= vrf
= NULL
;
2253 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2255 return static_ipv6_func (vty
, 1,
2256 argv
[idx_ipv6_prefixlen
]->arg
,
2258 argv
[idx_ipv6_ifname
]->arg
,
2260 argv
[idx_reject_blackhole
]->arg
,
2261 tag
, distance
, vrf
, NULL
);
2264 DEFUN (ipv6_route_ifname
,
2265 ipv6_route_ifname_cmd
,
2266 "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]",
2268 "Establish static routes\n"
2269 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2270 "IPv6 source-dest route\n"
2271 "IPv6 source prefix\n"
2272 "IPv6 gateway address\n"
2273 "IPv6 gateway interface name\n"
2274 "Set tag for this route\n"
2276 "Distance value for this prefix\n"
2280 int idx_ipv6_prefixlen
= 2;
2282 int idx_interface
= 4;
2284 char *src
, *tag
, *distance
, *vrf
;
2286 if (!strcmp(argv
[3]->text
, "from"))
2301 tag
= distance
= vrf
= NULL
;
2302 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2304 return static_ipv6_func (vty
, 1,
2305 argv
[idx_ipv6_prefixlen
]->arg
,
2307 argv
[idx_ipv6
]->arg
,
2308 argv
[idx_interface
]->arg
,
2310 tag
, distance
, vrf
, NULL
);
2313 DEFUN (ipv6_route_ifname_flags
,
2314 ipv6_route_ifname_flags_cmd
,
2315 "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]",
2317 "Establish static routes\n"
2318 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2319 "IPv6 source-dest route\n"
2320 "IPv6 source prefix\n"
2321 "IPv6 gateway address\n"
2322 "IPv6 gateway interface name\n"
2323 "Emit an ICMP unreachable when matched\n"
2324 "Silently discard pkts when matched\n"
2325 "Set tag for this route\n"
2327 "Distance value for this prefix\n"
2331 int idx_ipv6_prefixlen
= 2;
2334 int idx_reject_blackhole
;
2336 char *src
, *tag
, *distance
, *vrf
;
2338 if (!strcmp(argv
[3]->text
, "from"))
2343 idx_reject_blackhole
= 7;
2351 idx_reject_blackhole
= 5;
2355 tag
= distance
= vrf
= NULL
;
2356 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2358 return static_ipv6_func (vty
, 1,
2359 argv
[idx_ipv6_prefixlen
]->arg
,
2361 argv
[idx_ipv6
]->arg
,
2362 argv
[idx_interface
]->arg
,
2363 argv
[idx_reject_blackhole
]->arg
,
2364 tag
, distance
, vrf
, NULL
);
2367 DEFUN (no_ipv6_route
,
2369 "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]",
2372 "Establish static routes\n"
2373 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2374 "IPv6 source-dest route\n"
2375 "IPv6 source prefix\n"
2376 "IPv6 gateway address\n"
2377 "IPv6 gateway interface name\n"
2379 "Set tag for this route\n"
2381 "Distance value for this prefix\n"
2385 int idx_ipv6_prefixlen
= 3;
2386 int idx_ipv6_ifname
;
2388 char *src
, *tag
, *distance
, *vrf
;
2390 if (!strcmp(argv
[4]->text
, "from"))
2393 idx_ipv6_ifname
= 6;
2399 idx_ipv6_ifname
= 4;
2403 tag
= distance
= vrf
= NULL
;
2404 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2406 return static_ipv6_func (vty
, 0,
2407 argv
[idx_ipv6_prefixlen
]->arg
,
2409 argv
[idx_ipv6_ifname
]->arg
,
2411 tag
, distance
, vrf
, NULL
);
2414 DEFUN (no_ipv6_route_flags
,
2415 no_ipv6_route_flags_cmd
,
2416 "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]",
2419 "Establish static routes\n"
2420 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2421 "IPv6 source-dest route\n"
2422 "IPv6 source prefix\n"
2423 "IPv6 gateway address\n"
2424 "IPv6 gateway interface name\n"
2425 "Emit an ICMP unreachable when matched\n"
2426 "Silently discard pkts when matched\n"
2427 "Set tag for this route\n"
2429 "Distance value for this prefix\n"
2433 int idx_ipv6_prefixlen
= 3;
2434 int idx_ipv6_ifname
;
2435 int idx_reject_blackhole
;
2437 char *src
, *tag
, *distance
, *vrf
;
2439 if (!strcmp(argv
[4]->text
, "from"))
2442 idx_ipv6_ifname
= 6;
2443 idx_reject_blackhole
= 7;
2449 idx_ipv6_ifname
= 4;
2450 idx_reject_blackhole
= 5;
2454 tag
= distance
= vrf
= NULL
;
2455 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2457 return static_ipv6_func (vty
, 0,
2458 argv
[idx_ipv6_prefixlen
]->arg
,
2460 argv
[idx_ipv6_ifname
]->arg
,
2462 argv
[idx_reject_blackhole
]->arg
,
2463 tag
, distance
, vrf
, NULL
);
2466 DEFUN (no_ipv6_route_ifname
,
2467 no_ipv6_route_ifname_cmd
,
2468 "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]",
2471 "Establish static routes\n"
2472 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2473 "IPv6 source-dest route\n"
2474 "IPv6 source prefix\n"
2475 "IPv6 gateway address\n"
2476 "IPv6 gateway interface name\n"
2477 "Set tag for this route\n"
2479 "Distance value for this prefix\n"
2483 int idx_ipv6_prefixlen
= 3;
2487 char *src
, *tag
, *distance
, *vrf
;
2489 if (!strcmp(argv
[4]->text
, "from"))
2504 tag
= distance
= vrf
= NULL
;
2505 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2507 return static_ipv6_func (vty
, 0,
2508 argv
[idx_ipv6_prefixlen
]->arg
,
2510 argv
[idx_ipv6
]->arg
,
2511 argv
[idx_interface
]->arg
,
2513 tag
, distance
, vrf
, NULL
);
2516 DEFUN (no_ipv6_route_ifname_flags
,
2517 no_ipv6_route_ifname_flags_cmd
,
2518 "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]",
2521 "Establish static routes\n"
2522 "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
2523 "IPv6 source-dest route\n"
2524 "IPv6 source prefix\n"
2525 "IPv6 gateway address\n"
2526 "IPv6 gateway interface name\n"
2527 "Emit an ICMP unreachable when matched\n"
2528 "Silently discard pkts when matched\n"
2529 "Set tag for this route\n"
2531 "Distance value for this prefix\n"
2535 int idx_ipv6_prefixlen
= 3;
2538 int idx_reject_blackhole
;
2540 char *src
, *tag
, *distance
, *vrf
;
2542 if (!strcmp(argv
[4]->text
, "from"))
2547 idx_reject_blackhole
= 8;
2555 idx_reject_blackhole
= 6;
2559 tag
= distance
= vrf
= NULL
;
2560 zebra_vty_ip_route_tdv_helper (argc
, argv
, idx_curr
, &tag
, &distance
, &vrf
, NULL
);
2562 return static_ipv6_func (vty
, 0,
2563 argv
[idx_ipv6_prefixlen
]->arg
,
2565 argv
[idx_ipv6
]->arg
,
2566 argv
[idx_interface
]->arg
,
2567 argv
[idx_reject_blackhole
]->arg
,
2568 tag
, distance
, vrf
, NULL
);
2571 // dwalton duplicate to here
2572 DEFUN (show_ipv6_route
,
2573 show_ipv6_route_cmd
,
2574 "show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA
"] [json]",
2577 "IP forwarding table\n"
2578 "IP routing table\n"
2580 "Show only routes with tag\n"
2583 "Show route matching the specified Network/Mask pair only\n"
2584 FRR_IP6_REDIST_HELP_STR_ZEBRA
2587 bool uf
= use_fib(argv
[2]);
2588 struct route_table
*table
;
2590 route_tag_t tag
= 0;
2591 vrf_id_t vrf_id
= VRF_DEFAULT
;
2593 struct zebra_vrf
*zvrf
;
2594 int uj
= use_json(argc
, argv
);
2597 bool longer_prefixes
= false;
2598 bool supernets_only
= false;
2601 if (argv_find (argv
, argc
, "vrf", &idx
))
2603 if (strmatch(argv
[idx
+1]->arg
, "all"))
2606 VRF_GET_ID (vrf_id
, argv
[idx
+1]->arg
);
2609 if (argv_find (argv
, argc
, "tag", &idx
))
2610 VTY_GET_INTEGER_RANGE("tag", tag
, argv
[idx
+1]->arg
, 0, 4294967295);
2612 else if (argv_find (argv
, argc
, "X:X::X:X/M", &idx
))
2614 str2prefix (argv
[idx
]->arg
, &p
);
2615 longer_prefixes
= true;
2620 if (argv_find (argv
, argc
, "kernel", &idx
))
2621 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2622 else if (argv_find (argv
, argc
, "babel", &idx
))
2623 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2624 else if (argv_find (argv
, argc
, "connected", &idx
))
2625 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2626 else if (argv_find (argv
, argc
, "static", &idx
))
2627 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2628 else if (argv_find (argv
, argc
, "ripng", &idx
))
2629 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2630 else if (argv_find (argv
, argc
, "ospf6", &idx
))
2631 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2632 else if (argv_find (argv
, argc
, "isis", &idx
))
2633 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2634 else if (argv_find (argv
, argc
, "bgp", &idx
))
2635 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2636 else if (argv_find (argv
, argc
, "nhrp", &idx
))
2637 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2638 else if (argv_find (argv
, argc
, "table", &idx
))
2639 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2640 else if (argv_find (argv
, argc
, "vnc", &idx
))
2641 type
= proto_redistnum (AFI_IP6
, argv
[idx
]->text
);
2645 vty_out (vty
, "Unknown route type%s", VTY_NEWLINE
);
2652 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2654 if ((zvrf
= vrf
->info
) == NULL
||
2655 (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2658 do_show_ip_route (vty
, zvrf_name (zvrf
), AFI_IP6
, SAFI_UNICAST
, uf
, uj
, tag
,
2659 longer_prefixes
? &p
: NULL
, supernets_only
, type
, 0);
2664 vrf
= vrf_lookup_by_id (vrf_id
);
2665 do_show_ip_route (vty
, vrf
->name
, AFI_IP6
, SAFI_UNICAST
, uf
, uj
, tag
,
2666 longer_prefixes
? &p
: NULL
, supernets_only
, type
, 0);
2671 DEFUN (show_ipv6_route_addr
,
2672 show_ipv6_route_addr_cmd
,
2673 "show ipv6 route [vrf NAME] X:X::X:X",
2676 "IPv6 routing table\n"
2681 struct prefix_ipv6 p
;
2682 struct route_table
*table
;
2683 struct route_node
*rn
;
2684 vrf_id_t vrf_id
= VRF_DEFAULT
;
2686 if (strmatch(argv
[3]->text
, "vrf"))
2688 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
2689 ret
= str2prefix_ipv6 (argv
[5]->arg
, &p
);
2693 ret
= str2prefix_ipv6 (argv
[3]->arg
, &p
);
2698 vty_out (vty
, "Malformed IPv6 address%s", VTY_NEWLINE
);
2702 table
= zebra_vrf_table (AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2706 rn
= route_node_match (table
, (struct prefix
*) &p
);
2709 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
2713 vty_show_ip_route_detail (vty
, rn
, 0);
2715 route_unlock_node (rn
);
2720 DEFUN (show_ipv6_route_prefix
,
2721 show_ipv6_route_prefix_cmd
,
2722 "show ipv6 route [vrf NAME] X:X::X:X/M",
2725 "IPv6 routing table\n"
2730 struct prefix_ipv6 p
;
2731 struct route_table
*table
;
2732 struct route_node
*rn
;
2733 vrf_id_t vrf_id
= VRF_DEFAULT
;
2735 if (strmatch(argv
[3]->text
, "vrf"))
2737 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
2738 ret
= str2prefix_ipv6 (argv
[5]->arg
, &p
);
2741 ret
= str2prefix_ipv6 (argv
[3]->arg
, &p
);
2745 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
2749 table
= zebra_vrf_table (AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2753 rn
= route_node_match (table
, (struct prefix
*) &p
);
2754 if (! rn
|| rn
->p
.prefixlen
!= p
.prefixlen
)
2756 vty_out (vty
, "%% Network not in table%s", VTY_NEWLINE
);
2760 vty_show_ip_route_detail (vty
, rn
, 0);
2762 route_unlock_node (rn
);
2768 /* Show route summary. */
2769 DEFUN (show_ipv6_route_summary
,
2770 show_ipv6_route_summary_cmd
,
2771 "show ipv6 route [vrf NAME] summary",
2774 "IPv6 routing table\n"
2776 "Summary of all IPv6 routes\n")
2778 struct route_table
*table
;
2779 vrf_id_t vrf_id
= VRF_DEFAULT
;
2781 if (strmatch(argv
[3]->text
, "vrf"))
2782 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
2784 table
= zebra_vrf_table (AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2788 vty_show_ip_route_summary (vty
, table
);
2794 /* Show ipv6 route summary prefix. */
2795 DEFUN (show_ipv6_route_summary_prefix
,
2796 show_ipv6_route_summary_prefix_cmd
,
2797 "show ipv6 route [vrf NAME] summary prefix",
2800 "IPv6 routing table\n"
2802 "Summary of all IPv6 routes\n"
2805 struct route_table
*table
;
2806 vrf_id_t vrf_id
= VRF_DEFAULT
;
2808 if (strmatch(argv
[3]->text
, "vrf"))
2809 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
2811 table
= zebra_vrf_table (AFI_IP6
, SAFI_UNICAST
, vrf_id
);
2815 vty_show_ip_route_summary_prefix (vty
, table
);
2822 * Show IPv6 mroute command.Used to dump
2823 * the Multicast routing table.
2825 DEFUN (show_ipv6_mroute
,
2826 show_ipv6_mroute_cmd
,
2827 "show ipv6 mroute [vrf NAME]",
2830 "IPv6 Multicast routing table\n"
2833 struct route_table
*table
;
2834 struct route_node
*rn
;
2835 struct route_entry
*re
;
2837 vrf_id_t vrf_id
= VRF_DEFAULT
;
2840 VRF_GET_ID (vrf_id
, argv
[4]->arg
);
2842 table
= zebra_vrf_table (AFI_IP6
, SAFI_MULTICAST
, vrf_id
);
2846 /* Show all IPv6 route. */
2847 for (rn
= route_top (table
); rn
; rn
= srcdest_route_next (rn
))
2848 RNODE_FOREACH_RE (rn
, re
)
2852 vty_out (vty
, SHOW_ROUTE_V6_HEADER
);
2855 vty_show_ip_route (vty
, rn
, re
, NULL
);
2860 DEFUN (show_ipv6_route_vrf_all_addr
,
2861 show_ipv6_route_vrf_all_addr_cmd
,
2862 "show ipv6 route vrf all X:X::X:X",
2865 "IPv6 routing table\n"
2866 VRF_ALL_CMD_HELP_STR
2871 struct prefix_ipv6 p
;
2872 struct route_table
*table
;
2873 struct route_node
*rn
;
2875 struct zebra_vrf
*zvrf
;
2877 ret
= str2prefix_ipv6 (argv
[idx_ipv6
]->arg
, &p
);
2880 vty_out (vty
, "Malformed IPv6 address%s", VTY_NEWLINE
);
2884 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2886 if ((zvrf
= vrf
->info
) == NULL
||
2887 (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2890 rn
= route_node_match (table
, (struct prefix
*) &p
);
2894 vty_show_ip_route_detail (vty
, rn
, 0);
2896 route_unlock_node (rn
);
2902 DEFUN (show_ipv6_route_vrf_all_prefix
,
2903 show_ipv6_route_vrf_all_prefix_cmd
,
2904 "show ipv6 route vrf all X:X::X:X/M",
2907 "IPv6 routing table\n"
2908 VRF_ALL_CMD_HELP_STR
2911 int idx_ipv6_prefixlen
= 5;
2913 struct prefix_ipv6 p
;
2914 struct route_table
*table
;
2915 struct route_node
*rn
;
2917 struct zebra_vrf
*zvrf
;
2919 ret
= str2prefix_ipv6 (argv
[idx_ipv6_prefixlen
]->arg
, &p
);
2922 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
2926 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2928 if ((zvrf
= vrf
->info
) == NULL
||
2929 (table
= zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]) == NULL
)
2932 rn
= route_node_match (table
, (struct prefix
*) &p
);
2935 if (rn
->p
.prefixlen
!= p
.prefixlen
)
2937 route_unlock_node (rn
);
2941 vty_show_ip_route_detail (vty
, rn
, 0);
2943 route_unlock_node (rn
);
2949 DEFUN (show_ipv6_route_vrf_all_summary
,
2950 show_ipv6_route_vrf_all_summary_cmd
,
2951 "show ipv6 route vrf all summary",
2954 "IPv6 routing table\n"
2955 VRF_ALL_CMD_HELP_STR
2956 "Summary of all IPv6 routes\n")
2959 struct zebra_vrf
*zvrf
;
2961 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2962 if ((zvrf
= vrf
->info
) != NULL
)
2963 vty_show_ip_route_summary (vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
2968 DEFUN (show_ipv6_mroute_vrf_all
,
2969 show_ipv6_mroute_vrf_all_cmd
,
2970 "show ipv6 mroute vrf all",
2973 "IPv6 Multicast routing table\n"
2974 VRF_ALL_CMD_HELP_STR
)
2976 struct route_table
*table
;
2977 struct route_node
*rn
;
2978 struct route_entry
*re
;
2980 struct zebra_vrf
*zvrf
;
2983 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
2985 if ((zvrf
= vrf
->info
) == NULL
||
2986 (table
= zvrf
->table
[AFI_IP6
][SAFI_MULTICAST
]) == NULL
)
2989 /* Show all IPv6 route. */
2990 for (rn
= route_top (table
); rn
; rn
= srcdest_route_next (rn
))
2991 RNODE_FOREACH_RE (rn
, re
)
2995 vty_out (vty
, SHOW_ROUTE_V6_HEADER
);
2998 vty_show_ip_route (vty
, rn
, re
, NULL
);
3004 DEFUN (show_ipv6_route_vrf_all_summary_prefix
,
3005 show_ipv6_route_vrf_all_summary_prefix_cmd
,
3006 "show ipv6 route vrf all summary prefix",
3009 "IPv6 routing table\n"
3010 VRF_ALL_CMD_HELP_STR
3011 "Summary of all IPv6 routes\n"
3015 struct zebra_vrf
*zvrf
;
3017 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
3018 if ((zvrf
= vrf
->info
) != NULL
)
3019 vty_show_ip_route_summary_prefix (vty
, zvrf
->table
[AFI_IP6
][SAFI_UNICAST
]);
3024 DEFUN (allow_external_route_update
,
3025 allow_external_route_update_cmd
,
3026 "allow-external-route-update",
3027 "Allow FRR routes to be overwritten by external processes\n")
3034 DEFUN (no_allow_external_route_update
,
3035 no_allow_external_route_update_cmd
,
3036 "no allow-external-route-update",
3038 "Allow FRR routes to be overwritten by external processes\n")
3053 struct zebra_vrf
*zvrf
;
3055 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
3057 if (!(zvrf
= vrf
->info
))
3059 if (!zvrf_id (zvrf
))
3062 vty_out (vty
, "vrf %s ", zvrf_name (zvrf
));
3063 if (zvrf_id (zvrf
) == VRF_UNKNOWN
)
3064 vty_out (vty
, "inactive");
3066 vty_out (vty
, "id %u table %u", zvrf_id (zvrf
), zvrf
->table_id
);
3067 vty_out (vty
, "%s", VTY_NEWLINE
);
3074 /* Static ip route configuration write function. */
3076 zebra_ip_config (struct vty
*vty
)
3080 write
+= static_config (vty
, AFI_IP
, SAFI_UNICAST
, "ip route");
3081 write
+= static_config (vty
, AFI_IP
, SAFI_MULTICAST
, "ip mroute");
3082 write
+= static_config (vty
, AFI_IP6
, SAFI_UNICAST
, "ipv6 route");
3084 write
+= zebra_import_table_config (vty
);
3088 DEFUN (ip_zebra_import_table_distance
,
3089 ip_zebra_import_table_distance_cmd
,
3090 "ip import-table (1-252) [distance (1-255)] [route-map WORD]",
3092 "import routes from non-main kernel table\n"
3093 "kernel routing table id\n"
3094 "Distance for imported routes\n"
3095 "Default distance value\n"
3096 "route-map for filtering\n"
3099 u_int32_t table_id
= 0;
3101 VTY_GET_INTEGER("table", table_id
, argv
[2]->arg
);
3102 int distance
= ZEBRA_TABLE_DISTANCE_DEFAULT
;
3103 char *rmap
= strmatch (argv
[argc
- 2]->text
, "route-map") ?
3104 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, argv
[argc
- 1]->arg
) : NULL
;
3107 if (argc
== 7 || (argc
== 5 && !rmap
))
3108 VTY_GET_INTEGER_RANGE("distance", distance
, argv
[4]->arg
, 1, 255);
3110 if (!is_zebra_valid_kernel_table(table_id
))
3112 vty_out(vty
, "Invalid routing table ID, %d. Must be in range 1-252%s",
3113 table_id
, VTY_NEWLINE
);
3117 if (is_zebra_main_routing_table(table_id
))
3119 vty_out(vty
, "Invalid routing table ID, %d. Must be non-default table%s",
3120 table_id
, VTY_NEWLINE
);
3124 ret
= zebra_import_table(AFI_IP
, table_id
, distance
, rmap
, 1);
3126 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
);
3131 DEFUN (no_ip_zebra_import_table
,
3132 no_ip_zebra_import_table_cmd
,
3133 "no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
3136 "import routes from non-main kernel table\n"
3137 "kernel routing table id\n"
3138 "Distance for imported routes\n"
3139 "Default distance value\n"
3140 "route-map for filtering\n"
3143 u_int32_t table_id
= 0;
3144 VTY_GET_INTEGER("table", table_id
, argv
[3]->arg
);
3146 if (!is_zebra_valid_kernel_table(table_id
))
3148 vty_out(vty
, "Invalid routing table ID. Must be in range 1-252%s",
3153 if (is_zebra_main_routing_table(table_id
))
3155 vty_out(vty
, "Invalid routing table ID, %d. Must be non-default table%s",
3156 table_id
, VTY_NEWLINE
);
3160 if (!is_zebra_import_table_enabled(AFI_IP
, table_id
))
3163 return (zebra_import_table(AFI_IP
, table_id
, 0, NULL
, 0));
3167 config_write_protocol (struct vty
*vty
)
3170 vty_out(vty
, "allow-external-route-update%s", VTY_NEWLINE
);
3172 if (zebra_rnh_ip_default_route
)
3173 vty_out(vty
, "ip nht resolve-via-default%s", VTY_NEWLINE
);
3175 if (zebra_rnh_ipv6_default_route
)
3176 vty_out(vty
, "ipv6 nht resolve-via-default%s", VTY_NEWLINE
);
3178 enum multicast_mode ipv4_multicast_mode
= multicast_mode_ipv4_get ();
3180 if (ipv4_multicast_mode
!= MCAST_NO_CONFIG
)
3181 vty_out (vty
, "ip multicast rpf-lookup-mode %s%s",
3182 ipv4_multicast_mode
== MCAST_URIB_ONLY
? "urib-only" :
3183 ipv4_multicast_mode
== MCAST_MRIB_ONLY
? "mrib-only" :
3184 ipv4_multicast_mode
== MCAST_MIX_MRIB_FIRST
? "mrib-then-urib" :
3185 ipv4_multicast_mode
== MCAST_MIX_DISTANCE
? "lower-distance" :
3189 zebra_routemap_config_write_protocol(vty
);
3194 /* IP node for static routes. */
3195 static struct cmd_node ip_node
= { IP_NODE
, "", 1 };
3196 static struct cmd_node protocol_node
= { PROTOCOL_NODE
, "", 1 };
3200 zebra_vty_init (void)
3202 install_node (&ip_node
, zebra_ip_config
);
3203 install_node (&protocol_node
, config_write_protocol
);
3205 install_element (CONFIG_NODE
, &allow_external_route_update_cmd
);
3206 install_element (CONFIG_NODE
, &no_allow_external_route_update_cmd
);
3207 install_element (CONFIG_NODE
, &ip_mroute_dist_cmd
);
3208 install_element (CONFIG_NODE
, &no_ip_mroute_dist_cmd
);
3209 install_element (CONFIG_NODE
, &ip_multicast_mode_cmd
);
3210 install_element (CONFIG_NODE
, &no_ip_multicast_mode_cmd
);
3211 install_element (CONFIG_NODE
, &ip_route_cmd
);
3212 install_element (CONFIG_NODE
, &ip_route_flags_cmd
);
3213 install_element (CONFIG_NODE
, &ip_route_mask_cmd
);
3214 install_element (CONFIG_NODE
, &ip_route_mask_flags_cmd
);
3215 install_element (CONFIG_NODE
, &no_ip_route_cmd
);
3216 install_element (CONFIG_NODE
, &no_ip_route_mask_cmd
);
3217 install_element (CONFIG_NODE
, &ip_zebra_import_table_distance_cmd
);
3218 install_element (CONFIG_NODE
, &no_ip_zebra_import_table_cmd
);
3220 install_element (VIEW_NODE
, &show_vrf_cmd
);
3221 install_element (VIEW_NODE
, &show_ip_route_cmd
);
3222 install_element (VIEW_NODE
, &show_ip_nht_cmd
);
3223 install_element (VIEW_NODE
, &show_ip_nht_vrf_all_cmd
);
3224 install_element (VIEW_NODE
, &show_ipv6_nht_cmd
);
3225 install_element (VIEW_NODE
, &show_ipv6_nht_vrf_all_cmd
);
3226 install_element (VIEW_NODE
, &show_ip_route_addr_cmd
);
3227 install_element (VIEW_NODE
, &show_ip_route_prefix_cmd
);
3228 install_element (VIEW_NODE
, &show_ip_route_summary_cmd
);
3229 install_element (VIEW_NODE
, &show_ip_route_summary_prefix_cmd
);
3231 install_element (VIEW_NODE
, &show_ip_rpf_cmd
);
3232 install_element (VIEW_NODE
, &show_ip_rpf_addr_cmd
);
3234 /* Commands for VRF */
3236 install_element (CONFIG_NODE
, &no_ip_route_flags_cmd
);
3237 install_element (CONFIG_NODE
, &no_ip_route_mask_flags_cmd
);
3239 install_element (VIEW_NODE
, &show_ip_route_vrf_all_addr_cmd
);
3240 install_element (VIEW_NODE
, &show_ip_route_vrf_all_prefix_cmd
);
3241 install_element (VIEW_NODE
, &show_ip_route_vrf_all_summary_cmd
);
3242 install_element (VIEW_NODE
, &show_ip_route_vrf_all_summary_prefix_cmd
);
3244 install_element (CONFIG_NODE
, &ipv6_route_cmd
);
3245 install_element (CONFIG_NODE
, &ipv6_route_flags_cmd
);
3246 install_element (CONFIG_NODE
, &ipv6_route_ifname_cmd
);
3247 install_element (CONFIG_NODE
, &ipv6_route_ifname_flags_cmd
);
3248 install_element (CONFIG_NODE
, &no_ipv6_route_cmd
);
3249 install_element (CONFIG_NODE
, &no_ipv6_route_flags_cmd
);
3250 install_element (CONFIG_NODE
, &no_ipv6_route_ifname_cmd
);
3251 install_element (CONFIG_NODE
, &no_ipv6_route_ifname_flags_cmd
);
3252 install_element (CONFIG_NODE
, &ip_nht_default_route_cmd
);
3253 install_element (CONFIG_NODE
, &no_ip_nht_default_route_cmd
);
3254 install_element (CONFIG_NODE
, &ipv6_nht_default_route_cmd
);
3255 install_element (CONFIG_NODE
, &no_ipv6_nht_default_route_cmd
);
3256 install_element (VIEW_NODE
, &show_ipv6_route_cmd
);
3257 install_element (VIEW_NODE
, &show_ipv6_route_summary_cmd
);
3258 install_element (VIEW_NODE
, &show_ipv6_route_summary_prefix_cmd
);
3259 install_element (VIEW_NODE
, &show_ipv6_route_addr_cmd
);
3260 install_element (VIEW_NODE
, &show_ipv6_route_prefix_cmd
);
3261 install_element (VIEW_NODE
, &show_ipv6_mroute_cmd
);
3263 /* Commands for VRF */
3264 install_element (VIEW_NODE
, &show_ipv6_route_vrf_all_summary_cmd
);
3265 install_element (VIEW_NODE
, &show_ipv6_route_vrf_all_summary_prefix_cmd
);
3266 install_element (VIEW_NODE
, &show_ipv6_route_vrf_all_addr_cmd
);
3267 install_element (VIEW_NODE
, &show_ipv6_route_vrf_all_prefix_cmd
);
3269 install_element (VIEW_NODE
, &show_ipv6_mroute_vrf_all_cmd
);