2002-12-13 21:15:29 +01:00
|
|
|
/* Zebra VTY functions
|
|
|
|
* Copyright (C) 2002 Kunihiro Ishiguro
|
|
|
|
*
|
|
|
|
* This file is part of GNU Zebra.
|
|
|
|
*
|
|
|
|
* GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
* later version.
|
|
|
|
*
|
|
|
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2007-05-02 18:05:35 +02:00
|
|
|
#include "memory.h"
|
2015-05-29 05:48:31 +02:00
|
|
|
#include "zebra_memory.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "if.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "rib.h"
|
2015-05-20 02:40:34 +02:00
|
|
|
#include "nexthop.h"
|
2015-05-22 11:39:56 +02:00
|
|
|
#include "vrf.h"
|
2016-04-15 19:51:56 +02:00
|
|
|
#include "mpls.h"
|
2015-05-29 05:48:31 +02:00
|
|
|
#include "routemap.h"
|
2016-12-05 20:05:30 +01:00
|
|
|
#include "srcdest_table.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-06-28 19:17:12 +02:00
|
|
|
#include "zebra/zserv.h"
|
2016-04-14 15:20:47 +02:00
|
|
|
#include "zebra/zebra_vrf.h"
|
2016-04-15 19:51:56 +02:00
|
|
|
#include "zebra/zebra_mpls.h"
|
2015-05-20 02:40:34 +02:00
|
|
|
#include "zebra/zebra_rnh.h"
|
2015-05-20 03:03:42 +02:00
|
|
|
#include "zebra/redistribute.h"
|
2015-08-26 14:21:40 +02:00
|
|
|
#include "zebra/zebra_routemap.h"
|
2016-09-01 13:20:02 +02:00
|
|
|
#include "zebra/zebra_static.h"
|
2016-10-07 15:05:28 +02:00
|
|
|
#include "lib/json.h"
|
2015-08-26 14:21:40 +02:00
|
|
|
|
|
|
|
extern int allow_delete;
|
2005-06-28 19:17:12 +02:00
|
|
|
|
2016-08-29 21:59:53 +02:00
|
|
|
static int do_show_ip_route(struct vty *vty, const char *vrf_name,
|
2017-05-22 21:56:11 +02:00
|
|
|
afi_t afi, safi_t safi, bool use_fib, u_char use_json,
|
|
|
|
route_tag_t tag, struct prefix *longer_prefix_p,
|
|
|
|
bool supernets_only, int type, u_short ospf_instance_id);
|
2015-01-22 19:12:35 +01:00
|
|
|
static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn,
|
|
|
|
int mcast);
|
2014-07-14 16:19:00 +02:00
|
|
|
|
2016-08-29 21:59:53 +02:00
|
|
|
#define ONE_DAY_SECOND 60*60*24
|
|
|
|
#define ONE_WEEK_SECOND 60*60*24*7
|
|
|
|
|
2014-07-14 16:19:00 +02:00
|
|
|
/* General function for static route. */
|
2016-09-14 22:55:21 +02:00
|
|
|
int
|
2014-07-14 16:19:00 +02:00
|
|
|
zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
|
|
|
|
const char *dest_str, const char *mask_str,
|
|
|
|
const char *gate_str, const char *flag_str,
|
|
|
|
const char *tag_str, const char *distance_str,
|
2016-04-19 00:54:11 +02:00
|
|
|
const char *vrf_id_str, const char *label_str)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u_char distance;
|
|
|
|
struct prefix p;
|
|
|
|
struct in_addr gate;
|
|
|
|
struct in_addr mask;
|
2003-05-25 21:21:25 +02:00
|
|
|
u_char flag = 0;
|
2016-10-01 20:42:34 +02:00
|
|
|
route_tag_t tag = 0;
|
2016-04-27 22:22:13 +02:00
|
|
|
struct zebra_vrf *zvrf = NULL;
|
2015-12-04 18:34:42 +01:00
|
|
|
unsigned int ifindex = 0;
|
2016-05-10 14:49:28 +02:00
|
|
|
const char *ifname = NULL;
|
2016-10-21 22:05:03 +02:00
|
|
|
u_char type = STATIC_BLACKHOLE;
|
2016-04-19 00:54:11 +02:00
|
|
|
struct static_nh_label snh_label;
|
2015-12-04 18:34:42 +01:00
|
|
|
|
2016-04-19 00:54:11 +02:00
|
|
|
memset (&snh_label, 0, sizeof (struct static_nh_label));
|
2002-12-13 21:15:29 +01:00
|
|
|
ret = str2prefix (dest_str, &p);
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed address\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cisco like mask notation. */
|
|
|
|
if (mask_str)
|
|
|
|
{
|
|
|
|
ret = inet_aton (mask_str, &mask);
|
|
|
|
if (ret == 0)
|
2003-05-25 23:35:06 +02:00
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed address\n");
|
2003-05-25 23:35:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = ip_masklen (mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply mask for given prefix. */
|
|
|
|
apply_mask (&p);
|
|
|
|
|
2003-05-25 23:35:06 +02:00
|
|
|
/* Administrative distance. */
|
|
|
|
if (distance_str)
|
|
|
|
distance = atoi (distance_str);
|
|
|
|
else
|
|
|
|
distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
|
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* tag */
|
|
|
|
if (tag_str)
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
tag = strtoul(tag_str, NULL, 10);
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
/* VRF id */
|
2016-10-30 02:44:06 +02:00
|
|
|
zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
|
2016-04-27 22:22:13 +02:00
|
|
|
|
|
|
|
if (!zvrf)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% vrf %s is not defined\n", vrf_id_str);
|
2016-04-27 22:22:13 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2016-04-19 00:54:11 +02:00
|
|
|
/* Labels */
|
|
|
|
if (label_str)
|
|
|
|
{
|
2016-10-25 20:25:29 +02:00
|
|
|
if (!mpls_enabled)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty,
|
|
|
|
"%% MPLS not turned on in kernel, ignoring command\n");
|
2016-10-25 20:25:29 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2017-05-31 23:27:08 +02:00
|
|
|
int rc = mpls_str2label (label_str, &snh_label.num_labels,
|
|
|
|
snh_label.label);
|
|
|
|
if (rc < 0)
|
2016-04-19 00:54:11 +02:00
|
|
|
{
|
2017-05-31 23:27:08 +02:00
|
|
|
switch (rc) {
|
|
|
|
case -1:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed label(s)\n");
|
2017-05-31 23:27:08 +02:00
|
|
|
break;
|
|
|
|
case -2:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
MPLS_MIN_RESERVED_LABEL,MPLS_MAX_RESERVED_LABEL);
|
2017-05-31 23:27:08 +02:00
|
|
|
break;
|
|
|
|
case -3:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Too many labels. Enter %d or fewer\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
MPLS_MAX_LABELS);
|
2017-05-31 23:27:08 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-04-19 00:54:11 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-25 23:35:06 +02:00
|
|
|
/* Null0 static route. */
|
2003-05-28 14:02:15 +02:00
|
|
|
if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
|
2003-05-25 23:35:06 +02:00
|
|
|
{
|
|
|
|
if (flag_str)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% can not have flag %s with Null0\n", flag_str);
|
2003-05-25 23:35:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
if (add_cmd)
|
2016-11-24 17:10:19 +01:00
|
|
|
static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname,
|
2016-04-19 00:54:11 +02:00
|
|
|
ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
|
2003-05-25 23:35:06 +02:00
|
|
|
else
|
2016-11-24 17:10:19 +01:00
|
|
|
static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag,
|
2016-04-19 00:54:11 +02:00
|
|
|
distance, zvrf, &snh_label);
|
2003-05-25 23:35:06 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-05-25 21:21:25 +02:00
|
|
|
/* Route flags */
|
|
|
|
if (flag_str) {
|
|
|
|
switch(flag_str[0]) {
|
|
|
|
case 'r':
|
|
|
|
case 'R': /* XXX */
|
|
|
|
SET_FLAG (flag, ZEBRA_FLAG_REJECT);
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
case 'B': /* XXX */
|
|
|
|
SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
|
|
|
|
break;
|
|
|
|
default:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed flag %s \n", flag_str);
|
2003-05-25 23:35:06 +02:00
|
|
|
return CMD_WARNING;
|
2003-05-25 21:21:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-28 14:02:15 +02:00
|
|
|
if (gate_str == NULL)
|
|
|
|
{
|
|
|
|
if (add_cmd)
|
2016-11-24 17:10:19 +01:00
|
|
|
static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname, flag,
|
2016-04-19 00:54:11 +02:00
|
|
|
tag, distance, zvrf, &snh_label);
|
2003-05-28 14:02:15 +02:00
|
|
|
else
|
2016-11-24 17:10:19 +01:00
|
|
|
static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag, distance,
|
2016-04-19 00:54:11 +02:00
|
|
|
zvrf, &snh_label);
|
2003-05-28 14:02:15 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2016-10-18 01:36:21 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* When gateway is A.B.C.D format, gate is treated as nexthop
|
|
|
|
address other case gate is treated as interface name. */
|
|
|
|
ret = inet_aton (gate_str, &gate);
|
2015-12-04 18:34:42 +01:00
|
|
|
if (!ret)
|
|
|
|
{
|
2017-03-11 13:27:15 +01:00
|
|
|
struct interface *ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
|
2015-12-04 18:34:42 +01:00
|
|
|
if (!ifp)
|
2016-05-10 14:49:28 +02:00
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Unknown interface: %s\n", gate_str);
|
2016-05-10 14:49:28 +02:00
|
|
|
ifindex = IFINDEX_DELETED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ifindex = ifp->ifindex;
|
|
|
|
ifname = gate_str;
|
2016-08-24 06:07:49 +02:00
|
|
|
type = STATIC_IFINDEX;
|
2015-12-04 18:34:42 +01:00
|
|
|
}
|
2016-08-24 06:07:49 +02:00
|
|
|
else
|
|
|
|
type = STATIC_IPV4_GATEWAY;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (add_cmd)
|
2016-11-24 17:10:19 +01:00
|
|
|
static_add_route (AFI_IP, safi, type, &p, NULL,
|
2016-04-19 00:54:11 +02:00
|
|
|
ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
|
|
|
|
flag, tag, distance, zvrf, &snh_label);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-11-24 17:10:19 +01:00
|
|
|
static_delete_route (AFI_IP, safi, type, &p, NULL,
|
2016-04-19 00:54:11 +02:00
|
|
|
ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
|
|
|
|
distance, zvrf, &snh_label);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-07-14 16:19:00 +02:00
|
|
|
/* Static unicast routes for multicast RPF lookup. */
|
2015-01-22 19:03:53 +01:00
|
|
|
DEFUN (ip_mroute_dist,
|
|
|
|
ip_mroute_dist_cmd,
|
2016-09-28 06:47:43 +02:00
|
|
|
"ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
|
2014-07-14 16:19:00 +02:00
|
|
|
IP_STR
|
|
|
|
"Configure static unicast route into MRIB for multicast RPF lookup\n"
|
|
|
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
|
|
|
"Nexthop address\n"
|
|
|
|
"Nexthop interface name\n"
|
|
|
|
"Distance\n")
|
|
|
|
{
|
2016-09-28 06:47:43 +02:00
|
|
|
char *destprefix = argv[2]->arg;
|
|
|
|
char *nexthop = argv[3]->arg;
|
|
|
|
char *distance = (argc == 5) ? argv[4]->arg : NULL;
|
2014-07-14 16:19:00 +02:00
|
|
|
|
2016-10-18 01:36:21 +02:00
|
|
|
return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
|
2016-09-28 06:47:43 +02:00
|
|
|
}
|
2015-01-22 19:03:53 +01:00
|
|
|
|
|
|
|
DEFUN (no_ip_mroute_dist,
|
|
|
|
no_ip_mroute_dist_cmd,
|
2016-09-28 06:47:43 +02:00
|
|
|
"no ip mroute A.B.C.D/M <A.B.C.D|INTERFACE> [(1-255)]",
|
2016-11-08 02:46:04 +01:00
|
|
|
NO_STR
|
2014-07-14 16:19:00 +02:00
|
|
|
IP_STR
|
|
|
|
"Configure static unicast route into MRIB for multicast RPF lookup\n"
|
|
|
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
|
|
|
"Nexthop address\n"
|
|
|
|
"Nexthop interface name\n"
|
|
|
|
"Distance\n")
|
|
|
|
{
|
2016-09-30 17:31:48 +02:00
|
|
|
char *destprefix = argv[3]->arg;
|
|
|
|
char *nexthop = argv[4]->arg;
|
|
|
|
char *distance = (argc == 6) ? argv[5]->arg : NULL;
|
2014-07-14 16:19:00 +02:00
|
|
|
|
2016-10-18 01:36:21 +02:00
|
|
|
return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL);
|
2016-09-28 06:47:43 +02:00
|
|
|
}
|
2015-01-22 19:03:53 +01:00
|
|
|
|
2015-01-06 19:53:24 +01:00
|
|
|
DEFUN (ip_multicast_mode,
|
|
|
|
ip_multicast_mode_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"ip multicast rpf-lookup-mode <urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>",
|
2015-01-06 19:53:24 +01:00
|
|
|
IP_STR
|
|
|
|
"Multicast options\n"
|
|
|
|
"RPF lookup behavior\n"
|
|
|
|
"Lookup in unicast RIB only\n"
|
|
|
|
"Lookup in multicast RIB only\n"
|
|
|
|
"Try multicast RIB first, fall back to unicast RIB\n"
|
|
|
|
"Lookup both, use entry with lower distance\n"
|
|
|
|
"Lookup both, use entry with longer prefix\n")
|
|
|
|
{
|
2016-09-28 06:47:43 +02:00
|
|
|
char *mode = argv[3]->text;
|
2015-01-27 20:24:15 +01:00
|
|
|
|
2016-09-28 06:47:43 +02:00
|
|
|
if (strmatch (mode, "urib-only"))
|
2015-01-06 19:53:24 +01:00
|
|
|
multicast_mode_ipv4_set (MCAST_URIB_ONLY);
|
2016-09-28 06:47:43 +02:00
|
|
|
else if (strmatch (mode, "mrib-only"))
|
2015-01-06 19:53:24 +01:00
|
|
|
multicast_mode_ipv4_set (MCAST_MRIB_ONLY);
|
2016-09-28 06:47:43 +02:00
|
|
|
else if (strmatch (mode, "mrib-then-urib"))
|
2015-01-06 19:53:24 +01:00
|
|
|
multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST);
|
2016-09-28 06:47:43 +02:00
|
|
|
else if (strmatch (mode, "lower-distance"))
|
2015-01-06 19:53:24 +01:00
|
|
|
multicast_mode_ipv4_set (MCAST_MIX_DISTANCE);
|
2016-09-28 06:47:43 +02:00
|
|
|
else if (strmatch (mode, "longer-prefix"))
|
2015-01-06 19:53:24 +01:00
|
|
|
multicast_mode_ipv4_set (MCAST_MIX_PFXLEN);
|
|
|
|
else
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Invalid mode specified\n");
|
2015-01-06 19:53:24 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_multicast_mode,
|
|
|
|
no_ip_multicast_mode_cmd,
|
2016-09-28 06:47:43 +02:00
|
|
|
"no ip multicast rpf-lookup-mode [<urib-only|mrib-only|mrib-then-urib|lower-distance|longer-prefix>]",
|
2015-01-06 19:53:24 +01:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Multicast options\n"
|
|
|
|
"RPF lookup behavior\n"
|
|
|
|
"Lookup in unicast RIB only\n"
|
|
|
|
"Lookup in multicast RIB only\n"
|
|
|
|
"Try multicast RIB first, fall back to unicast RIB\n"
|
|
|
|
"Lookup both, use entry with lower distance\n"
|
|
|
|
"Lookup both, use entry with longer prefix\n")
|
|
|
|
{
|
|
|
|
multicast_mode_ipv4_set (MCAST_NO_CONFIG);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-14 16:19:00 +02:00
|
|
|
DEFUN (show_ip_rpf,
|
|
|
|
show_ip_rpf_cmd,
|
2017-05-22 21:56:11 +02:00
|
|
|
"show ip rpf [json]",
|
2014-07-14 16:19:00 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2017-05-22 21:56:11 +02:00
|
|
|
"Display RPF information for multicast source\n"
|
|
|
|
JSON_STR)
|
2014-07-14 16:19:00 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
int uj = use_json(argc, argv);
|
|
|
|
return do_show_ip_route (vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST, false, uj, 0, NULL, false, -1, 0);
|
2014-07-14 16:19:00 +02:00
|
|
|
}
|
|
|
|
|
2015-01-22 19:12:35 +01:00
|
|
|
DEFUN (show_ip_rpf_addr,
|
|
|
|
show_ip_rpf_addr_cmd,
|
|
|
|
"show ip rpf A.B.C.D",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"Display RPF information for multicast source\n"
|
|
|
|
"IP multicast source address (e.g. 10.0.0.0)\n")
|
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4 = 3;
|
2015-01-22 19:12:35 +01:00
|
|
|
struct in_addr addr;
|
|
|
|
struct route_node *rn;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-01-22 19:12:35 +01:00
|
|
|
int ret;
|
|
|
|
|
2016-09-23 21:26:31 +02:00
|
|
|
ret = inet_aton (argv[idx_ipv4]->arg, &addr);
|
2015-01-22 19:12:35 +01:00
|
|
|
if (ret == 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed address\n");
|
2015-01-22 19:12:35 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
re = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn);
|
2015-01-22 19:12:35 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re)
|
2015-01-22 19:12:35 +01:00
|
|
|
vty_show_ip_route_detail (vty, rn, 1);
|
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% No match for RPF lookup\n");
|
2015-01-22 19:12:35 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-09-26 17:25:28 +02:00
|
|
|
static void
|
|
|
|
zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[],
|
|
|
|
int idx_curr, char **tag,
|
2016-10-18 01:36:21 +02:00
|
|
|
char **distance, char **vrf, char **labels)
|
2003-05-25 21:21:25 +02:00
|
|
|
{
|
2016-10-06 06:08:34 +02:00
|
|
|
*distance = NULL;
|
|
|
|
while (idx_curr < argc)
|
|
|
|
{
|
|
|
|
if (strmatch (argv[idx_curr]->text, "tag"))
|
|
|
|
{
|
2016-10-18 01:36:21 +02:00
|
|
|
if (tag)
|
|
|
|
*tag = argv[idx_curr+1]->arg;
|
2016-10-06 06:08:34 +02:00
|
|
|
idx_curr += 2;
|
|
|
|
}
|
|
|
|
else if (strmatch (argv[idx_curr]->text, "vrf"))
|
|
|
|
{
|
2016-10-18 01:36:21 +02:00
|
|
|
if (vrf)
|
|
|
|
*vrf = argv[idx_curr+1]->arg;
|
|
|
|
idx_curr += 2;
|
|
|
|
}
|
|
|
|
else if (strmatch (argv[idx_curr]->text, "label"))
|
|
|
|
{
|
|
|
|
if (labels)
|
|
|
|
*labels = argv[idx_curr+1]->arg;
|
2016-10-06 06:08:34 +02:00
|
|
|
idx_curr += 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-10-18 01:36:21 +02:00
|
|
|
if (distance)
|
|
|
|
*distance = argv[idx_curr]->arg;
|
2016-10-06 06:08:34 +02:00
|
|
|
idx_curr++;
|
|
|
|
}
|
|
|
|
}
|
2016-09-26 17:25:28 +02:00
|
|
|
|
|
|
|
return;
|
2015-05-20 02:46:33 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 17:25:28 +02:00
|
|
|
/* Static route configuration. */
|
|
|
|
DEFUN (ip_route,
|
|
|
|
ip_route_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-20 02:46:33 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
|
|
|
"IP gateway address\n"
|
|
|
|
"IP gateway interface name\n"
|
|
|
|
"Null interface\n"
|
|
|
|
"Set tag for this route\n"
|
2016-09-26 17:25:28 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4_prefixlen = 2;
|
|
|
|
int idx_ipv4_ifname_null = 3;
|
2016-09-26 17:25:28 +02:00
|
|
|
int idx_curr = 4;
|
|
|
|
char *tag, *distance, *vrf;
|
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 17:25:28 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
|
|
|
|
argv[idx_ipv4_prefixlen]->arg,
|
|
|
|
NULL,
|
|
|
|
argv[idx_ipv4_ifname_null]->arg,
|
|
|
|
NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2003-05-25 21:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_route_flags,
|
|
|
|
ip_route_flags_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-20 02:46:33 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Set tag for this route\n"
|
2016-09-26 17:25:28 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4_prefixlen = 2;
|
|
|
|
int idx_reject_blackhole = 3;
|
2016-09-26 17:25:28 +02:00
|
|
|
int idx_curr = 4;
|
|
|
|
char *tag, *distance, *vrf;
|
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 17:25:28 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
|
|
|
|
argv[idx_ipv4_prefixlen]->arg,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
argv[idx_reject_blackhole]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2003-05-28 14:02:15 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Mask as A.B.C.D format. */
|
|
|
|
DEFUN (ip_route_mask,
|
|
|
|
ip_route_mask_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-20 02:46:33 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix\n"
|
|
|
|
"IP destination prefix mask\n"
|
|
|
|
"IP gateway address\n"
|
|
|
|
"IP gateway interface name\n"
|
|
|
|
"Null interface\n"
|
|
|
|
"Set tag for this route\n"
|
2016-09-26 17:25:28 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4 = 2;
|
|
|
|
int idx_ipv4_2 = 3;
|
|
|
|
int idx_ipv4_ifname_null = 4;
|
2016-09-26 17:25:28 +02:00
|
|
|
int idx_curr = 5;
|
|
|
|
char *tag, *distance, *vrf;
|
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 17:25:28 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
|
|
|
|
argv[idx_ipv4]->arg,
|
|
|
|
argv[idx_ipv4_2]->arg,
|
|
|
|
argv[idx_ipv4_ifname_null]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
NULL, tag, distance, vrf, NULL);
|
2003-05-25 21:21:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_route_mask_flags,
|
|
|
|
ip_route_mask_flags_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-20 02:46:33 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix\n"
|
|
|
|
"IP destination prefix mask\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Set tag for this route\n"
|
2016-09-26 17:25:28 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4 = 2;
|
|
|
|
int idx_ipv4_2 = 3;
|
|
|
|
int idx_reject_blackhole = 4;
|
2016-09-26 17:25:28 +02:00
|
|
|
int idx_curr = 5;
|
|
|
|
char *tag, *distance, *vrf;
|
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 17:25:28 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 1,
|
|
|
|
argv[idx_ipv4]->arg,
|
|
|
|
argv[idx_ipv4_2]->arg,
|
|
|
|
NULL,
|
|
|
|
argv[idx_reject_blackhole]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2003-05-28 14:02:15 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 14:10:57 +02:00
|
|
|
DEFUN (no_ip_route,
|
|
|
|
no_ip_route_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"no ip route A.B.C.D/M <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-22 11:40:06 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
|
|
|
"IP gateway address\n"
|
|
|
|
"IP gateway interface name\n"
|
|
|
|
"Null interface\n"
|
|
|
|
"Tag of this route\n"
|
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4_prefixlen = 3;
|
|
|
|
int idx_ipv4_ifname_null = 4;
|
2016-09-26 14:10:57 +02:00
|
|
|
int idx_curr = 5;
|
|
|
|
char *tag, *distance, *vrf;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-26 14:10:57 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 14:10:57 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
|
|
|
|
argv[idx_ipv4_prefixlen]->arg,
|
|
|
|
NULL,
|
|
|
|
argv[idx_ipv4_ifname_null]->arg,
|
|
|
|
NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-12-13 00:29:39 +01:00
|
|
|
DEFUN (no_ip_route_flags,
|
|
|
|
no_ip_route_flags_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"no ip route A.B.C.D/M <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-22 11:40:06 +02:00
|
|
|
NO_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
IP_STR
|
2015-05-22 11:40:06 +02:00
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Tag of this route\n"
|
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4_prefixlen = 3;
|
2016-09-26 14:10:57 +02:00
|
|
|
int idx_curr = 5;
|
|
|
|
char *tag, *distance, *vrf;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-26 14:10:57 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-26 14:10:57 +02:00
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
|
|
|
|
argv[idx_ipv4_prefixlen]->arg,
|
|
|
|
NULL, NULL, NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-09-26 14:10:57 +02:00
|
|
|
DEFUN (no_ip_route_mask,
|
|
|
|
no_ip_route_mask_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"no ip route A.B.C.D A.B.C.D <A.B.C.D|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-22 11:40:06 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix\n"
|
|
|
|
"IP destination prefix mask\n"
|
|
|
|
"IP gateway address\n"
|
|
|
|
"IP gateway interface name\n"
|
|
|
|
"Null interface\n"
|
2016-09-26 14:10:57 +02:00
|
|
|
"Tag of this route\n"
|
|
|
|
"Tag value\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4 = 3;
|
|
|
|
int idx_ipv4_2 = 4;
|
|
|
|
int idx_ipv4_ifname_null = 5;
|
2016-09-26 14:10:57 +02:00
|
|
|
int idx_curr = 6;
|
|
|
|
char *tag, *distance, *vrf;
|
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 14:10:57 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
|
|
|
|
argv[idx_ipv4]->arg,
|
|
|
|
argv[idx_ipv4_2]->arg,
|
|
|
|
argv[idx_ipv4_ifname_null]->arg,
|
|
|
|
NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-12-13 00:29:39 +01:00
|
|
|
DEFUN (no_ip_route_mask_flags,
|
|
|
|
no_ip_route_mask_flags_cmd,
|
2016-10-18 01:36:21 +02:00
|
|
|
"no ip route A.B.C.D A.B.C.D <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
|
2015-05-22 11:40:06 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IP destination prefix\n"
|
|
|
|
"IP destination prefix mask\n"
|
2016-09-26 14:10:57 +02:00
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Tag of this route\n"
|
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this route\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4 = 3;
|
|
|
|
int idx_ipv4_2 = 4;
|
2016-09-26 14:10:57 +02:00
|
|
|
int idx_curr = 6;
|
|
|
|
char *tag, *distance, *vrf;
|
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 14:10:57 +02:00
|
|
|
|
|
|
|
return zebra_static_ipv4 (vty, SAFI_UNICAST, 0,
|
|
|
|
argv[idx_ipv4]->arg,
|
|
|
|
argv[idx_ipv4_2]->arg,
|
|
|
|
NULL, NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
/* New RIB. Detailed information for IPv4 route. */
|
2005-06-28 19:17:12 +02:00
|
|
|
static void
|
2015-01-22 19:12:35 +01:00
|
|
|
vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct nexthop *nexthop, *tnexthop;
|
|
|
|
int recursing;
|
2016-12-05 20:05:30 +01:00
|
|
|
char buf[SRCDEST2STR_BUFFER];
|
2016-02-28 23:03:27 +01:00
|
|
|
struct zebra_vrf *zvrf;
|
2008-11-05 00:45:07 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re)
|
2008-11-05 00:45:07 +01:00
|
|
|
{
|
2015-03-07 08:40:48 +01:00
|
|
|
const char *mcast_info = "";
|
2015-01-22 19:12:35 +01:00
|
|
|
if (mcast)
|
|
|
|
{
|
2016-12-05 20:05:30 +01:00
|
|
|
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
2015-01-22 19:12:35 +01:00
|
|
|
mcast_info = (info->safi == SAFI_MULTICAST)
|
|
|
|
? " using Multicast RIB"
|
|
|
|
: " using Unicast RIB";
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2015-05-23 10:08:40 +02:00
|
|
|
vty_out (vty, "Routing entry for %s%s%s",
|
2016-12-05 20:05:30 +01:00
|
|
|
srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
|
2017-06-21 19:15:40 +02:00
|
|
|
VTYNL);
|
2017-06-01 13:26:25 +02:00
|
|
|
vty_out (vty, " Known via \"%s", zebra_route_string (re->type));
|
|
|
|
if (re->instance)
|
|
|
|
vty_out (vty, "[%d]", re->instance);
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, "\"");
|
2017-06-01 13:26:25 +02:00
|
|
|
vty_out (vty, ", distance %u, metric %u", re->distance, re->metric);
|
|
|
|
if (re->tag)
|
|
|
|
vty_out (vty, ", tag %d", re->tag);
|
|
|
|
if (re->mtu)
|
|
|
|
vty_out (vty, ", mtu %u", re->mtu);
|
|
|
|
if (re->vrf_id != VRF_DEFAULT)
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
zvrf = vrf_info_lookup(re->vrf_id);
|
2016-12-05 19:43:38 +01:00
|
|
|
vty_out (vty, ", vrf %s", zvrf_name (zvrf));
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", best");
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->refcnt)
|
|
|
|
vty_out (vty, ", refcnt %ld", re->refcnt);
|
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", blackhole");
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", reject");
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out (vty, "\n");
|
2008-11-05 00:45:07 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->type == ZEBRA_ROUTE_RIP
|
|
|
|
|| re->type == ZEBRA_ROUTE_OSPF
|
|
|
|
|| re->type == ZEBRA_ROUTE_ISIS
|
|
|
|
|| re->type == ZEBRA_ROUTE_NHRP
|
|
|
|
|| re->type == ZEBRA_ROUTE_TABLE
|
|
|
|
|| re->type == ZEBRA_ROUTE_BGP)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
time_t uptime;
|
|
|
|
struct tm *tm;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
uptime = time (NULL);
|
2017-06-01 13:26:25 +02:00
|
|
|
uptime -= re->uptime;
|
2015-05-22 11:40:06 +02:00
|
|
|
tm = gmtime (&uptime);
|
2015-05-20 02:24:41 +02:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, " Last update ");
|
2015-05-20 02:24:41 +02:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
if (uptime < ONE_DAY_SECOND)
|
2016-10-18 01:36:21 +02:00
|
|
|
vty_out (vty, "%02d:%02d:%02d",
|
2015-05-22 11:40:06 +02:00
|
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
|
else if (uptime < ONE_WEEK_SECOND)
|
2016-10-18 01:36:21 +02:00
|
|
|
vty_out (vty, "%dd%02dh%02dm",
|
2015-05-22 11:40:06 +02:00
|
|
|
tm->tm_yday, tm->tm_hour, tm->tm_min);
|
2015-05-20 02:24:41 +02:00
|
|
|
else
|
2016-10-18 01:36:21 +02:00
|
|
|
vty_out (vty, "%02dw%dd%02dh",
|
2015-05-22 11:40:06 +02:00
|
|
|
tm->tm_yday/7,
|
|
|
|
tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out (vty, " ago\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
char addrstr[32];
|
|
|
|
|
|
|
|
vty_out (vty, " %c%s",
|
|
|
|
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ',
|
|
|
|
recursing ? " " : "");
|
|
|
|
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
|
|
|
|
if (nexthop->ifindex)
|
|
|
|
vty_out (vty, ", via %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
vty_out (vty, " %s",
|
2017-06-10 21:42:13 +02:00
|
|
|
inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof buf));
|
2015-12-04 18:52:49 +01:00
|
|
|
if (nexthop->ifindex)
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", via %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
vty_out (vty, " directly connected, %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
2015-05-23 10:08:40 +02:00
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
|
|
|
vty_out (vty, " directly connected, Null0");
|
|
|
|
break;
|
|
|
|
default:
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
|
|
|
vty_out (vty, " inactive");
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
|
|
|
vty_out (vty, " onlink");
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
|
|
|
vty_out (vty, " (recursive)");
|
|
|
|
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
if (nexthop->src.ipv4.s_addr)
|
|
|
|
{
|
|
|
|
if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
|
|
|
|
sizeof addrstr))
|
|
|
|
vty_out (vty, ", src %s", addrstr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
|
|
|
|
{
|
|
|
|
if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
|
|
|
|
sizeof addrstr))
|
|
|
|
vty_out (vty, ", src %s", addrstr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-12-09 01:04:52 +01:00
|
|
|
|
|
|
|
/* Label information */
|
|
|
|
if (nexthop->nh_label && nexthop->nh_label->num_labels)
|
|
|
|
{
|
2017-05-10 15:42:00 +02:00
|
|
|
vty_out (vty, ", label %s",
|
2016-12-09 01:04:52 +01:00
|
|
|
mpls_label2str (nexthop->nh_label->num_labels,
|
2017-06-10 21:42:13 +02:00
|
|
|
nexthop->nh_label->label, buf, sizeof buf, 1));
|
2016-12-09 01:04:52 +01:00
|
|
|
}
|
|
|
|
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-06-01 13:26:25 +02:00
|
|
|
vty_show_ip_route (struct vty *vty, struct route_node *rn, struct route_entry *re,
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object *json)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
struct nexthop *nexthop, *tnexthop;
|
|
|
|
int recursing;
|
|
|
|
int len = 0;
|
2016-12-05 20:05:30 +01:00
|
|
|
char buf[SRCDEST2STR_BUFFER];
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object *json_nexthops = NULL;
|
|
|
|
json_object *json_nexthop = NULL;
|
|
|
|
json_object *json_route = NULL;
|
2017-05-10 15:42:00 +02:00
|
|
|
json_object *json_labels = NULL;
|
2016-08-29 21:59:53 +02:00
|
|
|
|
|
|
|
if (json)
|
|
|
|
{
|
|
|
|
json_route = json_object_new_object();
|
|
|
|
json_nexthops = json_object_new_array();
|
|
|
|
|
2016-12-05 20:05:30 +01:00
|
|
|
json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf));
|
2017-06-01 13:26:25 +02:00
|
|
|
json_object_string_add(json_route, "protocol", zebra_route_string(re->type));
|
2016-08-29 21:59:53 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->instance)
|
|
|
|
json_object_int_add(json_route, "instance", re->instance);
|
2016-08-29 21:59:53 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->vrf_id)
|
|
|
|
json_object_int_add(json_route, "vrfId", re->vrf_id);
|
2016-08-29 21:59:53 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object_boolean_true_add(json_route, "selected");
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->type != ZEBRA_ROUTE_CONNECT && re->type != ZEBRA_ROUTE_KERNEL)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
json_object_int_add(json_route, "distance", re->distance);
|
|
|
|
json_object_int_add(json_route, "metric", re->metric);
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object_boolean_true_add(json_route, "blackhole");
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object_boolean_true_add(json_route, "reject");
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->type == ZEBRA_ROUTE_RIP
|
|
|
|
|| re->type == ZEBRA_ROUTE_OSPF
|
|
|
|
|| re->type == ZEBRA_ROUTE_ISIS
|
|
|
|
|| re->type == ZEBRA_ROUTE_NHRP
|
|
|
|
|| re->type == ZEBRA_ROUTE_TABLE
|
|
|
|
|| re->type == ZEBRA_ROUTE_BGP)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
|
|
|
time_t uptime;
|
|
|
|
struct tm *tm;
|
|
|
|
|
|
|
|
uptime = time (NULL);
|
2017-06-01 13:26:25 +02:00
|
|
|
uptime -= re->uptime;
|
2016-08-29 21:59:53 +02:00
|
|
|
tm = gmtime (&uptime);
|
|
|
|
|
|
|
|
if (uptime < ONE_DAY_SECOND)
|
|
|
|
sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
|
else if (uptime < ONE_WEEK_SECOND)
|
|
|
|
sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min);
|
|
|
|
else
|
|
|
|
sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
|
|
|
|
|
|
|
|
json_object_string_add(json_route, "uptime", buf);
|
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
|
|
|
json_nexthop = json_object_new_object();
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
|
|
|
json_object_boolean_true_add(json_nexthop, "fib");
|
|
|
|
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4));
|
|
|
|
json_object_string_add(json_nexthop, "afi", "ipv4");
|
|
|
|
|
|
|
|
if (nexthop->ifindex)
|
|
|
|
{
|
|
|
|
json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
|
2017-06-01 13:26:25 +02:00
|
|
|
json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
2017-06-10 21:42:13 +02:00
|
|
|
json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof buf));
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object_string_add(json_nexthop, "afi", "ipv6");
|
|
|
|
|
|
|
|
if (nexthop->ifindex)
|
|
|
|
{
|
|
|
|
json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
|
2017-06-01 13:26:25 +02:00
|
|
|
json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
json_object_boolean_true_add(json_nexthop, "directlyConnected");
|
|
|
|
json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex);
|
2017-06-01 13:26:25 +02:00
|
|
|
json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2016-08-29 21:59:53 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
|
|
|
json_object_boolean_true_add(json_nexthop, "blackhole");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
|
|
|
json_object_boolean_true_add(json_nexthop, "active");
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
|
|
|
json_object_boolean_true_add(json_nexthop, "onLink");
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
|
|
|
json_object_boolean_true_add(json_nexthop, "recursive");
|
|
|
|
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
if (nexthop->src.ipv4.s_addr)
|
|
|
|
{
|
|
|
|
if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
|
|
|
|
json_object_string_add(json_nexthop, "source", buf);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
|
|
|
|
{
|
|
|
|
if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
|
|
|
|
json_object_string_add(json_nexthop, "source", buf);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-05-10 15:42:00 +02:00
|
|
|
if (nexthop->nh_label && nexthop->nh_label->num_labels)
|
|
|
|
{
|
|
|
|
json_labels = json_object_new_array();
|
|
|
|
|
|
|
|
for (int label_index = 0; label_index < nexthop->nh_label->num_labels; label_index++)
|
|
|
|
json_object_array_add(json_labels, json_object_new_int(nexthop->nh_label->label[label_index]));
|
|
|
|
|
|
|
|
json_object_object_add(json_nexthop, "labels", json_labels);
|
|
|
|
}
|
|
|
|
|
2016-08-29 21:59:53 +02:00
|
|
|
json_object_array_add(json_nexthops, json_nexthop);
|
|
|
|
}
|
|
|
|
|
|
|
|
json_object_object_add(json_route, "nexthops", json_nexthops);
|
|
|
|
json_object_array_add(json, json_route);
|
|
|
|
return;
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
/* Nexthop information. */
|
2017-06-01 13:26:25 +02:00
|
|
|
for (ALL_NEXTHOPS_RO(re->nexthop, nexthop, tnexthop, recursing))
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
if (nexthop == re->nexthop)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
/* Prefix information. */
|
2017-06-01 13:26:25 +02:00
|
|
|
len = vty_out (vty, "%c", zebra_route_char (re->type));
|
|
|
|
if (re->instance)
|
|
|
|
len += vty_out (vty, "[%d]", re->instance);
|
2015-05-23 10:08:40 +02:00
|
|
|
len += vty_out (vty, "%c%c %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED)
|
2015-05-23 10:08:40 +02:00
|
|
|
? '>' : ' ',
|
|
|
|
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
|
|
|
? '*' : ' ',
|
2016-12-05 20:05:30 +01:00
|
|
|
srcdest_rnode2str (rn, buf, sizeof buf));
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
/* Distance and metric display. */
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->type != ZEBRA_ROUTE_CONNECT
|
|
|
|
&& re->type != ZEBRA_ROUTE_KERNEL)
|
|
|
|
len += vty_out (vty, " [%d/%d]", re->distance,
|
|
|
|
re->metric);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
vty_out (vty, " %c%*c",
|
|
|
|
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
|
|
|
? '*' : ' ',
|
|
|
|
len - 3 + (2 * recursing), ' ');
|
|
|
|
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
|
|
|
|
if (nexthop->ifindex)
|
|
|
|
vty_out (vty, ", %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
vty_out (vty, " via %s",
|
2017-06-10 21:42:13 +02:00
|
|
|
inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, sizeof buf));
|
2015-12-04 18:52:49 +01:00
|
|
|
if (nexthop->ifindex)
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
vty_out (vty, " is directly connected, %s",
|
2017-06-01 13:26:25 +02:00
|
|
|
ifindex2ifname (nexthop->ifindex, re->vrf_id));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
2015-05-23 10:08:40 +02:00
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
|
|
|
vty_out (vty, " is directly connected, Null0");
|
|
|
|
break;
|
|
|
|
default:
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
|
|
|
vty_out (vty, " inactive");
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
|
|
|
vty_out (vty, " onlink");
|
|
|
|
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
|
|
|
vty_out (vty, " (recursive)");
|
|
|
|
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
if (nexthop->src.ipv4.s_addr)
|
|
|
|
{
|
|
|
|
if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
|
|
|
|
vty_out (vty, ", src %s", buf);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
|
|
|
|
{
|
|
|
|
if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
|
|
|
|
vty_out (vty, ", src %s", buf);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-12-09 01:04:52 +01:00
|
|
|
/* Label information */
|
|
|
|
if (nexthop->nh_label && nexthop->nh_label->num_labels)
|
|
|
|
{
|
2017-05-10 15:42:00 +02:00
|
|
|
vty_out (vty, ", label %s",
|
2016-12-09 01:04:52 +01:00
|
|
|
mpls_label2str (nexthop->nh_label->num_labels,
|
2017-06-10 21:42:13 +02:00
|
|
|
nexthop->nh_label->label, buf, sizeof buf, 1));
|
2016-12-09 01:04:52 +01:00
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_BLACKHOLE))
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", bh");
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_REJECT))
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, ", rej");
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->type == ZEBRA_ROUTE_RIP
|
|
|
|
|| re->type == ZEBRA_ROUTE_OSPF
|
|
|
|
|| re->type == ZEBRA_ROUTE_ISIS
|
|
|
|
|| re->type == ZEBRA_ROUTE_NHRP
|
|
|
|
|| re->type == ZEBRA_ROUTE_TABLE
|
|
|
|
|| re->type == ZEBRA_ROUTE_BGP)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
time_t uptime;
|
|
|
|
struct tm *tm;
|
|
|
|
|
|
|
|
uptime = time (NULL);
|
2017-06-01 13:26:25 +02:00
|
|
|
uptime -= re->uptime;
|
2015-05-22 11:40:06 +02:00
|
|
|
tm = gmtime (&uptime);
|
|
|
|
|
|
|
|
if (uptime < ONE_DAY_SECOND)
|
2016-10-18 01:36:21 +02:00
|
|
|
vty_out (vty, ", %02d:%02d:%02d",
|
2015-05-22 11:40:06 +02:00
|
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
|
else if (uptime < ONE_WEEK_SECOND)
|
2016-10-18 01:36:21 +02:00
|
|
|
vty_out (vty, ", %dd%02dh%02dm",
|
2015-05-22 11:40:06 +02:00
|
|
|
tm->tm_yday, tm->tm_hour, tm->tm_min);
|
|
|
|
else
|
2016-10-18 01:36:21 +02:00
|
|
|
vty_out (vty, ", %02dw%dd%02dh",
|
2015-05-22 11:40:06 +02:00
|
|
|
tm->tm_yday/7,
|
|
|
|
tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
|
|
|
|
}
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-10 22:33:48 +02:00
|
|
|
static bool
|
|
|
|
use_fib (struct cmd_token *token)
|
|
|
|
{
|
|
|
|
return strncmp(token->arg, "route", strlen(token->arg));
|
|
|
|
}
|
|
|
|
|
2014-07-14 16:19:00 +02:00
|
|
|
static int
|
2017-05-22 21:56:11 +02:00
|
|
|
do_show_ip_route (struct vty *vty, const char *vrf_name, afi_t afi, safi_t safi,
|
|
|
|
bool use_fib, u_char use_json, route_tag_t tag,
|
|
|
|
struct prefix *longer_prefix_p, bool supernets_only,
|
|
|
|
int type, u_short ospf_instance_id)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-05-22 11:40:06 +02:00
|
|
|
int first = 1;
|
2016-05-04 15:44:43 +02:00
|
|
|
struct zebra_vrf *zvrf = NULL;
|
2016-08-29 21:59:53 +02:00
|
|
|
char buf[BUFSIZ];
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_prefix = NULL;
|
2017-05-22 21:56:11 +02:00
|
|
|
u_int32_t addr;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name)))
|
2016-05-04 15:44:43 +02:00
|
|
|
{
|
2016-08-29 21:59:53 +02:00
|
|
|
if (use_json)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "{}\n");
|
2016-08-29 21:59:53 +02:00
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "vrf %s not defined\n", vrf_name);
|
2014-07-14 16:19:00 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2016-05-04 15:44:43 +02:00
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
if (zvrf_id (zvrf) == VRF_UNKNOWN)
|
2014-07-14 16:19:00 +02:00
|
|
|
{
|
2016-08-29 21:59:53 +02:00
|
|
|
if (use_json)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "{}\n");
|
2016-08-29 21:59:53 +02:00
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "vrf %s inactive\n", vrf_name);
|
2014-07-14 16:19:00 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-05-04 15:44:43 +02:00
|
|
|
}
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
table = zebra_vrf_table (afi, safi, zvrf_id (zvrf));
|
2015-05-22 11:40:06 +02:00
|
|
|
if (! table)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
|
|
|
if (use_json)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "{}\n");
|
2016-08-29 21:59:53 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (use_json)
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
/* Show all routes. */
|
|
|
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
if (use_fib && !CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
|
2017-05-22 21:56:11 +02:00
|
|
|
continue;
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (tag && re->tag != tag)
|
2017-05-22 21:56:11 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (longer_prefix_p && ! prefix_match (longer_prefix_p, &rn->p))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* This can only be true when the afi is IPv4 */
|
|
|
|
if (supernets_only)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
addr = ntohl (rn->p.u.prefix4.s_addr);
|
|
|
|
|
|
|
|
if (IN_CLASSC (addr) && rn->p.prefixlen >= 24)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (IN_CLASSB (addr) && rn->p.prefixlen >= 16)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (IN_CLASSA (addr) && rn->p.prefixlen >= 8)
|
2017-05-10 22:33:48 +02:00
|
|
|
continue;
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (type && re->type != type)
|
2017-05-22 21:56:11 +02:00
|
|
|
continue;
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (ospf_instance_id && (re->type != ZEBRA_ROUTE_OSPF || re->instance != ospf_instance_id))
|
2017-05-22 21:56:11 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (use_json)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
if (!json_prefix)
|
|
|
|
json_prefix = json_object_new_array();
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
2017-05-22 21:56:11 +02:00
|
|
|
else
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
|
|
|
if (first)
|
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
if (afi == AFI_IP)
|
|
|
|
vty_out (vty, SHOW_ROUTE_V4_HEADER);
|
|
|
|
else
|
|
|
|
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
|
|
|
|
|
|
|
if (zvrf_id (zvrf) != VRF_DEFAULT)
|
2017-07-13 19:20:20 +02:00
|
|
|
vty_out (vty, "\nVRF %s:\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zvrf_name(zvrf));
|
2017-05-22 21:56:11 +02:00
|
|
|
|
2016-08-29 21:59:53 +02:00
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
}
|
2017-05-22 21:56:11 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
vty_show_ip_route (vty, rn, re, json_prefix);
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (json_prefix)
|
|
|
|
{
|
|
|
|
prefix2str (&rn->p, buf, sizeof buf);
|
|
|
|
json_object_object_add(json, buf, json_prefix);
|
|
|
|
json_prefix = NULL;
|
|
|
|
}
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (use_json)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%s\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
|
2017-05-22 21:56:11 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2016-08-29 21:59:53 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-06-27 17:31:57 +02:00
|
|
|
}
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
DEFUN (show_ip_nht,
|
|
|
|
show_ip_nht_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ip nht [vrf NAME]",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2016-09-23 23:17:10 +02:00
|
|
|
"IP nexthop tracking table\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 23:17:10 +02:00
|
|
|
int idx_vrf = 4;
|
2016-02-01 19:55:42 +01:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
2016-09-23 23:17:10 +02:00
|
|
|
if (argc == 5)
|
|
|
|
VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ip_nht_vrf_all,
|
|
|
|
show_ip_nht_vrf_all_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ip nht vrf all",
|
2016-02-28 23:03:27 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP nexthop tracking table\n"
|
|
|
|
VRF_ALL_CMD_HELP_STR)
|
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2016-02-28 23:03:27 +01:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2017-07-13 19:20:20 +02:00
|
|
|
vty_out (vty, "\nVRF %s:\n", zvrf_name(zvrf));
|
2016-12-05 19:43:38 +01:00
|
|
|
zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE);
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
DEFUN (show_ipv6_nht,
|
|
|
|
show_ipv6_nht_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ipv6 nht [vrf NAME]",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
2016-02-18 15:07:55 +01:00
|
|
|
IPV6_STR
|
2016-09-23 23:17:10 +02:00
|
|
|
"IPv6 nexthop tracking table\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 23:17:10 +02:00
|
|
|
int idx_vrf = 4;
|
2016-02-01 19:55:42 +01:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
2016-09-23 23:17:10 +02:00
|
|
|
if (argc == 5)
|
|
|
|
VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ipv6_nht_vrf_all,
|
|
|
|
show_ipv6_nht_vrf_all_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ipv6 nht vrf all",
|
2016-02-28 23:03:27 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 nexthop tracking table\n"
|
|
|
|
VRF_ALL_CMD_HELP_STR)
|
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2016-02-28 23:03:27 +01:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2017-07-13 19:20:20 +02:00
|
|
|
vty_out (vty, "\nVRF %s:\n", zvrf_name(zvrf));
|
2016-12-05 19:43:38 +01:00
|
|
|
zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE);
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
DEFUN (ip_nht_default_route,
|
|
|
|
ip_nht_default_route_cmd,
|
|
|
|
"ip nht resolve-via-default",
|
|
|
|
IP_STR
|
|
|
|
"Filter Next Hop tracking route resolution\n"
|
|
|
|
"Resolve via default route\n")
|
|
|
|
{
|
|
|
|
if (zebra_rnh_ip_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
zebra_rnh_ip_default_route = 1;
|
|
|
|
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_nht_default_route,
|
|
|
|
no_ip_nht_default_route_cmd,
|
|
|
|
"no ip nht resolve-via-default",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Filter Next Hop tracking route resolution\n"
|
|
|
|
"Resolve via default route\n")
|
|
|
|
{
|
|
|
|
if (!zebra_rnh_ip_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
zebra_rnh_ip_default_route = 0;
|
|
|
|
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ipv6_nht_default_route,
|
|
|
|
ipv6_nht_default_route_cmd,
|
|
|
|
"ipv6 nht resolve-via-default",
|
|
|
|
IP6_STR
|
|
|
|
"Filter Next Hop tracking route resolution\n"
|
|
|
|
"Resolve via default route\n")
|
|
|
|
{
|
|
|
|
if (zebra_rnh_ipv6_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
zebra_rnh_ipv6_default_route = 1;
|
|
|
|
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ipv6_nht_default_route,
|
|
|
|
no_ipv6_nht_default_route_cmd,
|
|
|
|
"no ipv6 nht resolve-via-default",
|
|
|
|
NO_STR
|
|
|
|
IP6_STR
|
|
|
|
"Filter Next Hop tracking route resolution\n"
|
|
|
|
"Resolve via default route\n")
|
|
|
|
{
|
|
|
|
if (!zebra_rnh_ipv6_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
zebra_rnh_ipv6_default_route = 0;
|
|
|
|
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
DEFUN (show_ip_route,
|
|
|
|
show_ip_route_cmd,
|
|
|
|
"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]",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2017-05-10 22:33:48 +02:00
|
|
|
"IP forwarding table\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"IP routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-05-22 11:40:06 +02:00
|
|
|
"Show only routes with tag\n"
|
2017-05-22 21:56:11 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
|
|
|
|
"Show route matching the specified Network/Mask pair only\n"
|
|
|
|
"Show supernet entries only\n"
|
|
|
|
FRR_IP_REDIST_HELP_STR_ZEBRA
|
|
|
|
"Open Shortest Path First (OSPFv2)\n"
|
|
|
|
"Instance ID\n"
|
|
|
|
JSON_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-05-10 22:33:48 +02:00
|
|
|
bool uf = use_fib(argv[2]);
|
2015-05-22 11:40:06 +02:00
|
|
|
struct route_table *table;
|
2017-05-22 21:56:11 +02:00
|
|
|
int vrf_all = 0;
|
2016-10-18 01:36:21 +02:00
|
|
|
route_tag_t tag = 0;
|
2016-02-28 23:03:27 +01:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2017-05-22 21:56:11 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
int uj = use_json(argc, argv);
|
|
|
|
int idx = 0;
|
|
|
|
struct prefix p;
|
|
|
|
bool longer_prefixes = false;
|
|
|
|
bool supernets_only = false;
|
|
|
|
int type = 0;
|
|
|
|
u_short ospf_instance_id = 0;
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (argv_find (argv, argc, "vrf", &idx))
|
2016-09-23 23:17:10 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
if (strmatch(argv[idx+1]->arg, "all"))
|
|
|
|
vrf_all = 1;
|
|
|
|
else
|
|
|
|
VRF_GET_ID (vrf_id, argv[idx+1]->arg);
|
2016-09-23 23:17:10 +02:00
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (argv_find (argv, argc, "tag", &idx))
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
tag = strtoul(argv[idx + 1]->arg, NULL, 10);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
else if (argv_find (argv, argc, "A.B.C.D/M", &idx))
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
str2prefix (argv[idx]->arg, &p);
|
|
|
|
longer_prefixes = true;
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
2017-05-22 21:56:11 +02:00
|
|
|
|
|
|
|
else if (argv_find (argv, argc, "supernets_only", &idx))
|
|
|
|
supernets_only = true;
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
else
|
2016-09-23 23:17:10 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
if (argv_find (argv, argc, "kernel", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
2017-05-30 20:05:46 +02:00
|
|
|
else if (argv_find (argv, argc, "babel", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
2017-05-22 21:56:11 +02:00
|
|
|
else if (argv_find (argv, argc, "connected", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "static", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "rip", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "ospf", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "isis", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "bgp", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "pim", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "eigrp", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "nhrp", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "table", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "vnc", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP, argv[idx]->text);
|
|
|
|
|
|
|
|
if (argv_find (argv, argc, "(1-65535)", &idx))
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
ospf_instance_id = strtoul(argv[idx]->arg, NULL, 10);
|
2017-05-22 21:56:11 +02:00
|
|
|
|
|
|
|
if (type < 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Unknown route type\n");
|
2017-05-22 21:56:11 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2016-09-23 23:17:10 +02:00
|
|
|
}
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (vrf_all)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
{
|
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
|
|
|
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
do_show_ip_route (vty, zvrf_name (zvrf), AFI_IP, SAFI_UNICAST, uf, uj, tag,
|
|
|
|
longer_prefixes ? &p : NULL, supernets_only, type, ospf_instance_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
vrf = vrf_lookup_by_id (vrf_id);
|
|
|
|
do_show_ip_route (vty, vrf->name, AFI_IP, SAFI_UNICAST, uf, uj, tag,
|
|
|
|
longer_prefixes ? &p : NULL, supernets_only, type, ospf_instance_id);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_route_addr,
|
|
|
|
show_ip_route_addr_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ip route [vrf NAME] A.B.C.D",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-05-22 11:40:06 +02:00
|
|
|
"Network in the IP routing table to display\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
|
|
|
ret = str2prefix_ipv4 (argv[5]->arg, &p);
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
|
|
|
else
|
2016-09-23 23:17:10 +02:00
|
|
|
{
|
|
|
|
ret = str2prefix_ipv4 (argv[3]->arg, &p);
|
|
|
|
}
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed IPv4 address\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Network not in table\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-01-22 19:12:35 +01:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_route_prefix,
|
|
|
|
show_ip_route_prefix_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ip route [vrf NAME] A.B.C.D/M",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-05-22 11:40:06 +02:00
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
|
|
|
ret = str2prefix_ipv4 (argv[5]->arg, &p);
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
|
|
|
else
|
2016-09-23 23:17:10 +02:00
|
|
|
{
|
|
|
|
ret = str2prefix_ipv4 (argv[3]->arg, &p);
|
|
|
|
}
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed IPv4 address\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn || rn->p.prefixlen != p.prefixlen)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Network not in table\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-01-22 19:12:35 +01:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-05-22 11:40:06 +02:00
|
|
|
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
|
|
|
|
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
|
|
|
|
u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
u_int32_t i;
|
2016-04-21 07:27:29 +02:00
|
|
|
u_int32_t is_ibgp;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
memset (&rib_cnt, 0, sizeof(rib_cnt));
|
|
|
|
memset (&fib_cnt, 0, sizeof(fib_cnt));
|
2016-12-05 20:05:30 +01:00
|
|
|
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
2017-06-01 13:26:25 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re)
|
2016-04-21 07:27:29 +02:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
is_ibgp = (re->type == ZEBRA_ROUTE_BGP &&
|
|
|
|
CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP));
|
2016-04-21 07:27:29 +02:00
|
|
|
|
|
|
|
rib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
|
|
|
if (is_ibgp)
|
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
rib_cnt[re->type]++;
|
2016-04-21 07:27:29 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
|
2016-04-21 07:27:29 +02:00
|
|
|
{
|
|
|
|
fib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
|
|
|
|
|
|
|
if (is_ibgp)
|
|
|
|
fib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
fib_cnt[re->type]++;
|
2016-04-21 07:27:29 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20s %s (vrf %s)\n",
|
2015-05-22 11:40:06 +02:00
|
|
|
"Route Source", "Routes", "FIB",
|
2017-06-21 05:10:57 +02:00
|
|
|
zvrf_name(((rib_table_info_t *)table->info)->zvrf));
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2016-04-21 07:27:29 +02:00
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-05-13 20:13:00 +02:00
|
|
|
if ((rib_cnt[i] > 0) ||
|
|
|
|
(i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0))
|
2016-04-21 07:27:29 +02:00
|
|
|
{
|
|
|
|
if (i == ZEBRA_ROUTE_BGP)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", "ebgp",
|
2017-06-21 05:10:57 +02:00
|
|
|
rib_cnt[ZEBRA_ROUTE_BGP],fib_cnt[ZEBRA_ROUTE_BGP]);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", "ibgp",
|
2017-06-21 05:10:57 +02:00
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP],fib_cnt[ZEBRA_ROUTE_IBGP]);
|
2016-04-21 07:27:29 +02:00
|
|
|
}
|
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", zebra_route_string(i),
|
2017-06-21 05:10:57 +02:00
|
|
|
rib_cnt[i], fib_cnt[i]);
|
2016-04-21 07:27:29 +02:00
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "------\n");
|
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
|
2017-06-21 05:10:57 +02:00
|
|
|
fib_cnt[ZEBRA_ROUTE_TOTAL]);
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Implementation of the ip route summary prefix command.
|
|
|
|
*
|
|
|
|
* This command prints the primary prefixes that have been installed by various
|
|
|
|
* protocols on the box.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct nexthop *nexthop;
|
|
|
|
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
|
|
|
|
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
|
|
|
|
u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
u_int32_t i;
|
|
|
|
int cnt;
|
|
|
|
|
|
|
|
memset (&rib_cnt, 0, sizeof(rib_cnt));
|
|
|
|
memset (&fib_cnt, 0, sizeof(fib_cnt));
|
2016-12-05 20:05:30 +01:00
|
|
|
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
2017-06-01 13:26:25 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In case of ECMP, count only once.
|
|
|
|
*/
|
|
|
|
cnt = 0;
|
2017-06-01 13:26:25 +02:00
|
|
|
for (nexthop = re->nexthop; (!cnt && nexthop); nexthop = nexthop->next)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
cnt++;
|
|
|
|
rib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
2017-06-01 13:26:25 +02:00
|
|
|
rib_cnt[re->type]++;
|
2015-05-20 02:24:41 +02:00
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
|
|
|
{
|
|
|
|
fib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
2017-06-01 13:26:25 +02:00
|
|
|
fib_cnt[re->type]++;
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->type == ZEBRA_ROUTE_BGP &&
|
|
|
|
CHECK_FLAG (re->flags, ZEBRA_FLAG_IBGP))
|
2015-05-20 02:24:41 +02:00
|
|
|
{
|
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
|
|
|
|
fib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20s %s (vrf %s)\n",
|
2015-05-22 11:40:03 +02:00
|
|
|
"Route Source", "Prefix Routes", "FIB",
|
2017-06-21 05:10:57 +02:00
|
|
|
zvrf_name(((rib_table_info_t *)table->info)->zvrf));
|
2015-05-20 02:24:41 +02:00
|
|
|
|
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
|
|
|
{
|
|
|
|
if (rib_cnt[i] > 0)
|
|
|
|
{
|
|
|
|
if (i == ZEBRA_ROUTE_BGP)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", "ebgp",
|
2015-05-20 02:24:41 +02:00
|
|
|
rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP],
|
2017-06-21 05:10:57 +02:00
|
|
|
fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP]);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", "ibgp",
|
2017-06-21 05:10:57 +02:00
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP],fib_cnt[ZEBRA_ROUTE_IBGP]);
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", zebra_route_string(i),
|
2017-06-21 05:10:57 +02:00
|
|
|
rib_cnt[i], fib_cnt[i]);
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "------\n");
|
|
|
|
vty_out (vty, "%-20s %-20d %-20d \n", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL],
|
2017-06-21 05:10:57 +02:00
|
|
|
fib_cnt[ZEBRA_ROUTE_TOTAL]);
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Show route summary. */
|
|
|
|
DEFUN (show_ip_route_summary,
|
|
|
|
show_ip_route_summary_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ip route [vrf NAME] summary",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
"Summary of all routes\n")
|
|
|
|
{
|
2008-11-05 00:45:07 +01:00
|
|
|
struct route_table *table;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
|
|
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
2008-11-05 00:45:07 +01:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-11-05 00:45:07 +01:00
|
|
|
vty_show_ip_route_summary (vty, table);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:24:41 +02:00
|
|
|
/* Show route summary prefix. */
|
|
|
|
DEFUN (show_ip_route_summary_prefix,
|
|
|
|
show_ip_route_summary_prefix_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ip route [vrf NAME] summary prefix",
|
2015-05-20 02:24:41 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-05-20 02:24:41 +02:00
|
|
|
"Summary of all routes\n"
|
|
|
|
"Prefix routes\n")
|
|
|
|
{
|
|
|
|
struct route_table *table;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2015-05-20 02:24:41 +02:00
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
|
|
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
2015-05-20 02:24:41 +02:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
vty_show_ip_route_summary_prefix (vty, table);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
DEFUN (show_ip_route_vrf_all_addr,
|
|
|
|
show_ip_route_vrf_all_addr_cmd,
|
|
|
|
"show ip route vrf all A.B.C.D",
|
2015-05-22 11:40:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2017-05-22 21:56:11 +02:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
|
|
|
"Network in the IP routing table to display\n")
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
int idx_ipv4 = 5;
|
|
|
|
int ret;
|
|
|
|
struct prefix_ipv4 p;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2017-05-22 21:56:11 +02:00
|
|
|
|
|
|
|
ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p);
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed IPv4 address\n");
|
2017-05-22 21:56:11 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
2015-05-22 11:40:03 +02:00
|
|
|
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn)
|
|
|
|
continue;
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
|
|
|
|
|
|
|
route_unlock_node (rn);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ip_route_vrf_all_prefix,
|
|
|
|
show_ip_route_vrf_all_prefix_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ip route vrf all A.B.C.D/M",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv4_prefixlen = 5;
|
2015-05-22 11:40:06 +02:00
|
|
|
int ret;
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-09-23 21:26:31 +02:00
|
|
|
ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p);
|
2015-05-22 11:40:06 +02:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed IPv4 address\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
2015-05-22 11:40:06 +02:00
|
|
|
(table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn)
|
|
|
|
continue;
|
|
|
|
if (rn->p.prefixlen != p.prefixlen)
|
|
|
|
{
|
|
|
|
route_unlock_node (rn);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-01-22 19:12:35 +01:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ip_route_vrf_all_summary,
|
|
|
|
show_ip_route_vrf_all_summary_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ip route vrf all summary ",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
|
|
|
"Summary of all routes\n")
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ip_route_vrf_all_summary_prefix,
|
|
|
|
show_ip_route_vrf_all_summary_prefix_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ip route vrf all summary prefix",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
2015-05-22 11:40:06 +02:00
|
|
|
"Summary of all routes\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
"Prefix routes\n")
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-11-13 03:52:32 +01:00
|
|
|
/* Write static route configuration. */
|
2015-05-22 11:40:06 +02:00
|
|
|
static int
|
2016-11-13 03:52:32 +01:00
|
|
|
static_config (struct vty *vty, afi_t afi, safi_t safi, const char *cmd)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
struct route_node *rn;
|
2015-10-30 13:52:29 +01:00
|
|
|
struct static_route *si;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct route_table *stable;
|
2016-12-05 19:43:38 +01:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2016-11-13 03:52:32 +01:00
|
|
|
char buf[SRCDEST2STR_BUFFER];
|
2016-04-27 22:22:13 +02:00
|
|
|
int write =0;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2016-12-05 19:43:38 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
if (!(zvrf = vrf->info))
|
|
|
|
continue;
|
2016-11-13 03:52:32 +01:00
|
|
|
if ((stable = zvrf->stable[afi][safi]) == NULL)
|
2015-05-22 11:40:06 +02:00
|
|
|
continue;
|
|
|
|
|
2016-11-13 03:52:32 +01:00
|
|
|
for (rn = route_top (stable); rn; rn = srcdest_route_next (rn))
|
2015-05-22 11:40:06 +02:00
|
|
|
for (si = rn->info; si; si = si->next)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-11-13 03:52:32 +01:00
|
|
|
vty_out (vty, "%s %s", cmd, srcdest_rnode2str (rn, buf, sizeof buf));
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
switch (si->type)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2015-05-22 11:40:06 +02:00
|
|
|
case STATIC_IPV4_GATEWAY:
|
2015-10-30 13:52:29 +01:00
|
|
|
vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
2016-11-13 03:52:32 +01:00
|
|
|
case STATIC_IPV6_GATEWAY:
|
2017-06-10 21:42:13 +02:00
|
|
|
vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, sizeof buf));
|
2016-11-13 03:52:32 +01:00
|
|
|
break;
|
2015-12-04 18:34:42 +01:00
|
|
|
case STATIC_IFINDEX:
|
2016-05-04 02:04:43 +02:00
|
|
|
vty_out (vty, " %s", si->ifname);
|
2015-05-22 11:40:06 +02:00
|
|
|
break;
|
2016-10-25 21:38:04 +02:00
|
|
|
case STATIC_BLACKHOLE:
|
2015-05-22 11:40:06 +02:00
|
|
|
vty_out (vty, " Null0");
|
|
|
|
break;
|
2016-11-13 03:52:32 +01:00
|
|
|
case STATIC_IPV6_GATEWAY_IFINDEX:
|
|
|
|
vty_out (vty, " %s %s",
|
2017-06-10 21:42:13 +02:00
|
|
|
inet_ntop (AF_INET6, &si->addr.ipv6, buf, sizeof buf),
|
2016-11-13 03:52:32 +01:00
|
|
|
ifindex2ifname (si->ifindex, si->vrf_id));
|
|
|
|
break;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2016-10-25 21:38:04 +02:00
|
|
|
/* flags are incompatible with STATIC_BLACKHOLE */
|
|
|
|
if (si->type != STATIC_BLACKHOLE)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
|
|
|
|
vty_out (vty, " %s", "reject");
|
|
|
|
|
|
|
|
if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
|
|
|
|
vty_out (vty, " %s", "blackhole");
|
2015-05-22 11:40:03 +02:00
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
if (si->tag)
|
2016-10-25 22:29:52 +02:00
|
|
|
vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
|
|
|
|
vty_out (vty, " %d", si->distance);
|
|
|
|
|
|
|
|
if (si->vrf_id != VRF_DEFAULT)
|
2016-11-13 03:52:32 +01:00
|
|
|
vty_out (vty, " vrf %s", zvrf_name (zvrf));
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2016-10-25 22:29:52 +02:00
|
|
|
/* Label information */
|
|
|
|
if (si->snh_label.num_labels)
|
|
|
|
vty_out (vty, " label %s",
|
|
|
|
mpls_label2str (si->snh_label.num_labels,
|
2017-05-10 15:42:00 +02:00
|
|
|
si->snh_label.label, buf, sizeof buf, 0));
|
2016-10-25 22:29:52 +02:00
|
|
|
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
write = 1;
|
2015-05-22 11:40:03 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
return write;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* General fucntion for IPv6 static route. */
|
2016-10-18 01:36:21 +02:00
|
|
|
int
|
2015-05-22 11:40:06 +02:00
|
|
|
static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
|
2016-11-24 17:10:19 +01:00
|
|
|
const char *src_str,
|
2016-10-18 01:36:21 +02:00
|
|
|
const char *gate_str, const char *ifname,
|
|
|
|
const char *flag_str, const char *tag_str,
|
|
|
|
const char *distance_str, const char *vrf_id_str,
|
|
|
|
const char *label_str)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
|
|
|
int ret;
|
2015-05-22 11:40:06 +02:00
|
|
|
u_char distance;
|
2016-11-24 17:10:19 +01:00
|
|
|
struct prefix p, src;
|
|
|
|
struct prefix_ipv6 *src_p = NULL;
|
2015-05-22 11:40:06 +02:00
|
|
|
struct in6_addr *gate = NULL;
|
|
|
|
struct in6_addr gate_addr;
|
2016-10-25 21:38:04 +02:00
|
|
|
u_char type = STATIC_BLACKHOLE;
|
2015-05-22 11:40:06 +02:00
|
|
|
u_char flag = 0;
|
2016-10-18 01:36:21 +02:00
|
|
|
route_tag_t tag = 0;
|
2015-12-04 18:34:42 +01:00
|
|
|
unsigned int ifindex = 0;
|
|
|
|
struct interface *ifp = NULL;
|
2016-04-27 22:22:13 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2016-10-18 01:36:21 +02:00
|
|
|
struct static_nh_label snh_label;
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
ret = str2prefix (dest_str, &p);
|
2015-05-22 11:40:03 +02:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed address\n");
|
2015-05-22 11:40:03 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-11-24 17:10:19 +01:00
|
|
|
if (src_str)
|
|
|
|
{
|
|
|
|
ret = str2prefix (src_str, &src);
|
|
|
|
if (ret <= 0 || src.family != AF_INET6)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed source address\n");
|
2016-11-24 17:10:19 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
src_p = (struct prefix_ipv6*)&src;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
/* Apply mask for given prefix. */
|
|
|
|
apply_mask (&p);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
/* Administrative distance. */
|
|
|
|
if (distance_str)
|
|
|
|
distance = atoi (distance_str);
|
|
|
|
else
|
|
|
|
distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-10-25 22:29:52 +02:00
|
|
|
/* tag */
|
|
|
|
if (tag_str)
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
tag = strtoul(tag_str, NULL, 10);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
|
|
|
/* When gateway is valid IPv6 addrees, then gate is treated as
|
|
|
|
nexthop address other case gate is treated as interface name. */
|
|
|
|
ret = inet_pton (AF_INET6, gate_str, &gate_addr);
|
|
|
|
|
2016-03-30 02:41:59 +02:00
|
|
|
/* VRF id */
|
2016-12-05 19:43:38 +01:00
|
|
|
zvrf = zebra_vrf_lookup_by_name (vrf_id_str);
|
2016-04-27 22:22:13 +02:00
|
|
|
|
|
|
|
if (!zvrf)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% vrf %s is not defined\n", vrf_id_str);
|
2016-04-27 22:22:13 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2016-03-30 02:41:59 +02:00
|
|
|
|
2016-10-18 01:36:21 +02:00
|
|
|
/* Labels */
|
|
|
|
memset (&snh_label, 0, sizeof (struct static_nh_label));
|
|
|
|
if (label_str)
|
|
|
|
{
|
2016-10-25 22:29:52 +02:00
|
|
|
if (!mpls_enabled)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty,
|
|
|
|
"%% MPLS not turned on in kernel, ignoring command\n");
|
2016-10-25 22:29:52 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2017-05-31 23:27:08 +02:00
|
|
|
int rc = mpls_str2label (label_str, &snh_label.num_labels,
|
|
|
|
snh_label.label);
|
|
|
|
if (rc < 0)
|
2016-10-18 01:36:21 +02:00
|
|
|
{
|
2017-05-31 23:27:08 +02:00
|
|
|
switch (rc) {
|
|
|
|
case -1:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed label(s)\n");
|
2017-05-31 23:27:08 +02:00
|
|
|
break;
|
|
|
|
case -2:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Cannot use reserved label(s) (%d-%d)\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
MPLS_MIN_RESERVED_LABEL,MPLS_MAX_RESERVED_LABEL);
|
2017-05-31 23:27:08 +02:00
|
|
|
break;
|
|
|
|
case -3:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Too many labels. Enter %d or fewer\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
MPLS_MAX_LABELS);
|
2017-05-31 23:27:08 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-10-18 01:36:21 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-25 21:38:04 +02:00
|
|
|
/* Null0 static route. */
|
|
|
|
if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
|
|
|
|
{
|
|
|
|
if (flag_str)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% can not have flag %s with Null0\n", flag_str);
|
2016-10-25 21:38:04 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
if (add_cmd)
|
2017-06-14 09:23:36 +02:00
|
|
|
static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, NULL, ifindex, ifname,
|
2016-10-25 21:38:04 +02:00
|
|
|
ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
|
|
|
|
else
|
2017-06-14 09:23:36 +02:00
|
|
|
static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, NULL, ifindex, tag,
|
2016-10-25 21:38:04 +02:00
|
|
|
distance, zvrf, &snh_label);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Route flags */
|
|
|
|
if (flag_str) {
|
|
|
|
switch(flag_str[0]) {
|
|
|
|
case 'r':
|
|
|
|
case 'R': /* XXX */
|
|
|
|
SET_FLAG (flag, ZEBRA_FLAG_REJECT);
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
case 'B': /* XXX */
|
|
|
|
SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
|
|
|
|
break;
|
|
|
|
default:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed flag %s \n", flag_str);
|
2016-10-25 21:38:04 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-25 22:29:52 +02:00
|
|
|
if (ifname)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
|
|
|
/* When ifname is specified. It must be come with gateway
|
|
|
|
address. */
|
|
|
|
if (ret != 1)
|
2016-10-18 01:36:21 +02:00
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed address\n");
|
2016-10-18 01:36:21 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-12-04 18:34:42 +01:00
|
|
|
type = STATIC_IPV6_GATEWAY_IFINDEX;
|
2015-05-22 11:40:06 +02:00
|
|
|
gate = &gate_addr;
|
2017-03-11 13:27:15 +01:00
|
|
|
ifp = if_lookup_by_name (ifname, zvrf_id (zvrf));
|
2015-12-04 18:34:42 +01:00
|
|
|
if (!ifp)
|
2016-10-18 01:36:21 +02:00
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed Interface name %s\n", ifname);
|
2016-10-18 01:36:21 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-12-04 18:34:42 +01:00
|
|
|
ifindex = ifp->ifindex;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ret == 1)
|
2016-10-18 01:36:21 +02:00
|
|
|
{
|
|
|
|
type = STATIC_IPV6_GATEWAY;
|
|
|
|
gate = &gate_addr;
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
else
|
2016-10-18 01:36:21 +02:00
|
|
|
{
|
|
|
|
type = STATIC_IFINDEX;
|
2017-03-11 13:27:15 +01:00
|
|
|
ifp = if_lookup_by_name (gate_str, zvrf_id (zvrf));
|
2016-10-18 01:36:21 +02:00
|
|
|
if (!ifp)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Malformed Interface name %s\n", gate_str);
|
2016-05-10 14:49:28 +02:00
|
|
|
ifindex = IFINDEX_DELETED;
|
2016-10-18 01:36:21 +02:00
|
|
|
}
|
2016-05-10 14:49:28 +02:00
|
|
|
else
|
2016-10-18 01:36:21 +02:00
|
|
|
ifindex = ifp->ifindex;
|
|
|
|
ifname = gate_str;
|
|
|
|
}
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
if (add_cmd)
|
2016-11-24 17:10:19 +01:00
|
|
|
static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
|
2016-10-18 01:36:21 +02:00
|
|
|
ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
|
2015-05-22 11:40:06 +02:00
|
|
|
else
|
2016-11-24 17:10:19 +01:00
|
|
|
static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
|
2016-10-18 01:36:21 +02:00
|
|
|
ifindex, tag, distance, zvrf, &snh_label);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
DEFUN (ipv6_route,
|
|
|
|
ipv6_route_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-22 11:40:06 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
2016-10-25 21:38:04 +02:00
|
|
|
"Null interface\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Set tag for this route\n"
|
2016-09-26 15:23:26 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 2;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6_ifname;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[3]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[4]->arg;
|
|
|
|
idx_ipv6_ifname = 5;
|
|
|
|
idx_curr = 6;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6_ifname = 3;
|
|
|
|
idx_curr = 4;
|
|
|
|
}
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
return static_ipv6_func (vty, 1,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 15:23:26 +02:00
|
|
|
argv[idx_ipv6_ifname]->arg,
|
|
|
|
NULL, NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
DEFUN (ipv6_route_flags,
|
|
|
|
ipv6_route_flags_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-22 11:40:06 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Set tag for this route\n"
|
|
|
|
"Tag value\n"
|
2016-09-26 15:23:26 +02:00
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 2;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6_ifname;
|
|
|
|
int idx_reject_blackhole;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[3]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[4]->arg;
|
|
|
|
idx_ipv6_ifname = 5;
|
|
|
|
idx_reject_blackhole = 6;
|
|
|
|
idx_curr = 7;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6_ifname = 3;
|
|
|
|
idx_reject_blackhole = 4;
|
|
|
|
idx_curr = 5;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 15:23:26 +02:00
|
|
|
|
|
|
|
return static_ipv6_func (vty, 1,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 15:23:26 +02:00
|
|
|
argv[idx_ipv6_ifname]->arg,
|
|
|
|
NULL,
|
|
|
|
argv[idx_reject_blackhole]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2003-07-15 14:52:22 +02:00
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
DEFUN (ipv6_route_ifname,
|
|
|
|
ipv6_route_ifname_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-22 11:40:06 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
|
|
|
"Set tag for this route\n"
|
|
|
|
"Tag value\n"
|
2016-09-26 15:23:26 +02:00
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 2;
|
|
|
|
int idx_ipv6 = 3;
|
|
|
|
int idx_interface = 4;
|
2016-09-26 15:23:26 +02:00
|
|
|
int idx_curr = 5;
|
2016-11-24 17:10:19 +01:00
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[3]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[4]->arg;
|
|
|
|
idx_ipv6 = 5;
|
|
|
|
idx_interface = 6;
|
|
|
|
idx_curr = 7;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6 = 3;
|
|
|
|
idx_interface = 4;
|
|
|
|
idx_curr = 5;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 15:23:26 +02:00
|
|
|
|
|
|
|
return static_ipv6_func (vty, 1,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 15:23:26 +02:00
|
|
|
argv[idx_ipv6]->arg,
|
|
|
|
argv[idx_interface]->arg,
|
|
|
|
NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-20 02:24:41 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 15:23:26 +02:00
|
|
|
DEFUN (ipv6_route_ifname_flags,
|
|
|
|
ipv6_route_ifname_flags_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-22 11:40:06 +02:00
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Set tag for this route\n"
|
|
|
|
"Tag value\n"
|
2016-09-26 15:23:26 +02:00
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 2;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6;
|
|
|
|
int idx_interface;
|
|
|
|
int idx_reject_blackhole;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[3]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[4]->arg;
|
|
|
|
idx_ipv6 = 5;
|
|
|
|
idx_interface = 6;
|
|
|
|
idx_reject_blackhole = 7;
|
|
|
|
idx_curr = 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6 = 3;
|
|
|
|
idx_interface = 4;
|
|
|
|
idx_reject_blackhole = 5;
|
|
|
|
idx_curr = 6;
|
|
|
|
}
|
2016-09-26 15:23:26 +02:00
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 15:23:26 +02:00
|
|
|
|
|
|
|
return static_ipv6_func (vty, 1,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 15:23:26 +02:00
|
|
|
argv[idx_ipv6]->arg,
|
|
|
|
argv[idx_interface]->arg,
|
|
|
|
argv[idx_reject_blackhole]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
2003-07-15 14:52:22 +02:00
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
DEFUN (no_ipv6_route,
|
|
|
|
no_ipv6_route_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2003-05-25 21:21:25 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2003-05-25 21:21:25 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
2016-10-25 21:38:04 +02:00
|
|
|
"Null interface\n"
|
2015-05-20 02:46:33 +02:00
|
|
|
"Set tag for this route\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Tag value\n"
|
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 3;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6_ifname;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[4]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[5]->arg;
|
|
|
|
idx_ipv6_ifname = 6;
|
|
|
|
idx_curr = 7;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6_ifname = 4;
|
|
|
|
idx_curr = 5;
|
|
|
|
}
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2003-05-25 21:21:25 +02:00
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
return static_ipv6_func (vty, 0,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 16:01:50 +02:00
|
|
|
argv[idx_ipv6_ifname]->arg,
|
|
|
|
NULL, NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-20 02:46:33 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
DEFUN (no_ipv6_route_flags,
|
|
|
|
no_ipv6_route_flags_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-20 02:46:33 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-20 02:46:33 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Set tag for this route\n"
|
|
|
|
"Tag value\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 3;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6_ifname;
|
|
|
|
int idx_reject_blackhole;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[4]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[5]->arg;
|
|
|
|
idx_ipv6_ifname = 6;
|
|
|
|
idx_reject_blackhole = 7;
|
|
|
|
idx_curr = 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6_ifname = 4;
|
|
|
|
idx_reject_blackhole = 5;
|
|
|
|
idx_curr = 6;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 16:01:50 +02:00
|
|
|
|
|
|
|
return static_ipv6_func (vty, 0,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 16:01:50 +02:00
|
|
|
argv[idx_ipv6_ifname]->arg,
|
|
|
|
NULL,
|
|
|
|
argv[idx_reject_blackhole]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-20 02:46:33 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
DEFUN (no_ipv6_route_ifname,
|
|
|
|
no_ipv6_route_ifname_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-20 02:46:33 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-20 02:46:33 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
|
|
|
"Set tag for this route\n"
|
|
|
|
"Tag value\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 3;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6;
|
|
|
|
int idx_interface;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[4]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[5]->arg;
|
|
|
|
idx_ipv6 = 6;
|
|
|
|
idx_interface = 7;
|
|
|
|
idx_curr = 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6 = 4;
|
|
|
|
idx_interface = 5;
|
|
|
|
idx_curr = 6;
|
|
|
|
}
|
2003-05-25 21:21:25 +02:00
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 16:01:50 +02:00
|
|
|
|
|
|
|
return static_ipv6_func (vty, 0,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 16:01:50 +02:00
|
|
|
argv[idx_ipv6]->arg,
|
|
|
|
argv[idx_interface]->arg,
|
|
|
|
NULL,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2015-05-20 02:46:33 +02:00
|
|
|
}
|
|
|
|
|
2016-09-26 16:01:50 +02:00
|
|
|
DEFUN (no_ipv6_route_ifname_flags,
|
|
|
|
no_ipv6_route_ifname_flags_cmd,
|
2016-11-24 17:10:19 +01:00
|
|
|
"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]",
|
2015-05-20 02:46:33 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Establish static routes\n"
|
|
|
|
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
|
2016-11-24 17:10:19 +01:00
|
|
|
"IPv6 source-dest route\n"
|
|
|
|
"IPv6 source prefix\n"
|
2015-05-20 02:46:33 +02:00
|
|
|
"IPv6 gateway address\n"
|
|
|
|
"IPv6 gateway interface name\n"
|
|
|
|
"Emit an ICMP unreachable when matched\n"
|
|
|
|
"Silently discard pkts when matched\n"
|
|
|
|
"Set tag for this route\n"
|
|
|
|
"Tag value\n"
|
2015-05-22 11:40:06 +02:00
|
|
|
"Distance value for this prefix\n"
|
2017-07-05 20:30:36 +02:00
|
|
|
VRF_CMD_HELP_STR)
|
2015-05-20 02:46:33 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 3;
|
2016-11-24 17:10:19 +01:00
|
|
|
int idx_ipv6;
|
|
|
|
int idx_interface;
|
|
|
|
int idx_reject_blackhole;
|
|
|
|
int idx_curr;
|
|
|
|
char *src, *tag, *distance, *vrf;
|
|
|
|
|
2017-06-26 20:15:19 +02:00
|
|
|
if (strmatch(argv[4]->text, "from"))
|
2016-11-24 17:10:19 +01:00
|
|
|
{
|
|
|
|
src = argv[5]->arg;
|
|
|
|
idx_ipv6 = 6;
|
|
|
|
idx_interface = 7;
|
|
|
|
idx_reject_blackhole = 8;
|
|
|
|
idx_curr = 9;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
src = NULL;
|
|
|
|
idx_ipv6 = 4;
|
|
|
|
idx_interface = 5;
|
|
|
|
idx_reject_blackhole = 6;
|
|
|
|
idx_curr = 7;
|
|
|
|
}
|
2016-09-26 16:01:50 +02:00
|
|
|
|
|
|
|
tag = distance = vrf = NULL;
|
2016-10-18 01:36:21 +02:00
|
|
|
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
|
2016-09-26 16:01:50 +02:00
|
|
|
|
|
|
|
return static_ipv6_func (vty, 0,
|
|
|
|
argv[idx_ipv6_prefixlen]->arg,
|
2016-11-24 17:10:19 +01:00
|
|
|
src,
|
2016-09-26 16:01:50 +02:00
|
|
|
argv[idx_ipv6]->arg,
|
|
|
|
argv[idx_interface]->arg,
|
|
|
|
argv[idx_reject_blackhole]->arg,
|
2016-10-18 01:36:21 +02:00
|
|
|
tag, distance, vrf, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ipv6_route,
|
|
|
|
show_ipv6_route_cmd,
|
2017-05-22 21:56:11 +02:00
|
|
|
"show ipv6 <fib|route> [vrf NAME] [tag (1-4294967295)|X:X::X:X/M longer-prefixes|" FRR_IP6_REDIST_STR_ZEBRA "] [json]",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2017-05-22 21:56:11 +02:00
|
|
|
"IP forwarding table\n"
|
|
|
|
"IP routing table\n"
|
2016-09-28 06:47:43 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2017-05-22 21:56:11 +02:00
|
|
|
"Show only routes with tag\n"
|
|
|
|
"Tag value\n"
|
|
|
|
"IPv6 prefix\n"
|
|
|
|
"Show route matching the specified Network/Mask pair only\n"
|
|
|
|
FRR_IP6_REDIST_HELP_STR_ZEBRA
|
|
|
|
JSON_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
bool uf = use_fib(argv[2]);
|
2002-12-13 21:15:29 +01:00
|
|
|
struct route_table *table;
|
2017-05-22 21:56:11 +02:00
|
|
|
int vrf_all = 0;
|
|
|
|
route_tag_t tag = 0;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2017-05-22 21:56:11 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
int uj = use_json(argc, argv);
|
|
|
|
int idx = 0;
|
|
|
|
struct prefix p;
|
|
|
|
bool longer_prefixes = false;
|
|
|
|
bool supernets_only = false;
|
|
|
|
int type = 0;
|
2016-05-04 15:44:43 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (argv_find (argv, argc, "vrf", &idx))
|
|
|
|
{
|
|
|
|
if (strmatch(argv[idx+1]->arg, "all"))
|
|
|
|
vrf_all = 1;
|
|
|
|
else
|
|
|
|
VRF_GET_ID (vrf_id, argv[idx+1]->arg);
|
|
|
|
}
|
2016-09-28 06:47:43 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (argv_find (argv, argc, "tag", &idx))
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
tag = strtoul(argv[idx + 1]->arg, NULL, 10);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
else if (argv_find (argv, argc, "X:X::X:X/M", &idx))
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
str2prefix (argv[idx]->arg, &p);
|
|
|
|
longer_prefixes = true;
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
else
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
if (argv_find (argv, argc, "kernel", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
2017-05-30 20:05:46 +02:00
|
|
|
else if (argv_find (argv, argc, "babel", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
2017-05-22 21:56:11 +02:00
|
|
|
else if (argv_find (argv, argc, "connected", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "static", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "ripng", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "ospf6", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "isis", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "bgp", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "nhrp", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "table", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
else if (argv_find (argv, argc, "vnc", &idx))
|
|
|
|
type = proto_redistnum (AFI_IP6, argv[idx]->text);
|
|
|
|
|
|
|
|
if (type < 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Unknown route type\n");
|
2017-05-22 21:56:11 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
2016-08-29 21:59:53 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
if (vrf_all)
|
|
|
|
{
|
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2016-08-29 21:59:53 +02:00
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
|
|
|
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
2016-08-29 21:59:53 +02:00
|
|
|
|
2017-05-22 21:56:11 +02:00
|
|
|
do_show_ip_route (vty, zvrf_name (zvrf), AFI_IP6, SAFI_UNICAST, uf, uj, tag,
|
|
|
|
longer_prefixes ? &p : NULL, supernets_only, type, 0);
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-05-22 21:56:11 +02:00
|
|
|
vrf = vrf_lookup_by_id (vrf_id);
|
|
|
|
do_show_ip_route (vty, vrf->name, AFI_IP6, SAFI_UNICAST, uf, uj, tag,
|
|
|
|
longer_prefixes ? &p : NULL, supernets_only, type, 0);
|
2016-08-29 21:59:53 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ipv6_route_addr,
|
|
|
|
show_ipv6_route_addr_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ipv6 route [vrf NAME] X:X::X:X",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
"IPv6 Address\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct prefix_ipv6 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
|
|
|
ret = str2prefix_ipv6 (argv[5]->arg, &p);
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
|
|
|
else
|
2016-09-23 23:17:10 +02:00
|
|
|
{
|
|
|
|
ret = str2prefix_ipv6 (argv[3]->arg, &p);
|
|
|
|
}
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Malformed IPv6 address\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Network not in table\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:08:40 +02:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ipv6_route_prefix,
|
|
|
|
show_ipv6_route_prefix_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ipv6 route [vrf NAME] X:X::X:X/M",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
"IPv6 prefix\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct prefix_ipv6 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-02-28 23:03:27 +01:00
|
|
|
{
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
|
|
|
ret = str2prefix_ipv6 (argv[5]->arg, &p);
|
2016-02-28 23:03:27 +01:00
|
|
|
}
|
|
|
|
else
|
2016-09-23 23:17:10 +02:00
|
|
|
ret = str2prefix_ipv6 (argv[3]->arg, &p);
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Malformed IPv6 prefix\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn || rn->p.prefixlen != p.prefixlen)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%% Network not in table\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:08:40 +02:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2008-11-05 00:45:07 +01:00
|
|
|
/* Show route summary. */
|
|
|
|
DEFUN (show_ipv6_route_summary,
|
|
|
|
show_ipv6_route_summary_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ipv6 route [vrf NAME] summary",
|
2008-11-05 00:45:07 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2008-11-05 00:45:07 +01:00
|
|
|
"Summary of all IPv6 routes\n")
|
|
|
|
{
|
|
|
|
struct route_table *table;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2008-11-05 00:45:07 +01:00
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
2008-11-05 00:45:07 +01:00
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
2008-11-05 00:45:07 +01:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
vty_show_ip_route_summary (vty, table);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2015-05-20 02:24:41 +02:00
|
|
|
/* Show ipv6 route summary prefix. */
|
|
|
|
DEFUN (show_ipv6_route_summary_prefix,
|
|
|
|
show_ipv6_route_summary_prefix_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ipv6 route [vrf NAME] summary prefix",
|
2015-05-20 02:24:41 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
2015-05-20 02:24:41 +02:00
|
|
|
"Summary of all IPv6 routes\n"
|
|
|
|
"Prefix routes\n")
|
|
|
|
{
|
|
|
|
struct route_table *table;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2015-05-20 02:24:41 +02:00
|
|
|
|
2016-09-24 00:12:11 +02:00
|
|
|
if (strmatch(argv[3]->text, "vrf"))
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
2015-05-20 02:24:41 +02:00
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
2015-05-20 02:24:41 +02:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
vty_show_ip_route_summary_prefix (vty, table);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2011-11-26 18:59:32 +01:00
|
|
|
/*
|
|
|
|
* Show IPv6 mroute command.Used to dump
|
|
|
|
* the Multicast routing table.
|
|
|
|
*/
|
|
|
|
DEFUN (show_ipv6_mroute,
|
|
|
|
show_ipv6_mroute_cmd,
|
2016-09-23 23:17:10 +02:00
|
|
|
"show ipv6 mroute [vrf NAME]",
|
2011-11-26 18:59:32 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2016-09-23 23:17:10 +02:00
|
|
|
"IPv6 Multicast routing table\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
2011-11-26 18:59:32 +01:00
|
|
|
{
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2011-11-26 18:59:32 +01:00
|
|
|
int first = 1;
|
2015-05-22 11:40:03 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
2017-05-04 04:49:50 +02:00
|
|
|
if (argc == 5)
|
2016-09-23 23:17:10 +02:00
|
|
|
VRF_GET_ID (vrf_id, argv[4]->arg);
|
2011-11-26 18:59:32 +01:00
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
|
2011-11-26 18:59:32 +01:00
|
|
|
if (! table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
/* Show all IPv6 route. */
|
2016-12-05 20:05:30 +01:00
|
|
|
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
2017-06-01 13:26:25 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re)
|
2011-11-26 18:59:32 +01:00
|
|
|
{
|
|
|
|
if (first)
|
|
|
|
{
|
2011-11-27 15:39:40 +01:00
|
|
|
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
2011-11-26 18:59:32 +01:00
|
|
|
first = 0;
|
|
|
|
}
|
2017-06-01 13:26:25 +02:00
|
|
|
vty_show_ip_route (vty, rn, re, NULL);
|
2011-11-26 18:59:32 +01:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ipv6_route_vrf_all_addr,
|
|
|
|
show_ipv6_route_vrf_all_addr_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ipv6 route vrf all X:X::X:X",
|
2015-05-22 11:40:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
|
|
|
"IPv6 Address\n")
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6 = 5;
|
2015-05-22 11:40:03 +02:00
|
|
|
int ret;
|
|
|
|
struct prefix_ipv6 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-09-23 21:26:31 +02:00
|
|
|
ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p);
|
2015-05-22 11:40:03 +02:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Malformed IPv6 address\n");
|
2015-05-22 11:40:03 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-10-30 00:44:04 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
2015-05-22 11:40:03 +02:00
|
|
|
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn)
|
|
|
|
continue;
|
|
|
|
|
2015-05-23 10:08:40 +02:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ipv6_route_vrf_all_prefix,
|
|
|
|
show_ipv6_route_vrf_all_prefix_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ipv6 route vrf all X:X::X:X/M",
|
2015-05-22 11:40:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
|
|
|
"IPv6 prefix\n")
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-09-23 21:26:31 +02:00
|
|
|
int idx_ipv6_prefixlen = 5;
|
2015-05-22 11:40:03 +02:00
|
|
|
int ret;
|
|
|
|
struct prefix_ipv6 p;
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-09-23 21:26:31 +02:00
|
|
|
ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p);
|
2015-05-22 11:40:03 +02:00
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Malformed IPv6 prefix\n");
|
2015-05-22 11:40:03 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2016-10-30 00:44:04 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
2015-05-22 11:40:03 +02:00
|
|
|
(table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rn = route_node_match (table, (struct prefix *) &p);
|
|
|
|
if (! rn)
|
|
|
|
continue;
|
|
|
|
if (rn->p.prefixlen != p.prefixlen)
|
|
|
|
{
|
|
|
|
route_unlock_node (rn);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-05-23 10:08:40 +02:00
|
|
|
vty_show_ip_route_detail (vty, rn, 0);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
|
|
|
route_unlock_node (rn);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ipv6_route_vrf_all_summary,
|
|
|
|
show_ipv6_route_vrf_all_summary_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ipv6 route vrf all summary",
|
2015-05-22 11:40:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
|
|
|
"Summary of all IPv6 routes\n")
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-10-30 00:44:04 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2016-10-29 18:37:11 +02:00
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2015-05-22 11:40:03 +02:00
|
|
|
vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ipv6_mroute_vrf_all,
|
|
|
|
show_ipv6_mroute_vrf_all_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ipv6 mroute vrf all",
|
2015-05-22 11:40:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 Multicast routing table\n"
|
|
|
|
VRF_ALL_CMD_HELP_STR)
|
|
|
|
{
|
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
int first = 1;
|
|
|
|
|
2016-10-30 00:44:04 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL ||
|
2017-04-04 02:14:18 +02:00
|
|
|
(table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
|
2015-05-22 11:40:03 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Show all IPv6 route. */
|
2016-12-05 20:05:30 +01:00
|
|
|
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
2017-06-01 13:26:25 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re)
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
|
|
|
first = 0;
|
|
|
|
}
|
2017-06-01 13:26:25 +02:00
|
|
|
vty_show_ip_route (vty, rn, re, NULL);
|
2015-05-22 11:40:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
DEFUN (show_ipv6_route_vrf_all_summary_prefix,
|
|
|
|
show_ipv6_route_vrf_all_summary_prefix_cmd,
|
2016-09-26 17:51:10 +02:00
|
|
|
"show ipv6 route vrf all summary prefix",
|
2015-05-22 11:40:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IPv6 routing table\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
VRF_ALL_CMD_HELP_STR
|
2015-05-22 11:40:03 +02:00
|
|
|
"Summary of all IPv6 routes\n"
|
2016-02-28 23:03:27 +01:00
|
|
|
"Prefix routes\n")
|
2015-05-22 11:40:03 +02:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
2015-05-22 11:40:03 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-10-30 00:44:04 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2016-10-29 18:37:11 +02:00
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2015-05-22 11:40:03 +02:00
|
|
|
vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-08-26 14:21:40 +02:00
|
|
|
DEFUN (allow_external_route_update,
|
|
|
|
allow_external_route_update_cmd,
|
|
|
|
"allow-external-route-update",
|
2017-03-12 01:06:09 +01:00
|
|
|
"Allow FRR routes to be overwritten by external processes\n")
|
2015-08-26 14:21:40 +02:00
|
|
|
{
|
|
|
|
allow_delete = 1;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_allow_external_route_update,
|
|
|
|
no_allow_external_route_update_cmd,
|
|
|
|
"no allow-external-route-update",
|
2017-03-12 01:06:09 +01:00
|
|
|
NO_STR
|
|
|
|
"Allow FRR routes to be overwritten by external processes\n")
|
2015-08-26 14:21:40 +02:00
|
|
|
{
|
|
|
|
allow_delete = 0;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
/* show vrf */
|
|
|
|
DEFUN (show_vrf,
|
|
|
|
show_vrf_cmd,
|
|
|
|
"show vrf",
|
|
|
|
SHOW_STR
|
|
|
|
"VRF\n")
|
|
|
|
{
|
2016-10-29 02:26:04 +02:00
|
|
|
struct vrf *vrf;
|
2016-02-01 19:55:42 +01:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-10-30 00:30:57 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
2016-02-01 19:55:42 +01:00
|
|
|
{
|
2016-12-05 19:43:38 +01:00
|
|
|
if (!(zvrf = vrf->info))
|
|
|
|
continue;
|
|
|
|
if (!zvrf_id (zvrf))
|
2016-02-01 19:55:42 +01:00
|
|
|
continue;
|
|
|
|
|
2016-10-30 22:50:26 +01:00
|
|
|
vty_out (vty, "vrf %s ", zvrf_name (zvrf));
|
|
|
|
if (zvrf_id (zvrf) == VRF_UNKNOWN)
|
2016-05-03 19:54:01 +02:00
|
|
|
vty_out (vty, "inactive");
|
|
|
|
else
|
2016-10-30 22:50:26 +01:00
|
|
|
vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id);
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Static ip route configuration write function. */
|
2005-06-28 19:17:12 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
zebra_ip_config (struct vty *vty)
|
|
|
|
{
|
|
|
|
int write = 0;
|
|
|
|
|
2016-11-13 03:52:32 +01:00
|
|
|
write += static_config (vty, AFI_IP, SAFI_UNICAST, "ip route");
|
|
|
|
write += static_config (vty, AFI_IP, SAFI_MULTICAST, "ip mroute");
|
|
|
|
write += static_config (vty, AFI_IP6, SAFI_UNICAST, "ipv6 route");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 03:03:42 +02:00
|
|
|
write += zebra_import_table_config (vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
return write;
|
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:42 +02:00
|
|
|
DEFUN (ip_zebra_import_table_distance,
|
|
|
|
ip_zebra_import_table_distance_cmd,
|
2016-10-04 21:21:45 +02:00
|
|
|
"ip import-table (1-252) [distance (1-255)] [route-map WORD]",
|
2016-05-11 17:47:02 +02:00
|
|
|
IP_STR
|
|
|
|
"import routes from non-main kernel table\n"
|
|
|
|
"kernel routing table id\n"
|
|
|
|
"Distance for imported routes\n"
|
|
|
|
"Default distance value\n"
|
|
|
|
"route-map for filtering\n"
|
|
|
|
"route-map name\n")
|
|
|
|
{
|
|
|
|
u_int32_t table_id = 0;
|
|
|
|
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
table_id = strtoul(argv[2]->arg, NULL, 10);
|
2016-09-28 06:47:43 +02:00
|
|
|
int distance = ZEBRA_TABLE_DISTANCE_DEFAULT;
|
|
|
|
char *rmap = strmatch (argv[argc - 2]->text, "route-map") ?
|
|
|
|
XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL;
|
2017-06-10 22:39:41 +02:00
|
|
|
int ret;
|
|
|
|
|
2016-09-28 06:47:43 +02:00
|
|
|
if (argc == 7 || (argc == 5 && !rmap))
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
distance = strtoul(argv[4]->arg, NULL, 10);
|
2016-05-11 17:47:02 +02:00
|
|
|
|
|
|
|
if (!is_zebra_valid_kernel_table(table_id))
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Invalid routing table ID, %d. Must be in range 1-252\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
table_id);
|
2016-05-11 17:47:02 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_zebra_main_routing_table(table_id))
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Invalid routing table ID, %d. Must be non-default table\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
table_id);
|
2016-05-11 17:47:02 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-06-10 22:39:41 +02:00
|
|
|
ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
|
|
|
|
if (rmap)
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
|
|
|
|
|
|
|
|
return ret;
|
2016-05-11 17:47:02 +02:00
|
|
|
}
|
|
|
|
|
2015-05-20 03:03:42 +02:00
|
|
|
DEFUN (no_ip_zebra_import_table,
|
|
|
|
no_ip_zebra_import_table_cmd,
|
2016-09-28 06:47:43 +02:00
|
|
|
"no ip import-table (1-252) [distance (1-255)] [route-map NAME]",
|
2015-05-20 03:03:42 +02:00
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"import routes from non-main kernel table\n"
|
2016-11-30 00:07:11 +01:00
|
|
|
"kernel routing table id\n"
|
|
|
|
"Distance for imported routes\n"
|
|
|
|
"Default distance value\n"
|
|
|
|
"route-map for filtering\n"
|
|
|
|
"route-map name\n")
|
2015-05-20 03:03:42 +02:00
|
|
|
{
|
|
|
|
u_int32_t table_id = 0;
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
table_id = strtoul(argv[3]->arg, NULL, 10);
|
2015-05-20 03:03:42 +02:00
|
|
|
|
|
|
|
if (!is_zebra_valid_kernel_table(table_id))
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty,"Invalid routing table ID. Must be in range 1-252\n");
|
2015-05-20 03:03:42 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_zebra_main_routing_table(table_id))
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Invalid routing table ID, %d. Must be non-default table\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
table_id);
|
2015-05-20 03:03:42 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!is_zebra_import_table_enabled(AFI_IP, table_id))
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2016-05-11 17:47:02 +02:00
|
|
|
return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
|
2015-05-20 03:03:42 +02:00
|
|
|
}
|
|
|
|
|
2015-08-26 14:21:40 +02:00
|
|
|
static int
|
|
|
|
config_write_protocol (struct vty *vty)
|
|
|
|
{
|
|
|
|
if (allow_delete)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "allow-external-route-update\n");
|
2015-08-26 14:21:40 +02:00
|
|
|
|
|
|
|
if (zebra_rnh_ip_default_route)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ip nht resolve-via-default\n");
|
2015-08-26 14:21:40 +02:00
|
|
|
|
|
|
|
if (zebra_rnh_ipv6_default_route)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ipv6 nht resolve-via-default\n");
|
2015-08-26 14:21:40 +02:00
|
|
|
|
2015-01-06 19:53:24 +01:00
|
|
|
enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get ();
|
|
|
|
|
|
|
|
if (ipv4_multicast_mode != MCAST_NO_CONFIG)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ip multicast rpf-lookup-mode %s\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" : ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" : ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" : ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" : "longer-prefix");
|
2015-01-06 19:53:24 +01:00
|
|
|
|
2015-08-26 14:21:40 +02:00
|
|
|
zebra_routemap_config_write_protocol(vty);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* IP node for static routes. */
|
2008-12-01 20:10:34 +01:00
|
|
|
static struct cmd_node ip_node = { IP_NODE, "", 1 };
|
2015-08-26 14:21:40 +02:00
|
|
|
static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Route VTY. */
|
|
|
|
void
|
2005-06-28 19:17:12 +02:00
|
|
|
zebra_vty_init (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
install_node (&ip_node, zebra_ip_config);
|
2015-08-26 14:21:40 +02:00
|
|
|
install_node (&protocol_node, config_write_protocol);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-08-26 14:21:40 +02:00
|
|
|
install_element (CONFIG_NODE, &allow_external_route_update_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_allow_external_route_update_cmd);
|
2015-01-22 19:03:53 +01:00
|
|
|
install_element (CONFIG_NODE, &ip_mroute_dist_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd);
|
2015-01-06 19:53:24 +01:00
|
|
|
install_element (CONFIG_NODE, &ip_multicast_mode_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &ip_route_cmd);
|
2003-05-25 21:21:25 +02:00
|
|
|
install_element (CONFIG_NODE, &ip_route_flags_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &ip_route_mask_cmd);
|
2003-05-25 21:21:25 +02:00
|
|
|
install_element (CONFIG_NODE, &ip_route_mask_flags_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &no_ip_route_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_route_mask_cmd);
|
2015-05-20 03:03:42 +02:00
|
|
|
install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
install_element (VIEW_NODE, &show_vrf_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (VIEW_NODE, &show_ip_route_cmd);
|
2015-05-20 02:40:34 +02:00
|
|
|
install_element (VIEW_NODE, &show_ip_nht_cmd);
|
2016-02-28 23:03:27 +01:00
|
|
|
install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd);
|
2015-05-20 02:40:34 +02:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_nht_cmd);
|
2016-02-28 23:03:27 +01:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (VIEW_NODE, &show_ip_route_addr_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
|
2008-11-05 00:45:07 +01:00
|
|
|
install_element (VIEW_NODE, &show_ip_route_summary_cmd);
|
2015-05-20 02:24:41 +02:00
|
|
|
install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2014-07-14 16:19:00 +02:00
|
|
|
install_element (VIEW_NODE, &show_ip_rpf_cmd);
|
2015-01-22 19:12:35 +01:00
|
|
|
install_element (VIEW_NODE, &show_ip_rpf_addr_cmd);
|
2011-11-26 18:59:32 +01:00
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
/* Commands for VRF */
|
|
|
|
|
2016-09-26 14:10:57 +02:00
|
|
|
install_element (CONFIG_NODE, &no_ip_route_flags_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2016-02-28 23:03:27 +01:00
|
|
|
install_element (VIEW_NODE, &show_ip_route_vrf_all_addr_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &ipv6_route_cmd);
|
2003-05-25 21:21:25 +02:00
|
|
|
install_element (CONFIG_NODE, &ipv6_route_flags_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &ipv6_route_ifname_cmd);
|
2003-05-25 21:21:25 +02:00
|
|
|
install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &no_ipv6_route_cmd);
|
2003-05-25 21:21:25 +02:00
|
|
|
install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd);
|
2003-05-25 21:21:25 +02:00
|
|
|
install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd);
|
2015-05-20 03:04:16 +02:00
|
|
|
install_element (CONFIG_NODE, &ip_nht_default_route_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd);
|
|
|
|
install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_cmd);
|
2008-11-05 00:45:07 +01:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_summary_cmd);
|
2015-05-20 02:24:41 +02:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
|
2011-11-26 18:59:32 +01:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_mroute_cmd);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
|
|
|
/* Commands for VRF */
|
2016-02-28 23:03:27 +01:00
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd);
|
2015-05-22 11:40:03 +02:00
|
|
|
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|