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"
|
2018-03-01 11:10:47 +01:00
|
|
|
#include "linklist.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"
|
2017-05-15 07:45:55 +02:00
|
|
|
#include "vxlan.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-08-27 16:43:37 +02:00
|
|
|
#include "zebra/zebra_router.h"
|
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-10-07 15:05:28 +02:00
|
|
|
#include "lib/json.h"
|
2017-05-15 07:45:55 +02:00
|
|
|
#include "zebra/zebra_vxlan.h"
|
2017-11-09 17:09:58 +01:00
|
|
|
#ifndef VTYSH_EXTRACT_PL
|
2017-07-28 02:27:56 +02:00
|
|
|
#include "zebra/zebra_vty_clippy.c"
|
2017-11-09 17:09:58 +01:00
|
|
|
#endif
|
2017-10-25 16:47:55 +02:00
|
|
|
#include "zebra/zserv.h"
|
2017-12-07 16:47:30 +01:00
|
|
|
#include "zebra/router-id.h"
|
|
|
|
#include "zebra/ipforward.h"
|
2017-10-08 03:49:27 +02:00
|
|
|
#include "zebra/zebra_vxlan_private.h"
|
2018-04-23 15:17:19 +02:00
|
|
|
#include "zebra/zebra_pbr.h"
|
2015-08-26 14:21:40 +02:00
|
|
|
|
|
|
|
extern int allow_delete;
|
2005-06-28 19:17:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
|
2018-08-29 14:19:54 +02:00
|
|
|
safi_t safi, bool use_fib, bool use_json,
|
2017-09-13 20:16:12 +02:00
|
|
|
route_tag_t tag,
|
|
|
|
const struct prefix *longer_prefix_p,
|
2017-07-17 14:03:14 +02:00
|
|
|
bool supernets_only, int type,
|
2018-03-27 21:13:34 +02:00
|
|
|
unsigned short ospf_instance_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
|
|
|
|
int mcast);
|
2017-09-13 22:40:19 +02:00
|
|
|
static void vty_show_ip_route_summary(struct vty *vty,
|
|
|
|
struct route_table *table);
|
|
|
|
static void vty_show_ip_route_summary_prefix(struct vty *vty,
|
|
|
|
struct route_table *table);
|
2014-07-14 16:19:00 +02: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")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
char *mode = argv[3]->text;
|
|
|
|
|
|
|
|
if (strmatch(mode, "urib-only"))
|
|
|
|
multicast_mode_ipv4_set(MCAST_URIB_ONLY);
|
|
|
|
else if (strmatch(mode, "mrib-only"))
|
|
|
|
multicast_mode_ipv4_set(MCAST_MRIB_ONLY);
|
|
|
|
else if (strmatch(mode, "mrib-then-urib"))
|
|
|
|
multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST);
|
|
|
|
else if (strmatch(mode, "lower-distance"))
|
|
|
|
multicast_mode_ipv4_set(MCAST_MIX_DISTANCE);
|
|
|
|
else if (strmatch(mode, "longer-prefix"))
|
|
|
|
multicast_mode_ipv4_set(MCAST_MIX_PFXLEN);
|
|
|
|
else {
|
|
|
|
vty_out(vty, "Invalid mode specified\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
2015-01-06 19:53:24 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-01-06 19:53:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
multicast_mode_ipv4_set(MCAST_NO_CONFIG);
|
|
|
|
return CMD_SUCCESS;
|
2015-01-06 19:53:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-07-17 14:03:14 +02:00
|
|
|
return do_show_ip_route(vty, VRF_DEFAULT_NAME, AFI_IP, SAFI_MULTICAST,
|
2017-11-20 01:38:55 +01:00
|
|
|
false, uj, 0, NULL, false, 0, 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")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
int idx_ipv4 = 3;
|
|
|
|
struct in_addr addr;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct route_entry *re;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "%% Malformed address\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
re = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn);
|
|
|
|
|
|
|
|
if (re)
|
|
|
|
vty_show_ip_route_detail(vty, rn, 1);
|
|
|
|
else
|
|
|
|
vty_out(vty, "%% No match for RPF lookup\n");
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2019-01-14 22:32:26 +01:00
|
|
|
static char re_status_output_char(struct route_entry *re, struct nexthop *nhop)
|
|
|
|
{
|
2019-01-14 22:37:53 +01:00
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
|
2019-02-02 01:56:07 +01:00
|
|
|
if (!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_DUPLICATE) &&
|
|
|
|
!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_RECURSIVE))
|
2019-01-14 22:32:26 +01:00
|
|
|
return '*';
|
2019-01-14 22:37:53 +01:00
|
|
|
else
|
|
|
|
return ' ';
|
2019-01-14 22:32:26 +01:00
|
|
|
}
|
|
|
|
|
2019-01-14 22:37:53 +01:00
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED)) {
|
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
|
|
|
|
return 'q';
|
|
|
|
|
2019-01-30 02:29:20 +01:00
|
|
|
return 'r';
|
2019-01-14 22:37:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
|
|
|
|
return 'q';
|
|
|
|
|
2019-01-14 22:32:26 +01:00
|
|
|
return ' ';
|
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:06 +02:00
|
|
|
/* New RIB. Detailed information for IPv4 route. */
|
2017-07-17 14:03:14 +02:00
|
|
|
static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
|
|
|
|
int mcast)
|
|
|
|
{
|
|
|
|
struct route_entry *re;
|
|
|
|
struct nexthop *nexthop;
|
|
|
|
char buf[SRCDEST2STR_BUFFER];
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2017-09-15 17:47:35 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
2017-07-17 14:03:14 +02:00
|
|
|
const char *mcast_info = "";
|
|
|
|
if (mcast) {
|
|
|
|
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
|
|
|
mcast_info = (info->safi == SAFI_MULTICAST)
|
|
|
|
? " using Multicast RIB"
|
|
|
|
: " using Unicast RIB";
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "Routing entry for %s%s\n",
|
|
|
|
srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info);
|
|
|
|
vty_out(vty, " Known via \"%s", zebra_route_string(re->type));
|
|
|
|
if (re->instance)
|
|
|
|
vty_out(vty, "[%d]", re->instance);
|
|
|
|
vty_out(vty, "\"");
|
|
|
|
vty_out(vty, ", distance %u, metric %u", re->distance,
|
|
|
|
re->metric);
|
2017-12-08 21:02:46 +01:00
|
|
|
if (re->tag) {
|
2017-10-06 03:38:19 +02:00
|
|
|
vty_out(vty, ", tag %u", re->tag);
|
2017-12-08 21:02:46 +01:00
|
|
|
#if defined(SUPPORT_REALMS)
|
|
|
|
if (re->tag > 0 && re->tag <= 255)
|
|
|
|
vty_out(vty, "(realm)");
|
|
|
|
#endif
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
if (re->mtu)
|
|
|
|
vty_out(vty, ", mtu %u", re->mtu);
|
|
|
|
if (re->vrf_id != VRF_DEFAULT) {
|
|
|
|
zvrf = vrf_info_lookup(re->vrf_id);
|
|
|
|
vty_out(vty, ", vrf %s", zvrf_name(zvrf));
|
|
|
|
}
|
|
|
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
|
|
|
vty_out(vty, ", best");
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
2017-09-12 20:58:10 +02:00
|
|
|
time_t uptime;
|
|
|
|
struct tm *tm;
|
|
|
|
|
|
|
|
uptime = time(NULL);
|
|
|
|
uptime -= re->uptime;
|
|
|
|
tm = gmtime(&uptime);
|
|
|
|
|
|
|
|
vty_out(vty, " Last update ");
|
|
|
|
|
|
|
|
if (uptime < ONE_DAY_SECOND)
|
2018-03-06 20:02:52 +01:00
|
|
|
vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
|
|
|
|
tm->tm_sec);
|
2017-09-12 20:58:10 +02:00
|
|
|
else if (uptime < ONE_WEEK_SECOND)
|
2018-03-06 20:02:52 +01:00
|
|
|
vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
|
|
|
|
tm->tm_min);
|
2017-09-12 20:58:10 +02:00
|
|
|
else
|
|
|
|
vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
|
|
|
|
tm->tm_yday - ((tm->tm_yday / 7) * 7),
|
|
|
|
tm->tm_hour);
|
|
|
|
vty_out(vty, " ago\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-01-26 16:12:35 +01:00
|
|
|
for (ALL_NEXTHOPS(re->ng, nexthop)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
char addrstr[32];
|
|
|
|
|
|
|
|
vty_out(vty, " %c%s",
|
2019-01-14 22:32:26 +01:00
|
|
|
re_status_output_char(re, nexthop),
|
2017-07-17 14:03:14 +02:00
|
|
|
nexthop->rparent ? " " : "");
|
|
|
|
|
|
|
|
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",
|
2018-02-08 15:12:12 +01:00
|
|
|
ifindex2ifname(
|
|
|
|
nexthop->ifindex,
|
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
vty_out(vty, " %s",
|
|
|
|
inet_ntop(AF_INET6, &nexthop->gate.ipv6,
|
|
|
|
buf, sizeof buf));
|
|
|
|
if (nexthop->ifindex)
|
|
|
|
vty_out(vty, ", via %s",
|
2018-02-08 15:12:12 +01:00
|
|
|
ifindex2ifname(
|
|
|
|
nexthop->ifindex,
|
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
vty_out(vty, " directly connected, %s",
|
|
|
|
ifindex2ifname(nexthop->ifindex,
|
2018-02-08 15:12:12 +01:00
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
2010-02-05 04:31:56 +01:00
|
|
|
vty_out(vty, " unreachable");
|
|
|
|
switch (nexthop->bh_type) {
|
|
|
|
case BLACKHOLE_REJECT:
|
|
|
|
vty_out(vty, " (ICMP unreachable)");
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_ADMINPROHIB:
|
2017-08-30 17:23:01 +02:00
|
|
|
vty_out(vty,
|
|
|
|
" (ICMP admin-prohibited)");
|
2010-02-05 04:31:56 +01:00
|
|
|
break;
|
|
|
|
case BLACKHOLE_NULL:
|
|
|
|
vty_out(vty, " (blackhole)");
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_UNSPEC:
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2018-01-08 16:43:07 +01:00
|
|
|
|
2018-07-17 16:20:52 +02:00
|
|
|
if ((re->vrf_id != nexthop->vrf_id)
|
2018-07-18 15:05:50 +02:00
|
|
|
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
|
2018-01-08 16:43:07 +01:00
|
|
|
struct vrf *vrf =
|
2018-02-08 15:12:12 +01:00
|
|
|
vrf_lookup_by_id(nexthop->vrf_id);
|
2018-01-08 16:43:07 +01:00
|
|
|
|
2018-03-27 20:59:05 +02:00
|
|
|
if (vrf)
|
|
|
|
vty_out(vty, "(vrf %s)", vrf->name);
|
|
|
|
else
|
2018-10-25 20:06:59 +02:00
|
|
|
vty_out(vty, "(vrf UNKNOWN)");
|
2018-01-08 16:43:07 +01:00
|
|
|
}
|
|
|
|
|
2017-09-12 20:52:20 +02:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
|
|
|
|
vty_out(vty, " (duplicate nexthop removed)");
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-07-25 11:55:41 +02:00
|
|
|
if (re->nexthop_mtu)
|
|
|
|
vty_out(vty, ", mtu %u", re->nexthop_mtu);
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/* Label information */
|
|
|
|
if (nexthop->nh_label
|
|
|
|
&& nexthop->nh_label->num_labels) {
|
|
|
|
vty_out(vty, ", label %s",
|
|
|
|
mpls_label2str(
|
|
|
|
nexthop->nh_label->num_labels,
|
|
|
|
nexthop->nh_label->label, buf,
|
|
|
|
sizeof buf, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
|
|
|
|
struct route_entry *re, json_object *json)
|
|
|
|
{
|
|
|
|
struct nexthop *nexthop;
|
|
|
|
int len = 0;
|
|
|
|
char buf[SRCDEST2STR_BUFFER];
|
|
|
|
json_object *json_nexthops = NULL;
|
|
|
|
json_object *json_nexthop = NULL;
|
|
|
|
json_object *json_route = NULL;
|
|
|
|
json_object *json_labels = NULL;
|
2017-09-12 20:58:10 +02:00
|
|
|
time_t uptime;
|
|
|
|
struct tm *tm;
|
|
|
|
|
|
|
|
uptime = time(NULL);
|
|
|
|
uptime -= re->uptime;
|
|
|
|
tm = gmtime(&uptime);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (json) {
|
|
|
|
json_route = json_object_new_object();
|
|
|
|
json_nexthops = json_object_new_array();
|
|
|
|
|
|
|
|
json_object_string_add(json_route, "prefix",
|
|
|
|
srcdest_rnode2str(rn, buf, sizeof buf));
|
|
|
|
json_object_string_add(json_route, "protocol",
|
|
|
|
zebra_route_string(re->type));
|
|
|
|
|
|
|
|
if (re->instance)
|
|
|
|
json_object_int_add(json_route, "instance",
|
|
|
|
re->instance);
|
|
|
|
|
|
|
|
if (re->vrf_id)
|
|
|
|
json_object_int_add(json_route, "vrfId", re->vrf_id);
|
|
|
|
|
|
|
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
|
|
|
|
json_object_boolean_true_add(json_route, "selected");
|
|
|
|
|
zebra: display metric for connected routes
In a VRR/VRRP setup we can have connected routes with different costs.
So this change eliminates suppressing metric display for connected routes.
Sample output -
root@TORC11:~# vtysh -c "show ipv6 route vrf vrf1"
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR,
> - selected route, * - FIB route
VRF vrf1:
K * ::/0 [255/8192] unreachable (ICMP unreachable), 00:00:36
C * 2001:aa:1::/64 [0/100] is directly connected, vlan1002-v0, 00:00:36
C>* 2001:aa:1::/64 [0/90] is directly connected, vlan1002, 00:00:36
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-01-15 00:56:30 +01:00
|
|
|
json_object_int_add(json_route, "distance",
|
|
|
|
re->distance);
|
|
|
|
json_object_int_add(json_route, "metric", re->metric);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-14 22:37:53 +01:00
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
|
|
|
|
json_object_boolean_true_add(json_route, "installed");
|
|
|
|
|
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
|
|
|
|
json_object_boolean_true_add(json_route, "failed");
|
|
|
|
|
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
|
|
|
|
json_object_boolean_true_add(json_route, "queued");
|
|
|
|
|
|
|
|
if (re->type != ZEBRA_ROUTE_CONNECT) {
|
|
|
|
json_object_int_add(json_route, "distance",
|
|
|
|
re->distance);
|
|
|
|
json_object_int_add(json_route, "metric", re->metric);
|
|
|
|
}
|
|
|
|
|
2018-08-08 00:15:34 +02:00
|
|
|
if (re->tag)
|
|
|
|
json_object_int_add(json_route, "tag", re->tag);
|
|
|
|
|
2018-05-02 22:50:37 +02:00
|
|
|
json_object_int_add(json_route, "internalStatus",
|
|
|
|
re->status);
|
|
|
|
json_object_int_add(json_route, "internalFlags",
|
|
|
|
re->flags);
|
2017-09-12 20:58:10 +02:00
|
|
|
if (uptime < ONE_DAY_SECOND)
|
2018-03-06 20:02:52 +01:00
|
|
|
sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
|
|
|
|
tm->tm_sec);
|
2017-09-12 20:58:10 +02:00
|
|
|
else if (uptime < ONE_WEEK_SECOND)
|
2018-03-06 20:02:52 +01:00
|
|
|
sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
|
|
|
|
tm->tm_min);
|
2017-09-12 20:58:10 +02:00
|
|
|
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-07-17 14:03:14 +02:00
|
|
|
|
2018-01-26 16:12:35 +01:00
|
|
|
for (ALL_NEXTHOPS(re->ng, nexthop)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
json_nexthop = json_object_new_object();
|
|
|
|
|
2018-05-02 22:50:37 +02:00
|
|
|
json_object_int_add(json_nexthop, "flags",
|
|
|
|
nexthop->flags);
|
|
|
|
|
2017-09-12 20:52:20 +02:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
|
|
|
|
json_object_boolean_true_add(json_nexthop,
|
|
|
|
"duplicate");
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
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);
|
|
|
|
json_object_string_add(
|
|
|
|
json_nexthop, "interfaceName",
|
2018-02-08 15:12:12 +01:00
|
|
|
ifindex2ifname(
|
|
|
|
nexthop->ifindex,
|
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
json_object_string_add(
|
|
|
|
json_nexthop, "ip",
|
|
|
|
inet_ntop(AF_INET6, &nexthop->gate.ipv6,
|
|
|
|
buf, sizeof buf));
|
|
|
|
json_object_string_add(json_nexthop, "afi",
|
|
|
|
"ipv6");
|
|
|
|
|
|
|
|
if (nexthop->ifindex) {
|
|
|
|
json_object_int_add(json_nexthop,
|
|
|
|
"interfaceIndex",
|
|
|
|
nexthop->ifindex);
|
|
|
|
json_object_string_add(
|
|
|
|
json_nexthop, "interfaceName",
|
2018-02-08 15:12:12 +01:00
|
|
|
ifindex2ifname(
|
|
|
|
nexthop->ifindex,
|
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
json_object_boolean_true_add(
|
|
|
|
json_nexthop, "directlyConnected");
|
|
|
|
json_object_int_add(json_nexthop,
|
|
|
|
"interfaceIndex",
|
|
|
|
nexthop->ifindex);
|
|
|
|
json_object_string_add(
|
|
|
|
json_nexthop, "interfaceName",
|
|
|
|
ifindex2ifname(nexthop->ifindex,
|
2018-02-08 15:12:12 +01:00
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
|
|
|
json_object_boolean_true_add(json_nexthop,
|
2010-02-05 04:31:56 +01:00
|
|
|
"unreachable");
|
|
|
|
switch (nexthop->bh_type) {
|
|
|
|
case BLACKHOLE_REJECT:
|
|
|
|
json_object_boolean_true_add(
|
2017-08-30 17:23:01 +02:00
|
|
|
json_nexthop, "reject");
|
2010-02-05 04:31:56 +01:00
|
|
|
break;
|
|
|
|
case BLACKHOLE_ADMINPROHIB:
|
|
|
|
json_object_boolean_true_add(
|
2017-08-30 17:23:01 +02:00
|
|
|
json_nexthop,
|
|
|
|
"admin-prohibited");
|
2010-02-05 04:31:56 +01:00
|
|
|
break;
|
|
|
|
case BLACKHOLE_NULL:
|
|
|
|
json_object_boolean_true_add(
|
2017-08-30 17:23:01 +02:00
|
|
|
json_nexthop, "blackhole");
|
2010-02-05 04:31:56 +01:00
|
|
|
break;
|
|
|
|
case BLACKHOLE_UNSPEC:
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-07-17 16:20:52 +02:00
|
|
|
if ((nexthop->vrf_id != re->vrf_id)
|
2018-07-18 15:05:50 +02:00
|
|
|
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
|
2018-01-08 16:43:07 +01:00
|
|
|
struct vrf *vrf =
|
2018-02-08 15:12:12 +01:00
|
|
|
vrf_lookup_by_id(nexthop->vrf_id);
|
2018-01-08 16:43:07 +01:00
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
json_object_string_add(json_nexthop, "vrf",
|
2018-01-08 16:43:07 +01:00
|
|
|
vrf->name);
|
|
|
|
}
|
2017-09-12 20:52:20 +02:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
|
|
|
|
json_object_boolean_true_add(json_nexthop,
|
|
|
|
"duplicate");
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Nexthop information. */
|
2018-01-26 16:12:35 +01:00
|
|
|
for (ALL_NEXTHOPS(re->ng, nexthop)) {
|
|
|
|
if (nexthop == re->ng.nexthop) {
|
2017-07-17 14:03:14 +02:00
|
|
|
/* Prefix information. */
|
|
|
|
len = vty_out(vty, "%c", zebra_route_char(re->type));
|
|
|
|
if (re->instance)
|
|
|
|
len += vty_out(vty, "[%d]", re->instance);
|
|
|
|
len += vty_out(
|
|
|
|
vty, "%c%c %s",
|
|
|
|
CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
|
|
|
|
? '>'
|
|
|
|
: ' ',
|
2019-01-14 22:32:26 +01:00
|
|
|
re_status_output_char(re, nexthop),
|
2017-07-17 14:03:14 +02:00
|
|
|
srcdest_rnode2str(rn, buf, sizeof buf));
|
|
|
|
|
|
|
|
/* Distance and metric display. */
|
zebra: display metric for connected routes
In a VRR/VRRP setup we can have connected routes with different costs.
So this change eliminates suppressing metric display for connected routes.
Sample output -
root@TORC11:~# vtysh -c "show ipv6 route vrf vrf1"
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR,
> - selected route, * - FIB route
VRF vrf1:
K * ::/0 [255/8192] unreachable (ICMP unreachable), 00:00:36
C * 2001:aa:1::/64 [0/100] is directly connected, vlan1002-v0, 00:00:36
C>* 2001:aa:1::/64 [0/90] is directly connected, vlan1002, 00:00:36
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
2019-01-15 00:56:30 +01:00
|
|
|
if (((re->type == ZEBRA_ROUTE_CONNECT) &&
|
|
|
|
(re->distance || re->metric)) ||
|
|
|
|
(re->type != ZEBRA_ROUTE_CONNECT))
|
2017-10-06 03:38:19 +02:00
|
|
|
len += vty_out(vty, " [%u/%u]", re->distance,
|
2017-07-17 14:03:14 +02:00
|
|
|
re->metric);
|
2017-09-12 20:52:20 +02:00
|
|
|
} else {
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, " %c%*c",
|
2019-01-14 22:32:26 +01:00
|
|
|
re_status_output_char(re, nexthop),
|
2017-07-17 14:03:14 +02:00
|
|
|
len - 3 + (2 * nexthop_level(nexthop)), ' ');
|
2017-09-12 20:52:20 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
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",
|
|
|
|
ifindex2ifname(nexthop->ifindex,
|
2018-02-08 15:12:12 +01:00
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
vty_out(vty, " via %s",
|
|
|
|
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
|
|
|
|
sizeof buf));
|
|
|
|
if (nexthop->ifindex)
|
|
|
|
vty_out(vty, ", %s",
|
|
|
|
ifindex2ifname(nexthop->ifindex,
|
2018-02-08 15:12:12 +01:00
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
vty_out(vty, " is directly connected, %s",
|
2018-01-08 15:56:08 +01:00
|
|
|
ifindex2ifname(nexthop->ifindex,
|
2018-02-08 15:12:12 +01:00
|
|
|
nexthop->vrf_id));
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
2010-02-05 04:31:56 +01:00
|
|
|
vty_out(vty, " unreachable");
|
|
|
|
switch (nexthop->bh_type) {
|
|
|
|
case BLACKHOLE_REJECT:
|
|
|
|
vty_out(vty, " (ICMP unreachable)");
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_ADMINPROHIB:
|
|
|
|
vty_out(vty, " (ICMP admin-prohibited)");
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_NULL:
|
|
|
|
vty_out(vty, " (blackhole)");
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_UNSPEC:
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2018-01-08 16:43:07 +01:00
|
|
|
|
2018-07-17 16:20:52 +02:00
|
|
|
if ((nexthop->vrf_id != re->vrf_id)
|
2018-07-18 15:05:50 +02:00
|
|
|
&& (nexthop->type != NEXTHOP_TYPE_BLACKHOLE)) {
|
2018-02-08 15:12:12 +01:00
|
|
|
struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
|
2018-01-08 16:43:07 +01:00
|
|
|
|
2018-03-27 20:59:05 +02:00
|
|
|
if (vrf)
|
|
|
|
vty_out(vty, "(vrf %s)", vrf->name);
|
|
|
|
else
|
2018-10-25 20:06:59 +02:00
|
|
|
vty_out(vty, "(vrf UNKNOWN)");
|
2018-01-08 16:43:07 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Label information */
|
|
|
|
if (nexthop->nh_label && nexthop->nh_label->num_labels) {
|
|
|
|
vty_out(vty, ", label %s",
|
|
|
|
mpls_label2str(nexthop->nh_label->num_labels,
|
|
|
|
nexthop->nh_label->label, buf,
|
|
|
|
sizeof buf, 1));
|
|
|
|
}
|
|
|
|
|
2017-09-12 20:58:10 +02:00
|
|
|
if (uptime < ONE_DAY_SECOND)
|
|
|
|
vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
|
|
|
|
tm->tm_min, tm->tm_sec);
|
|
|
|
else if (uptime < ONE_WEEK_SECOND)
|
|
|
|
vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
|
|
|
|
tm->tm_hour, tm->tm_min);
|
|
|
|
else
|
|
|
|
vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
|
|
|
|
tm->tm_yday - ((tm->tm_yday / 7) * 7),
|
|
|
|
tm->tm_hour);
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-08 00:15:34 +02:00
|
|
|
static void vty_show_ip_route_detail_json(struct vty *vty,
|
|
|
|
struct route_node *rn)
|
|
|
|
{
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_prefix = NULL;
|
|
|
|
struct route_entry *re;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
json = json_object_new_object();
|
zebra: `show ip route A.B.C.D json` would only show last route entry
The `show ip route A.B.C.D json` command was only displaying
the last route entry looked at and we would drop the data
associated with other route entries. This fixes the issue:
robot# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
K>* 0.0.0.0/0 [0/100] via 192.168.201.1, enp3s0, 00:13:31
C>* 4.50.50.50/32 is directly connected, lo, 00:13:31
D 10.0.0.1/32 [150/0] via 192.168.201.1, enp3s0, 00:09:46
S>* 10.0.0.1/32 [1/0] via 192.168.201.1, enp3s0, 00:10:04
C>* 192.168.201.0/24 is directly connected, enp3s0, 00:13:31
robot# show ip route 10.0.0.1 json
{
"10.0.0.1\/32":[
{
"prefix":"10.0.0.1\/32",
"protocol":"sharp",
"distance":150,
"metric":0,
"internalStatus":0,
"internalFlags":1,
"uptime":"00:09:50",
"nexthops":[
{
"flags":1,
"ip":"192.168.201.1",
"afi":"ipv4",
"interfaceIndex":2,
"interfaceName":"enp3s0",
"active":true
}
]
},
{
"prefix":"10.0.0.1\/32",
"protocol":"static",
"selected":true,
"distance":1,
"metric":0,
"internalStatus":0,
"internalFlags":2064,
"uptime":"00:10:08",
"nexthops":[
{
"flags":3,
"fib":true,
"ip":"192.168.201.1",
"afi":"ipv4",
"interfaceIndex":2,
"interfaceName":"enp3s0",
"active":true
}
]
}
]
}
robot#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2018-12-05 21:12:50 +01:00
|
|
|
json_prefix = json_object_new_array();
|
2018-08-08 00:15:34 +02:00
|
|
|
|
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
|
|
|
vty_show_ip_route(vty, rn, re, json_prefix);
|
|
|
|
}
|
|
|
|
|
zebra: `show ip route A.B.C.D json` would only show last route entry
The `show ip route A.B.C.D json` command was only displaying
the last route entry looked at and we would drop the data
associated with other route entries. This fixes the issue:
robot# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route
K>* 0.0.0.0/0 [0/100] via 192.168.201.1, enp3s0, 00:13:31
C>* 4.50.50.50/32 is directly connected, lo, 00:13:31
D 10.0.0.1/32 [150/0] via 192.168.201.1, enp3s0, 00:09:46
S>* 10.0.0.1/32 [1/0] via 192.168.201.1, enp3s0, 00:10:04
C>* 192.168.201.0/24 is directly connected, enp3s0, 00:13:31
robot# show ip route 10.0.0.1 json
{
"10.0.0.1\/32":[
{
"prefix":"10.0.0.1\/32",
"protocol":"sharp",
"distance":150,
"metric":0,
"internalStatus":0,
"internalFlags":1,
"uptime":"00:09:50",
"nexthops":[
{
"flags":1,
"ip":"192.168.201.1",
"afi":"ipv4",
"interfaceIndex":2,
"interfaceName":"enp3s0",
"active":true
}
]
},
{
"prefix":"10.0.0.1\/32",
"protocol":"static",
"selected":true,
"distance":1,
"metric":0,
"internalStatus":0,
"internalFlags":2064,
"uptime":"00:10:08",
"nexthops":[
{
"flags":3,
"fib":true,
"ip":"192.168.201.1",
"afi":"ipv4",
"interfaceIndex":2,
"interfaceName":"enp3s0",
"active":true
}
]
}
]
}
robot#
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2018-12-05 21:12:50 +01:00
|
|
|
prefix2str(&rn->p, buf, sizeof(buf));
|
|
|
|
json_object_object_add(json, buf, json_prefix);
|
2018-08-08 00:15:34 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
|
2018-02-14 04:38:47 +01:00
|
|
|
static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
|
|
|
|
struct route_table *table, afi_t afi,
|
|
|
|
bool use_fib, route_tag_t tag,
|
|
|
|
const struct prefix *longer_prefix_p,
|
|
|
|
bool supernets_only, int type,
|
2018-08-29 14:19:54 +02:00
|
|
|
unsigned short ospf_instance_id, bool use_json)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct route_entry *re;
|
|
|
|
int first = 1;
|
2018-02-14 04:38:47 +01:00
|
|
|
rib_dest_t *dest;
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_prefix = NULL;
|
2018-02-14 04:38:47 +01:00
|
|
|
uint32_t addr;
|
|
|
|
char buf[BUFSIZ];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (use_json)
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
|
|
|
/* Show all routes. */
|
2018-07-19 21:16:06 +02:00
|
|
|
for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
|
2017-11-30 20:03:07 +01:00
|
|
|
dest = rib_dest_from_rnode(rn);
|
|
|
|
|
2017-09-15 17:47:35 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
2018-03-06 20:02:52 +01:00
|
|
|
if (use_fib && re != dest->selected_fib)
|
2017-07-17 14:03:14 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (tag && re->tag != tag)
|
|
|
|
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) {
|
|
|
|
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)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type && re->type != type)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (ospf_instance_id
|
|
|
|
&& (re->type != ZEBRA_ROUTE_OSPF
|
|
|
|
|| re->instance != ospf_instance_id))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (use_json) {
|
|
|
|
if (!json_prefix)
|
|
|
|
json_prefix = json_object_new_array();
|
|
|
|
} else {
|
|
|
|
if (first) {
|
|
|
|
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)
|
|
|
|
vty_out(vty, "\nVRF %s:\n",
|
|
|
|
zvrf_name(zvrf));
|
|
|
|
|
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_show_ip_route(vty, rn, re, json_prefix);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (json_prefix) {
|
2018-08-08 00:15:34 +02:00
|
|
|
prefix2str(&rn->p, buf, sizeof(buf));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_object_add(json, buf, json_prefix);
|
|
|
|
json_prefix = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (use_json) {
|
2018-08-08 00:15:34 +02:00
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
|
|
|
|
JSON_C_TO_STRING_PRETTY));
|
2017-07-17 14:03:14 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
2018-02-14 04:38:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
|
2018-08-29 14:19:54 +02:00
|
|
|
safi_t safi, bool use_fib, bool use_json,
|
2018-02-14 04:38:47 +01:00
|
|
|
route_tag_t tag,
|
|
|
|
const struct prefix *longer_prefix_p,
|
|
|
|
bool supernets_only, int type,
|
2018-03-27 21:13:34 +02:00
|
|
|
unsigned short ospf_instance_id)
|
2018-02-14 04:38:47 +01:00
|
|
|
{
|
|
|
|
struct route_table *table;
|
|
|
|
struct zebra_vrf *zvrf = NULL;
|
|
|
|
|
|
|
|
if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) {
|
|
|
|
if (use_json)
|
|
|
|
vty_out(vty, "{}\n");
|
|
|
|
else
|
|
|
|
vty_out(vty, "vrf %s not defined\n", vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zvrf_id(zvrf) == VRF_UNKNOWN) {
|
|
|
|
if (use_json)
|
|
|
|
vty_out(vty, "{}\n");
|
|
|
|
else
|
|
|
|
vty_out(vty, "vrf %s inactive\n", vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
table = zebra_vrf_table(afi, safi, zvrf_id(zvrf));
|
|
|
|
if (!table) {
|
|
|
|
if (use_json)
|
|
|
|
vty_out(vty, "{}\n");
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
do_show_route_helper(vty, zvrf, table, afi, use_fib, tag,
|
|
|
|
longer_prefix_p, supernets_only, type,
|
|
|
|
ospf_instance_id, use_json);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (show_route_table,
|
|
|
|
show_route_table_cmd,
|
|
|
|
"show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table [json$json]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IP6_STR
|
|
|
|
"IP routing table\n"
|
|
|
|
"Table to display\n"
|
|
|
|
"The table number to display, if available\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
|
|
|
struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
|
|
|
|
struct route_table *t;
|
|
|
|
|
2018-08-27 16:43:37 +02:00
|
|
|
t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
|
2018-02-14 04:38:47 +01:00
|
|
|
if (t)
|
|
|
|
do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
|
|
|
|
0, 0, !!json);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2016-06-27 17:31:57 +02:00
|
|
|
}
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2018-03-28 11:06:39 +02:00
|
|
|
DEFPY (show_route_table_vrf,
|
|
|
|
show_route_table_vrf_cmd,
|
|
|
|
"show <ip$ipv4|ipv6$ipv6> route table (1-4294967295)$table vrf NAME$vrf_name [json$json]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IP6_STR
|
|
|
|
"IP routing table\n"
|
|
|
|
"Table to display\n"
|
|
|
|
"The table number to display, if available\n"
|
|
|
|
VRF_CMD_HELP_STR
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
struct route_table *t;
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
|
|
|
if (vrf_name)
|
2018-07-27 16:09:38 +02:00
|
|
|
VRF_GET_ID(vrf_id, vrf_name, !!json);
|
2018-03-28 11:06:39 +02:00
|
|
|
zvrf = zebra_vrf_lookup_by_id(vrf_id);
|
|
|
|
|
2018-08-27 16:43:37 +02:00
|
|
|
t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST);
|
2018-03-28 11:06:39 +02:00
|
|
|
if (t)
|
|
|
|
do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false,
|
|
|
|
0, 0, !!json);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2019-01-21 15:47:10 +01:00
|
|
|
DEFPY (show_ip_nht,
|
2015-05-22 11:40:06 +02:00
|
|
|
show_ip_nht_cmd,
|
2019-01-21 15:47:10 +01:00
|
|
|
"show <ip$ipv4|ipv6$ipv6> nht [vrf NAME$vrf_name|vrf all$vrf_all]",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2019-01-21 15:47:10 +01:00
|
|
|
IP6_STR
|
2016-09-23 23:17:10 +02:00
|
|
|
"IP nexthop tracking table\n"
|
2019-01-21 15:47:10 +01:00
|
|
|
VRF_CMD_HELP_STR
|
|
|
|
VRF_ALL_CMD_HELP_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2019-01-21 15:47:10 +01:00
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
2017-07-17 14:03:14 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2019-01-21 15:47:10 +01:00
|
|
|
if (vrf_all) {
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
if ((zvrf = vrf->info) != NULL) {
|
|
|
|
vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
|
|
|
|
zebra_print_rnh_table(zvrf_id(zvrf), afi, vty,
|
|
|
|
RNH_NEXTHOP_TYPE);
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
if (vrf_name)
|
|
|
|
VRF_GET_ID(vrf_id, vrf_name, false);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2019-01-21 15:47:10 +01:00
|
|
|
zebra_print_rnh_table(vrf_id, afi, vty, RNH_NEXTHOP_TYPE);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2018-12-17 12:18:57 +01:00
|
|
|
DEFPY (show_ip_import_check,
|
|
|
|
show_ip_import_check_cmd,
|
|
|
|
"show <ip$ipv4|ipv6$ipv6> import-check [vrf NAME$vrf_name|vrf all$vrf_all]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
IP6_STR
|
|
|
|
"IP import check tracking table\n"
|
|
|
|
VRF_CMD_HELP_STR
|
|
|
|
VRF_ALL_CMD_HELP_STR)
|
|
|
|
{
|
2019-01-21 15:30:36 +01:00
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
2018-12-17 12:18:57 +01:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
|
|
|
if (vrf_all) {
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
if ((zvrf = vrf->info) != NULL) {
|
|
|
|
vty_out(vty, "\nVRF %s:\n",
|
|
|
|
zvrf_name(zvrf));
|
2019-01-21 15:30:36 +01:00
|
|
|
zebra_print_rnh_table(zvrf_id(zvrf), afi, vty,
|
2019-01-17 23:55:39 +01:00
|
|
|
RNH_IMPORT_CHECK_TYPE);
|
2018-12-17 12:18:57 +01:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
if (vrf_name)
|
|
|
|
VRF_GET_ID(vrf_id, vrf_name, false);
|
|
|
|
|
2019-01-21 15:30:36 +01:00
|
|
|
zebra_print_rnh_table(vrf_id, afi, vty, RNH_IMPORT_CHECK_TYPE);
|
2018-12-17 12:18:57 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2016-02-01 19:55:42 +01:00
|
|
|
|
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")
|
|
|
|
{
|
2018-10-11 19:48:23 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
|
2018-10-11 19:46:55 +02:00
|
|
|
|
|
|
|
if (!zvrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2018-10-11 19:48:23 +02:00
|
|
|
if (zebra_rnh_ip_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zebra_rnh_ip_default_route = 1;
|
2018-10-11 19:48:23 +02:00
|
|
|
|
2019-01-21 15:30:36 +01:00
|
|
|
zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
{
|
2018-10-11 19:48:23 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
|
2018-10-11 19:46:55 +02:00
|
|
|
|
|
|
|
if (!zvrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2018-10-11 19:48:23 +02:00
|
|
|
if (!zebra_rnh_ip_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zebra_rnh_ip_default_route = 0;
|
2019-01-21 15:30:36 +01:00
|
|
|
zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
{
|
2018-10-11 19:48:23 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
|
2018-10-11 19:46:55 +02:00
|
|
|
|
|
|
|
if (!zvrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2018-10-11 19:48:23 +02:00
|
|
|
if (zebra_rnh_ipv6_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zebra_rnh_ipv6_default_route = 1;
|
2019-01-21 15:30:36 +01:00
|
|
|
zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
{
|
|
|
|
|
2018-10-11 19:48:23 +02:00
|
|
|
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
|
2018-10-11 19:46:55 +02:00
|
|
|
|
|
|
|
if (!zvrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2018-10-11 19:48:23 +02:00
|
|
|
if (!zebra_rnh_ipv6_default_route)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zebra_rnh_ipv6_default_route = 0;
|
2019-01-21 15:30:36 +01:00
|
|
|
zebra_evaluate_rnh(zvrf, AFI_IP6, 1, RNH_NEXTHOP_TYPE, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2017-09-13 20:16:12 +02:00
|
|
|
DEFPY (show_route,
|
|
|
|
show_route_cmd,
|
|
|
|
"show\
|
|
|
|
<\
|
|
|
|
ip$ipv4 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
|
2017-09-13 20:25:39 +02:00
|
|
|
[{\
|
2017-09-13 20:16:12 +02:00
|
|
|
tag (1-4294967295)\
|
|
|
|
|A.B.C.D/M$prefix longer-prefixes\
|
|
|
|
|supernets-only$supernets_only\
|
2017-09-13 20:25:39 +02:00
|
|
|
}]\
|
|
|
|
[<\
|
|
|
|
" FRR_IP_REDIST_STR_ZEBRA "$type_str\
|
2017-09-13 20:16:12 +02:00
|
|
|
|ospf$type_str (1-65535)$ospf_instance_id\
|
2017-09-13 20:25:39 +02:00
|
|
|
>]\
|
2017-09-13 20:16:12 +02:00
|
|
|
|ipv6$ipv6 <fib$fib|route> [vrf <NAME$vrf_name|all$vrf_all>]\
|
2017-09-13 20:25:39 +02:00
|
|
|
[{\
|
2017-09-13 20:16:12 +02:00
|
|
|
tag (1-4294967295)\
|
|
|
|
|X:X::X:X/M$prefix longer-prefixes\
|
2017-09-13 20:25:39 +02:00
|
|
|
}]\
|
|
|
|
[" FRR_IP6_REDIST_STR_ZEBRA "$type_str]\
|
2017-09-13 20:16:12 +02:00
|
|
|
>\
|
|
|
|
[json$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"
|
2017-09-13 20:16:12 +02:00
|
|
|
VRF_FULL_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"
|
2017-09-13 20:16:12 +02:00
|
|
|
IPV6_STR
|
|
|
|
"IP forwarding table\n"
|
|
|
|
"IP routing table\n"
|
|
|
|
VRF_FULL_CMD_HELP_STR
|
|
|
|
"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
|
2017-05-22 21:56:11 +02:00
|
|
|
JSON_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-09-13 20:16:12 +02:00
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
2017-07-17 14:03:14 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
int type = 0;
|
|
|
|
|
2017-09-13 20:16:12 +02:00
|
|
|
if (type_str) {
|
|
|
|
type = proto_redistnum(afi, type_str);
|
2017-07-17 14:03:14 +02:00
|
|
|
if (type < 0) {
|
|
|
|
vty_out(vty, "Unknown route type\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vrf_all) {
|
2017-09-15 17:47:35 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-09-13 20:16:12 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
struct route_table *table;
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL
|
2017-09-13 20:16:12 +02:00
|
|
|
|| (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
|
2017-07-17 14:03:14 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
do_show_ip_route(
|
2017-09-13 20:16:12 +02:00
|
|
|
vty, zvrf_name(zvrf), afi, SAFI_UNICAST, !!fib,
|
|
|
|
!!json, tag, prefix_str ? prefix : NULL,
|
|
|
|
!!supernets_only, type, ospf_instance_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-09-13 20:16:12 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
|
|
|
if (vrf_name)
|
2018-07-27 16:09:38 +02:00
|
|
|
VRF_GET_ID(vrf_id, vrf_name, !!json);
|
2017-07-17 14:03:14 +02:00
|
|
|
vrf = vrf_lookup_by_id(vrf_id);
|
2017-09-13 20:16:12 +02:00
|
|
|
do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, !!fib,
|
|
|
|
!!json, tag, prefix_str ? prefix : NULL,
|
|
|
|
!!supernets_only, type, ospf_instance_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2017-09-13 20:16:12 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
DEFPY (show_route_detail,
|
|
|
|
show_route_detail_cmd,
|
|
|
|
"show\
|
|
|
|
<\
|
|
|
|
ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
|
|
|
|
<\
|
|
|
|
A.B.C.D$address\
|
|
|
|
|A.B.C.D/M$prefix\
|
|
|
|
>\
|
|
|
|
|ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
|
|
|
|
<\
|
|
|
|
X:X::X:X$address\
|
|
|
|
|X:X::X:X/M$prefix\
|
|
|
|
>\
|
2018-08-08 00:15:34 +02:00
|
|
|
>\
|
|
|
|
[json$json]",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2017-09-13 22:40:19 +02:00
|
|
|
VRF_FULL_CMD_HELP_STR
|
|
|
|
"Network in the IP routing table to display\n"
|
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
|
|
|
|
IP6_STR
|
|
|
|
"IP routing table\n"
|
|
|
|
VRF_FULL_CMD_HELP_STR
|
|
|
|
"IPv6 Address\n"
|
2018-08-08 00:15:34 +02:00
|
|
|
"IPv6 prefix\n"
|
|
|
|
JSON_STR)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-09-13 22:40:19 +02:00
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_table *table;
|
2017-09-13 22:40:19 +02:00
|
|
|
struct prefix p;
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_node *rn;
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
if (address_str)
|
|
|
|
prefix_str = address_str;
|
|
|
|
if (str2prefix(prefix_str, &p) < 0) {
|
|
|
|
vty_out(vty, "%% Malformed address\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
if (vrf_all) {
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-09-13 22:40:19 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL
|
|
|
|
|| (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rn = route_node_match(table, &p);
|
|
|
|
if (!rn)
|
|
|
|
continue;
|
|
|
|
if (!address_str && rn->p.prefixlen != p.prefixlen) {
|
|
|
|
route_unlock_node(rn);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-08-08 00:15:34 +02:00
|
|
|
if (json)
|
|
|
|
vty_show_ip_route_detail_json(vty, rn);
|
|
|
|
else
|
|
|
|
vty_show_ip_route_detail(vty, rn, 0);
|
2017-09-13 22:40:19 +02:00
|
|
|
|
|
|
|
route_unlock_node(rn);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
|
|
|
if (vrf_name)
|
2018-07-27 16:09:38 +02:00
|
|
|
VRF_GET_ID(vrf_id, vrf_name, false);
|
2017-09-13 22:40:19 +02:00
|
|
|
|
|
|
|
table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
|
|
|
|
if (!table)
|
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
rn = route_node_match(table, &p);
|
|
|
|
if (!rn) {
|
|
|
|
vty_out(vty, "%% Network not in table\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
if (!address_str && rn->p.prefixlen != p.prefixlen) {
|
|
|
|
vty_out(vty, "%% Network not in table\n");
|
|
|
|
route_unlock_node(rn);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2018-08-08 00:15:34 +02:00
|
|
|
if (json)
|
|
|
|
vty_show_ip_route_detail_json(vty, rn);
|
|
|
|
else
|
|
|
|
vty_show_ip_route_detail(vty, rn, 0);
|
2017-09-13 22:40:19 +02:00
|
|
|
|
|
|
|
route_unlock_node(rn);
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
DEFPY (show_route_summary,
|
|
|
|
show_route_summary_cmd,
|
|
|
|
"show\
|
|
|
|
<\
|
|
|
|
ip$ipv4 route [vrf <NAME$vrf_name|all$vrf_all>]\
|
|
|
|
summary [prefix$prefix]\
|
|
|
|
|ipv6$ipv6 route [vrf <NAME$vrf_name|all$vrf_all>]\
|
|
|
|
summary [prefix$prefix]\
|
|
|
|
>",
|
2015-05-22 11:40:06 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP routing table\n"
|
2017-09-13 22:40:19 +02:00
|
|
|
VRF_FULL_CMD_HELP_STR
|
|
|
|
"Summary of all routes\n"
|
|
|
|
"Prefix routes\n"
|
|
|
|
IP6_STR
|
|
|
|
"IP routing table\n"
|
|
|
|
VRF_FULL_CMD_HELP_STR
|
|
|
|
"Summary of all routes\n"
|
|
|
|
"Prefix routes\n")
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-09-13 22:40:19 +02:00
|
|
|
afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_table *table;
|
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
if (vrf_all) {
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
2016-02-28 23:03:27 +01:00
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-09-13 22:40:19 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL
|
|
|
|
|| (table = zvrf->table[afi][SAFI_UNICAST]) == NULL)
|
|
|
|
continue;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
if (prefix)
|
|
|
|
vty_show_ip_route_summary_prefix(vty, table);
|
|
|
|
else
|
|
|
|
vty_show_ip_route_summary(vty, table);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
if (vrf_name)
|
2018-07-27 16:09:38 +02:00
|
|
|
VRF_GET_ID(vrf_id, vrf_name, false);
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id);
|
|
|
|
if (!table)
|
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-09-13 22:40:19 +02:00
|
|
|
if (prefix)
|
|
|
|
vty_show_ip_route_summary_prefix(vty, table);
|
|
|
|
else
|
|
|
|
vty_show_ip_route_summary(vty, table);
|
|
|
|
}
|
2015-05-22 11:40:06 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:06 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static void vty_show_ip_route_summary(struct vty *vty,
|
|
|
|
struct route_table *table)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_node *rn;
|
|
|
|
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)
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
uint32_t i;
|
|
|
|
uint32_t is_ibgp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
memset(&rib_cnt, 0, sizeof(rib_cnt));
|
|
|
|
memset(&fib_cnt, 0, sizeof(fib_cnt));
|
|
|
|
for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
|
2017-09-15 17:47:35 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
2017-07-17 14:03:14 +02:00
|
|
|
is_ibgp = (re->type == ZEBRA_ROUTE_BGP
|
|
|
|
&& CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP));
|
|
|
|
|
|
|
|
rib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
|
|
|
if (is_ibgp)
|
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
else
|
|
|
|
rib_cnt[re->type]++;
|
|
|
|
|
|
|
|
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
|
|
|
|
fib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
|
|
|
|
|
|
|
if (is_ibgp)
|
|
|
|
fib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
else
|
|
|
|
fib_cnt[re->type]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source", "Routes",
|
2018-08-31 01:11:39 +02:00
|
|
|
"FIB", zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
2017-07-22 14:52:33 +02:00
|
|
|
if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP
|
|
|
|
&& rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (i == ZEBRA_ROUTE_BGP) {
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
|
|
|
|
rib_cnt[ZEBRA_ROUTE_BGP],
|
|
|
|
fib_cnt[ZEBRA_ROUTE_BGP]);
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
|
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP],
|
|
|
|
fib_cnt[ZEBRA_ROUTE_IBGP]);
|
|
|
|
} else
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n",
|
|
|
|
zebra_route_string(i), rib_cnt[i],
|
|
|
|
fib_cnt[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "------\n");
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
|
|
|
|
rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
|
|
|
|
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.
|
|
|
|
*
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
static void vty_show_ip_route_summary_prefix(struct vty *vty,
|
|
|
|
struct route_table *table)
|
2015-05-22 11:40:06 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_node *rn;
|
|
|
|
struct route_entry *re;
|
|
|
|
struct nexthop *nexthop;
|
2015-05-22 11:40:06 +02:00
|
|
|
#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX
|
|
|
|
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
|
|
|
|
uint32_t i;
|
2017-07-17 14:03:14 +02:00
|
|
|
int cnt;
|
|
|
|
|
|
|
|
memset(&rib_cnt, 0, sizeof(rib_cnt));
|
|
|
|
memset(&fib_cnt, 0, sizeof(fib_cnt));
|
|
|
|
for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
|
2017-09-15 17:47:35 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In case of ECMP, count only once.
|
|
|
|
*/
|
|
|
|
cnt = 0;
|
2019-01-14 22:37:53 +01:00
|
|
|
if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
|
|
|
|
fib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
|
|
|
fib_cnt[re->type]++;
|
|
|
|
}
|
2018-01-26 16:12:35 +01:00
|
|
|
for (nexthop = re->ng.nexthop; (!cnt && nexthop);
|
2017-07-17 14:03:14 +02:00
|
|
|
nexthop = nexthop->next) {
|
|
|
|
cnt++;
|
|
|
|
rib_cnt[ZEBRA_ROUTE_TOTAL]++;
|
|
|
|
rib_cnt[re->type]++;
|
|
|
|
if (re->type == ZEBRA_ROUTE_BGP
|
|
|
|
&& CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
|
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP]++;
|
2019-01-14 22:37:53 +01:00
|
|
|
if (CHECK_FLAG(re->status,
|
|
|
|
ROUTE_ENTRY_INSTALLED))
|
2017-07-17 14:03:14 +02:00
|
|
|
fib_cnt[ZEBRA_ROUTE_IBGP]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "%-20s %-20s %s (vrf %s)\n", "Route Source",
|
|
|
|
"Prefix Routes", "FIB",
|
2018-08-31 01:11:39 +02:00
|
|
|
zvrf_name(((rib_table_info_t *)route_table_get_info(table))->zvrf));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
|
|
|
if (rib_cnt[i] > 0) {
|
|
|
|
if (i == ZEBRA_ROUTE_BGP) {
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n", "ebgp",
|
|
|
|
rib_cnt[ZEBRA_ROUTE_BGP]
|
|
|
|
- rib_cnt[ZEBRA_ROUTE_IBGP],
|
|
|
|
fib_cnt[ZEBRA_ROUTE_BGP]
|
|
|
|
- fib_cnt[ZEBRA_ROUTE_IBGP]);
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n", "ibgp",
|
|
|
|
rib_cnt[ZEBRA_ROUTE_IBGP],
|
|
|
|
fib_cnt[ZEBRA_ROUTE_IBGP]);
|
|
|
|
} else
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n",
|
|
|
|
zebra_route_string(i), rib_cnt[i],
|
|
|
|
fib_cnt[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out(vty, "------\n");
|
|
|
|
vty_out(vty, "%-20s %-20d %-20d \n", "Totals",
|
|
|
|
rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL]);
|
|
|
|
vty_out(vty, "\n");
|
2015-05-20 02:24:41 +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
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct route_entry *re;
|
|
|
|
int first = 1;
|
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
|
|
|
if (argc == 5)
|
2018-07-27 16:09:38 +02:00
|
|
|
VRF_GET_ID(vrf_id, argv[4]->arg, false);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id);
|
|
|
|
if (!table)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
/* Show all IPv6 route. */
|
|
|
|
for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
|
2017-09-15 17:47:35 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (first) {
|
|
|
|
vty_out(vty, SHOW_ROUTE_V6_HEADER);
|
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
vty_show_ip_route(vty, rn, re, NULL);
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
2011-11-26 18:59:32 +01:00
|
|
|
}
|
|
|
|
|
2015-05-22 11:40:03 +02:00
|
|
|
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)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct route_table *table;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct route_entry *re;
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
int first = 1;
|
|
|
|
|
2017-09-15 17:47:35 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if ((zvrf = vrf->info) == NULL
|
|
|
|
|| (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Show all IPv6 route. */
|
|
|
|
for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
|
2017-09-15 17:47:35 +02:00
|
|
|
RNODE_FOREACH_RE (rn, re) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (first) {
|
|
|
|
vty_out(vty, SHOW_ROUTE_V6_HEADER);
|
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
vty_show_ip_route(vty, rn, re, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
2015-05-22 11:40:03 +02:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
allow_delete = 1;
|
2015-08-26 14:21:40 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-08-26 14:21:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
allow_delete = 0;
|
2015-08-26 14:21:40 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2015-08-26 14:21:40 +02:00
|
|
|
}
|
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
/* show vrf */
|
|
|
|
DEFUN (show_vrf,
|
|
|
|
show_vrf_cmd,
|
|
|
|
"show vrf",
|
|
|
|
SHOW_STR
|
|
|
|
"VRF\n")
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2018-05-10 10:05:28 +02:00
|
|
|
if (vrf_is_backend_netns())
|
|
|
|
vty_out(vty, "netns-based vrfs\n");
|
|
|
|
|
2017-09-15 17:47:35 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!(zvrf = vrf->info))
|
|
|
|
continue;
|
2018-01-22 09:38:45 +01:00
|
|
|
if (zvrf_id(zvrf) == VRF_DEFAULT)
|
2017-07-17 14:03:14 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
vty_out(vty, "vrf %s ", zvrf_name(zvrf));
|
2018-03-06 20:02:52 +01:00
|
|
|
if (zvrf_id(zvrf) == VRF_UNKNOWN || !zvrf_is_active(zvrf))
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "inactive");
|
2017-12-07 15:58:48 +01:00
|
|
|
else if (zvrf_ns_name(zvrf))
|
2018-03-06 20:02:52 +01:00
|
|
|
vty_out(vty, "id %u netns %s", zvrf_id(zvrf),
|
|
|
|
zvrf_ns_name(zvrf));
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
|
|
|
vty_out(vty, "id %u table %u", zvrf_id(zvrf),
|
|
|
|
zvrf->table_id);
|
2017-12-07 00:19:11 +01:00
|
|
|
if (vrf_is_user_cfged(vrf))
|
|
|
|
vty_out(vty, " (configured)");
|
2017-07-17 14:03:14 +02:00
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-02-01 19:55:42 +01:00
|
|
|
}
|
|
|
|
|
2018-06-16 00:23:27 +02:00
|
|
|
DEFUN_HIDDEN (default_vrf_vni_mapping,
|
2017-11-18 09:50:46 +01:00
|
|
|
default_vrf_vni_mapping_cmd,
|
2018-02-06 23:28:22 +01:00
|
|
|
"vni " CMD_VNI_RANGE "[prefix-routes-only]",
|
2017-11-18 09:50:46 +01:00
|
|
|
"VNI corresponding to the DEFAULT VRF\n"
|
2018-02-06 23:28:22 +01:00
|
|
|
"VNI-ID\n"
|
|
|
|
"Prefix routes only \n")
|
2017-11-18 09:50:46 +01:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
char err[ERR_STR_SZ];
|
|
|
|
struct zebra_vrf *zvrf = NULL;
|
|
|
|
vni_t vni = strtoul(argv[1]->arg, NULL, 10);
|
2018-02-06 23:28:22 +01:00
|
|
|
int filter = 0;
|
2017-11-18 09:50:46 +01:00
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
if (!zvrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2018-02-06 23:28:22 +01:00
|
|
|
if (argc == 3)
|
|
|
|
filter = 1;
|
|
|
|
|
|
|
|
ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
|
|
|
|
filter, 1);
|
2017-11-18 09:50:46 +01:00
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "%s\n", err);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-06-16 00:23:27 +02:00
|
|
|
DEFUN_HIDDEN (no_default_vrf_vni_mapping,
|
2017-11-18 09:50:46 +01:00
|
|
|
no_default_vrf_vni_mapping_cmd,
|
|
|
|
"no vni " CMD_VNI_RANGE,
|
|
|
|
NO_STR
|
|
|
|
"VNI corresponding to DEFAULT VRF\n"
|
|
|
|
"VNI-ID")
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
char err[ERR_STR_SZ];
|
|
|
|
vni_t vni = strtoul(argv[2]->arg, NULL, 10);
|
|
|
|
struct zebra_vrf *zvrf = NULL;
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
if (!zvrf)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
2018-02-06 23:28:22 +01:00
|
|
|
ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ, 0, 0);
|
2017-11-18 09:50:46 +01:00
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "%s\n", err);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-10-08 03:49:27 +02:00
|
|
|
DEFUN (vrf_vni_mapping,
|
|
|
|
vrf_vni_mapping_cmd,
|
2018-02-06 23:28:22 +01:00
|
|
|
"vni " CMD_VNI_RANGE "[prefix-routes-only]",
|
2017-11-18 09:50:46 +01:00
|
|
|
"VNI corresponding to tenant VRF\n"
|
2018-02-06 23:28:22 +01:00
|
|
|
"VNI-ID\n"
|
|
|
|
"prefix-routes-only\n")
|
2017-10-08 03:49:27 +02:00
|
|
|
{
|
|
|
|
int ret = 0;
|
2018-02-06 23:28:22 +01:00
|
|
|
int filter = 0;
|
2017-10-08 03:49:27 +02:00
|
|
|
|
|
|
|
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
|
|
|
|
vni_t vni = strtoul(argv[1]->arg, NULL, 10);
|
|
|
|
char err[ERR_STR_SZ];
|
|
|
|
|
|
|
|
assert(vrf);
|
|
|
|
assert(zvrf);
|
|
|
|
|
2018-02-06 23:28:22 +01:00
|
|
|
if (argc == 3)
|
|
|
|
filter = 1;
|
|
|
|
|
2018-01-18 19:27:26 +01:00
|
|
|
/* Mark as having FRR configuration */
|
|
|
|
vrf_set_user_cfged(vrf);
|
2018-02-06 23:28:22 +01:00
|
|
|
ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err, ERR_STR_SZ,
|
|
|
|
filter, 1);
|
2017-10-08 03:49:27 +02:00
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "%s\n", err);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_vrf_vni_mapping,
|
|
|
|
no_vrf_vni_mapping_cmd,
|
2018-04-10 10:37:21 +02:00
|
|
|
"no vni " CMD_VNI_RANGE "[prefix-routes-only]",
|
2017-10-08 03:49:27 +02:00
|
|
|
NO_STR
|
2017-11-18 09:50:46 +01:00
|
|
|
"VNI corresponding to tenant VRF\n"
|
2018-04-10 10:37:21 +02:00
|
|
|
"VNI-ID\n"
|
|
|
|
"prefix-routes-only\n")
|
2017-10-08 03:49:27 +02:00
|
|
|
{
|
|
|
|
int ret = 0;
|
2018-04-10 10:37:21 +02:00
|
|
|
int filter = 0;
|
2017-10-08 03:49:27 +02:00
|
|
|
char err[ERR_STR_SZ];
|
|
|
|
vni_t vni = strtoul(argv[2]->arg, NULL, 10);
|
|
|
|
|
|
|
|
ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
|
|
|
|
|
|
|
|
assert(vrf);
|
|
|
|
assert(zvrf);
|
|
|
|
|
2018-04-10 10:37:21 +02:00
|
|
|
if (argc == 4)
|
|
|
|
filter = 1;
|
|
|
|
|
|
|
|
ret = zebra_vxlan_process_vrf_vni_cmd(zvrf, vni, err,
|
|
|
|
ERR_STR_SZ, filter, 0);
|
2017-10-08 03:49:27 +02:00
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "%s\n", err);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2017-12-07 00:19:11 +01:00
|
|
|
/* If no other FRR config for this VRF, mark accordingly. */
|
|
|
|
if (!zebra_vrf_has_config(zvrf))
|
|
|
|
vrf_reset_user_cfged(vrf);
|
|
|
|
|
2017-10-08 03:49:27 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* show vrf */
|
|
|
|
DEFUN (show_vrf_vni,
|
|
|
|
show_vrf_vni_cmd,
|
2017-10-17 11:30:42 +02:00
|
|
|
"show vrf vni [json]",
|
2017-10-08 03:49:27 +02:00
|
|
|
SHOW_STR
|
|
|
|
"VRF\n"
|
2017-10-17 11:30:42 +02:00
|
|
|
"VNI\n"
|
|
|
|
JSON_STR)
|
2017-10-08 03:49:27 +02:00
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
struct zebra_vrf *zvrf;
|
2017-10-17 11:30:42 +02:00
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_vrfs = NULL;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-17 11:30:42 +02:00
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json = json_object_new_object();
|
|
|
|
json_vrfs = json_object_new_array();
|
|
|
|
}
|
2017-10-08 03:49:27 +02:00
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
if (!uj)
|
2018-03-06 20:02:52 +01:00
|
|
|
vty_out(vty, "%-37s %-10s %-20s %-20s %-5s %-18s\n", "VRF",
|
|
|
|
"VNI", "VxLAN IF", "L3-SVI", "State", "Rmac");
|
2017-11-15 10:01:00 +01:00
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-10-08 03:49:27 +02:00
|
|
|
zvrf = vrf->info;
|
|
|
|
if (!zvrf)
|
|
|
|
continue;
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
zebra_vxlan_print_vrf_vni(vty, zvrf, json_vrfs);
|
2017-10-17 11:30:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_add(json, "vrfs", json_vrfs);
|
|
|
|
vty_out(vty, "%s\n", json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
|
|
json_object_free(json);
|
2017-10-08 03:49:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_global,
|
|
|
|
show_evpn_global_cmd,
|
|
|
|
"show evpn [json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-11-15 10:01:00 +01:00
|
|
|
|
|
|
|
zebra_vxlan_print_evpn(vty, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
DEFUN (show_evpn_vni,
|
|
|
|
show_evpn_vni_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn vni [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
2018-11-15 18:33:43 +01:00
|
|
|
"VxLAN Network Identifier\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_vnis(vty, zvrf, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
2018-11-15 18:33:43 +01:00
|
|
|
DEFUN (show_evpn_vni_detail, show_evpn_vni_detail_cmd,
|
|
|
|
"show evpn vni detail [json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"Detailed Information On Each VNI\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
zebra_vxlan_print_vnis_detail(vty, zvrf, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
DEFUN (show_evpn_vni_vni,
|
|
|
|
show_evpn_vni_vni_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn vni " CMD_VNI_RANGE "[json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"VNI number\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[3]->arg, NULL, 10);
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_vni(vty, zvrf, vni, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_rmac_vni_mac,
|
|
|
|
show_evpn_rmac_vni_mac_cmd,
|
|
|
|
"show evpn rmac vni " CMD_VNI_RANGE " mac WORD [json]",
|
2017-10-17 01:51:32 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"RMAC\n"
|
2017-11-15 10:01:00 +01:00
|
|
|
"L3 VNI\n"
|
2017-10-17 01:51:32 +02:00
|
|
|
"VNI number\n"
|
|
|
|
"MAC\n"
|
2017-10-17 14:25:47 +02:00
|
|
|
"mac-address (e.g. 0a:0a:0a:0a:0a:0a)\n"
|
|
|
|
JSON_STR)
|
2017-10-17 01:51:32 +02:00
|
|
|
{
|
|
|
|
vni_t l3vni = 0;
|
|
|
|
struct ethaddr mac;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-17 01:51:32 +02:00
|
|
|
|
|
|
|
l3vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
if (!prefix_str2mac(argv[6]->arg, &mac)) {
|
|
|
|
vty_out(vty, "%% Malformed MAC address\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2017-10-17 14:25:47 +02:00
|
|
|
zebra_vxlan_print_specific_rmac_l3vni(vty, l3vni, &mac, uj);
|
2017-10-17 01:51:32 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_rmac_vni,
|
|
|
|
show_evpn_rmac_vni_cmd,
|
|
|
|
"show evpn rmac vni " CMD_VNI_RANGE "[json]",
|
2017-10-08 03:49:27 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"RMAC\n"
|
2017-11-15 10:01:00 +01:00
|
|
|
"L3 VNI\n"
|
2017-10-08 03:49:27 +02:00
|
|
|
"VNI number\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
vni_t l3vni = 0;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-08 03:49:27 +02:00
|
|
|
|
|
|
|
l3vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
zebra_vxlan_print_rmacs_l3vni(vty, l3vni, uj);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_rmac_vni_all,
|
|
|
|
show_evpn_rmac_vni_all_cmd,
|
|
|
|
"show evpn rmac vni all [json]",
|
2017-10-08 03:49:27 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"RMAC addresses\n"
|
2017-11-15 10:01:00 +01:00
|
|
|
"L3 VNI\n"
|
2017-10-08 03:49:27 +02:00
|
|
|
"All VNIs\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-08 03:49:27 +02:00
|
|
|
|
|
|
|
zebra_vxlan_print_rmacs_all_l3vni(vty, uj);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_nh_vni_ip,
|
|
|
|
show_evpn_nh_vni_ip_cmd,
|
|
|
|
"show evpn next-hops vni " CMD_VNI_RANGE " ip WORD [json]",
|
2017-10-17 01:51:32 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"Remote Vteps\n"
|
2017-11-15 10:01:00 +01:00
|
|
|
"L3 VNI\n"
|
2017-10-17 01:51:32 +02:00
|
|
|
"VNI number\n"
|
|
|
|
"Ip address\n"
|
2017-10-17 13:32:31 +02:00
|
|
|
"Host address (ipv4 or ipv6)\n"
|
|
|
|
JSON_STR)
|
2017-10-17 01:51:32 +02:00
|
|
|
{
|
|
|
|
vni_t l3vni;
|
|
|
|
struct ipaddr ip;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-17 01:51:32 +02:00
|
|
|
|
|
|
|
l3vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
if (str2ipaddr(argv[6]->arg, &ip) != 0) {
|
|
|
|
if (!uj)
|
|
|
|
vty_out(vty, "%% Malformed Neighbor address\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2017-10-17 13:32:31 +02:00
|
|
|
zebra_vxlan_print_specific_nh_l3vni(vty, l3vni, &ip, uj);
|
2017-10-17 01:51:32 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_nh_vni,
|
|
|
|
show_evpn_nh_vni_cmd,
|
|
|
|
"show evpn next-hops vni " CMD_VNI_RANGE "[json]",
|
2017-10-08 03:49:27 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"Remote Vteps\n"
|
2017-11-15 10:01:00 +01:00
|
|
|
"L3 VNI\n"
|
2017-10-08 03:49:27 +02:00
|
|
|
"VNI number\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
vni_t l3vni;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-08 03:49:27 +02:00
|
|
|
|
|
|
|
l3vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
zebra_vxlan_print_nh_l3vni(vty, l3vni, uj);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
DEFUN (show_evpn_nh_vni_all,
|
|
|
|
show_evpn_nh_vni_all_cmd,
|
|
|
|
"show evpn next-hops vni all [json]",
|
2017-10-08 03:49:27 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"Remote VTEPs\n"
|
2017-11-15 10:01:00 +01:00
|
|
|
"L3 VNI\n"
|
2017-10-08 03:49:27 +02:00
|
|
|
"All VNIs\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-10-08 03:49:27 +02:00
|
|
|
|
|
|
|
zebra_vxlan_print_nh_all_l3vni(vty, uj);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
DEFUN (show_evpn_mac_vni,
|
|
|
|
show_evpn_mac_vni_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn mac vni " CMD_VNI_RANGE "[json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"VNI number\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_evpn_mac_vni_all,
|
|
|
|
show_evpn_mac_vni_all_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn mac vni all [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"All VNIs\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2018-11-04 19:17:29 +01:00
|
|
|
zebra_vxlan_print_macs_all_vni(vty, zvrf, false, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
2018-11-22 09:18:10 +01:00
|
|
|
DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
|
|
|
|
"show evpn mac vni all detail [json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"All VNIs\n"
|
|
|
|
"Detailed Information On Each VNI MAC\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
DEFUN (show_evpn_mac_vni_all_vtep,
|
|
|
|
show_evpn_mac_vni_all_vtep_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn mac vni all vtep A.B.C.D [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"All VNIs\n"
|
|
|
|
"Remote VTEP\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"Remote VTEP IP address\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
struct in_addr vtep_ip;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!inet_aton(argv[6]->arg, &vtep_ip)) {
|
2017-06-22 01:37:51 +02:00
|
|
|
if (!uj)
|
|
|
|
vty_out(vty, "%% Malformed VTEP IP address\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (show_evpn_mac_vni_mac,
|
|
|
|
show_evpn_mac_vni_mac_cmd,
|
2018-10-26 22:57:23 +02:00
|
|
|
"show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"MAC\n"
|
2018-10-26 22:57:23 +02:00
|
|
|
"MAC address (e.g., 00:e0:ec:20:12:62)\n"
|
|
|
|
JSON_STR)
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
|
|
|
struct ethaddr mac;
|
2018-10-26 22:57:23 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
if (!prefix_str2mac(argv[6]->arg, &mac)) {
|
|
|
|
vty_out(vty, "%% Malformed MAC address");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2018-10-26 22:57:23 +02:00
|
|
|
zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_evpn_mac_vni_vtep,
|
|
|
|
show_evpn_mac_vni_vtep_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"Remote VTEP\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"Remote VTEP IP address\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
|
|
|
struct in_addr vtep_ip;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
if (!inet_aton(argv[6]->arg, &vtep_ip)) {
|
2017-06-22 01:37:51 +02:00
|
|
|
if (!uj)
|
|
|
|
vty_out(vty, "%% Malformed VTEP IP address\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
2018-11-04 19:17:29 +01:00
|
|
|
DEFPY (show_evpn_mac_vni_all_dad,
|
|
|
|
show_evpn_mac_vni_all_dad_cmd,
|
|
|
|
"show evpn mac vni all duplicate [json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"All VNIs\n"
|
|
|
|
"Duplicate address list\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
zebra_vxlan_print_macs_all_vni(vty, zvrf, true, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFPY (show_evpn_mac_vni_dad,
|
|
|
|
show_evpn_mac_vni_dad_cmd,
|
|
|
|
"show evpn mac vni " CMD_VNI_RANGE " duplicate" "[json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"MAC addresses\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"Duplicate address list\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
|
|
|
|
zebra_vxlan_print_macs_vni_dad(vty, zvrf, vni, uj);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (show_evpn_neigh_vni_dad,
|
|
|
|
show_evpn_neigh_vni_dad_cmd,
|
|
|
|
"show evpn arp-cache vni " CMD_VNI_RANGE "duplicate" "[json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"Duplicate address list\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
zebra_vxlan_print_neigh_vni_dad(vty, zvrf, vni, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (show_evpn_neigh_vni_all_dad,
|
|
|
|
show_evpn_neigh_vni_all_dad_cmd,
|
|
|
|
"show evpn arp-cache vni all duplicate [json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"All VNIs\n"
|
|
|
|
"Duplicate address list\n"
|
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
zebra_vxlan_print_neigh_all_vni(vty, zvrf, true, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
DEFUN (show_evpn_neigh_vni,
|
|
|
|
show_evpn_neigh_vni_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"VNI number\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_evpn_neigh_vni_all,
|
|
|
|
show_evpn_neigh_vni_all_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn arp-cache vni all [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"All VNIs\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2018-11-04 19:17:29 +01:00
|
|
|
zebra_vxlan_print_neigh_all_vni(vty, zvrf, false, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
2018-11-22 10:56:52 +01:00
|
|
|
DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
|
|
|
|
"show evpn arp-cache vni all detail [json]",
|
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"All VNIs\n"
|
|
|
|
"Neighbor details for all vnis in detail\n" JSON_STR)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, uj);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-15 07:45:55 +02:00
|
|
|
DEFUN (show_evpn_neigh_vni_neigh,
|
|
|
|
show_evpn_neigh_vni_neigh_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"Neighbor\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"Neighbor address (IPv4 or IPv6 address)\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
|
|
|
struct ipaddr ip;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
if (str2ipaddr(argv[6]->arg, &ip) != 0) {
|
2017-06-22 01:37:51 +02:00
|
|
|
if (!uj)
|
|
|
|
vty_out(vty, "%% Malformed Neighbor address\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_evpn_neigh_vni_vtep,
|
|
|
|
show_evpn_neigh_vni_vtep_cmd,
|
2017-06-22 01:37:51 +02:00
|
|
|
"show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
|
2017-05-15 07:45:55 +02:00
|
|
|
SHOW_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"ARP and ND cache\n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"Remote VTEP\n"
|
2017-06-22 01:37:51 +02:00
|
|
|
"Remote VTEP IP address\n"
|
2017-07-25 14:17:31 +02:00
|
|
|
JSON_STR)
|
2017-05-15 07:45:55 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni;
|
|
|
|
struct in_addr vtep_ip;
|
2018-08-29 14:19:54 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
vni = strtoul(argv[4]->arg, NULL, 10);
|
|
|
|
if (!inet_aton(argv[6]->arg, &vtep_ip)) {
|
2017-06-22 01:37:51 +02:00
|
|
|
if (!uj)
|
|
|
|
vty_out(vty, "%% Malformed VTEP IP address\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2017-05-15 07:45:55 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
2017-06-22 01:37:51 +02:00
|
|
|
zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-05-15 07:45:55 +02:00
|
|
|
}
|
|
|
|
|
2018-04-23 15:17:19 +02:00
|
|
|
/* policy routing contexts */
|
|
|
|
DEFUN (show_pbr_ipset,
|
|
|
|
show_pbr_ipset_cmd,
|
|
|
|
"show pbr ipset [WORD]",
|
|
|
|
SHOW_STR
|
|
|
|
"Policy-Based Routing\n"
|
|
|
|
"IPset Context information\n"
|
|
|
|
"IPset Name information\n")
|
|
|
|
{
|
|
|
|
int idx = 0;
|
|
|
|
int found = 0;
|
|
|
|
found = argv_find(argv, argc, "WORD", &idx);
|
|
|
|
if (!found)
|
|
|
|
zebra_pbr_show_ipset_list(vty, NULL);
|
|
|
|
else
|
|
|
|
zebra_pbr_show_ipset_list(vty, argv[idx]->arg);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* policy routing contexts */
|
|
|
|
DEFUN (show_pbr_iptable,
|
|
|
|
show_pbr_iptable_cmd,
|
2018-06-29 13:45:01 +02:00
|
|
|
"show pbr iptable [WORD]",
|
2018-04-23 15:17:19 +02:00
|
|
|
SHOW_STR
|
|
|
|
"Policy-Based Routing\n"
|
2018-06-29 13:45:01 +02:00
|
|
|
"IPtable Context information\n"
|
|
|
|
"IPtable Name information\n")
|
2018-04-23 15:17:19 +02:00
|
|
|
{
|
2018-06-29 13:45:01 +02:00
|
|
|
int idx = 0;
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
found = argv_find(argv, argc, "WORD", &idx);
|
|
|
|
if (!found)
|
|
|
|
zebra_pbr_show_iptable(vty, NULL);
|
|
|
|
else
|
|
|
|
zebra_pbr_show_iptable(vty, argv[idx]->arg);
|
2018-04-23 15:17:19 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-11-04 19:55:39 +01:00
|
|
|
DEFPY (clear_evpn_dup_addr,
|
|
|
|
clear_evpn_dup_addr_cmd,
|
|
|
|
"clear evpn dup-addr vni <all$vni_all |" CMD_VNI_RANGE"$vni_val [mac M:A:C$mac_val | ip <A.B.C.D|X:X::X:X>]>",
|
|
|
|
CLEAR_STR
|
|
|
|
"EVPN\n"
|
|
|
|
"Duplicate address \n"
|
|
|
|
"VxLAN Network Identifier\n"
|
|
|
|
"VNI number\n"
|
|
|
|
"All VNIs\n"
|
|
|
|
"MAC\n"
|
|
|
|
"MAC address (e.g., 00:e0:ec:20:12:62)\n"
|
|
|
|
"IP\n"
|
|
|
|
"IPv4 address\n"
|
|
|
|
"IPv6 address\n")
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
vni_t vni = 0;
|
|
|
|
struct ipaddr host_ip = {.ipa_type = IPADDR_NONE };
|
|
|
|
struct ethaddr mac_addr;
|
2018-12-03 04:08:22 +01:00
|
|
|
int ret = CMD_SUCCESS;
|
2018-11-04 19:55:39 +01:00
|
|
|
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
if (vni_val) {
|
|
|
|
vni = strtoul(vni_val, NULL, 10);
|
|
|
|
|
|
|
|
if (mac_val) {
|
|
|
|
prefix_str2mac(mac_val, &mac_addr);
|
2018-12-03 04:08:22 +01:00
|
|
|
ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf,
|
|
|
|
vni,
|
|
|
|
&mac_addr);
|
|
|
|
} else if (ip) {
|
2018-11-04 19:55:39 +01:00
|
|
|
if (sockunion_family(ip) == AF_INET) {
|
|
|
|
host_ip.ipa_type = IPADDR_V4;
|
|
|
|
host_ip.ipaddr_v4.s_addr = sockunion2ip(ip);
|
|
|
|
} else {
|
|
|
|
host_ip.ipa_type = IPADDR_V6;
|
|
|
|
memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr,
|
|
|
|
sizeof(struct in6_addr));
|
|
|
|
}
|
2018-12-03 04:08:22 +01:00
|
|
|
ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf,
|
|
|
|
vni,
|
|
|
|
&host_ip);
|
2018-11-04 19:55:39 +01:00
|
|
|
} else
|
2018-12-03 04:08:22 +01:00
|
|
|
ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni);
|
2018-11-04 19:55:39 +01:00
|
|
|
|
|
|
|
} else {
|
2018-12-03 04:08:22 +01:00
|
|
|
ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf);
|
2018-11-04 19:55:39 +01:00
|
|
|
}
|
|
|
|
|
2018-12-03 04:08:22 +01:00
|
|
|
return ret;
|
2018-11-04 19:55:39 +01:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Static ip route configuration write function. */
|
2017-07-17 14:03:14 +02:00
|
|
|
static int zebra_ip_config(struct vty *vty)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
int write = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
write += zebra_import_table_config(vty);
|
2018-01-10 15:48:54 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return write;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
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")
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t table_id = 0;
|
2016-05-11 17:47:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
table_id = strtoul(argv[2]->arg, NULL, 10);
|
|
|
|
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;
|
|
|
|
int ret;
|
2017-06-10 22:39:41 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (argc == 7 || (argc == 5 && !rmap))
|
|
|
|
distance = strtoul(argv[4]->arg, NULL, 10);
|
2016-05-11 17:47:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!is_zebra_valid_kernel_table(table_id)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Invalid routing table ID, %d. Must be in range 1-252\n",
|
|
|
|
table_id);
|
2017-08-25 02:43:29 +02:00
|
|
|
if (rmap)
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2016-05-11 17:47:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (is_zebra_main_routing_table(table_id)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Invalid routing table ID, %d. Must be non-default table\n",
|
|
|
|
table_id);
|
2017-08-25 02:43:29 +02:00
|
|
|
if (rmap)
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
|
2017-07-17 14:03:14 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2016-05-11 17:47:02 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1);
|
|
|
|
if (rmap)
|
|
|
|
XFREE(MTYPE_ROUTE_MAP_NAME, rmap);
|
2017-06-10 22:39:41 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return ret;
|
2016-05-11 17:47:02 +02:00
|
|
|
}
|
|
|
|
|
2017-10-25 17:13:42 +02:00
|
|
|
DEFUN_HIDDEN (zebra_packet_process,
|
|
|
|
zebra_packet_process_cmd,
|
|
|
|
"zebra zapi-packets (1-10000)",
|
|
|
|
ZEBRA_STR
|
|
|
|
"Zapi Protocol\n"
|
|
|
|
"Number of packets to process before relinquishing thread\n")
|
|
|
|
{
|
|
|
|
uint32_t packets = strtoul(argv[2]->arg, NULL, 10);
|
|
|
|
|
2019-01-11 21:35:45 +01:00
|
|
|
atomic_store_explicit(&zrouter.packets_to_process, packets,
|
2018-04-27 00:30:26 +02:00
|
|
|
memory_order_relaxed);
|
2017-10-25 17:13:42 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_HIDDEN (no_zebra_packet_process,
|
|
|
|
no_zebra_packet_process_cmd,
|
|
|
|
"no zebra zapi-packets [(1-10000)]",
|
|
|
|
NO_STR
|
|
|
|
ZEBRA_STR
|
|
|
|
"Zapi Protocol\n"
|
|
|
|
"Number of packets to process before relinquishing thread\n")
|
|
|
|
{
|
2019-01-11 21:35:45 +01:00
|
|
|
atomic_store_explicit(&zrouter.packets_to_process,
|
2018-04-27 00:30:26 +02:00
|
|
|
ZEBRA_ZAPI_PACKETS_TO_PROCESS,
|
|
|
|
memory_order_relaxed);
|
2017-10-25 17:13:42 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-10-25 16:47:55 +02:00
|
|
|
DEFUN_HIDDEN (zebra_workqueue_timer,
|
|
|
|
zebra_workqueue_timer_cmd,
|
|
|
|
"zebra work-queue (0-10000)",
|
|
|
|
ZEBRA_STR
|
|
|
|
"Work Queue\n"
|
|
|
|
"Time in milliseconds\n")
|
|
|
|
{
|
2018-03-06 20:02:52 +01:00
|
|
|
uint32_t timer = strtoul(argv[2]->arg, NULL, 10);
|
2019-01-11 21:11:38 +01:00
|
|
|
zrouter.ribq->spec.hold = timer;
|
2017-10-25 16:47:55 +02:00
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
return CMD_SUCCESS;
|
2017-10-25 16:47:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN_HIDDEN (no_zebra_workqueue_timer,
|
|
|
|
no_zebra_workqueue_timer_cmd,
|
|
|
|
"no zebra work-queue [(0-10000)]",
|
|
|
|
NO_STR
|
|
|
|
ZEBRA_STR
|
|
|
|
"Work Queue\n"
|
|
|
|
"Time in milliseconds\n")
|
|
|
|
{
|
2019-01-11 21:11:38 +01:00
|
|
|
zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
|
2017-10-25 16:47:55 +02:00
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
return CMD_SUCCESS;
|
2017-10-25 16:47:55 +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
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t table_id = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
table_id = strtoul(argv[3]->arg, NULL, 10);
|
2015-05-20 03:03:42 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!is_zebra_valid_kernel_table(table_id)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Invalid routing table ID. Must be in range 1-252\n");
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-05-20 03:03:42 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (is_zebra_main_routing_table(table_id)) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Invalid routing table ID, %d. Must be non-default table\n",
|
|
|
|
table_id);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2015-05-20 03:03:42 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (!is_zebra_import_table_enabled(AFI_IP, table_id))
|
|
|
|
return CMD_SUCCESS;
|
2015-05-20 03:03:42 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));
|
2015-05-20 03:03:42 +02:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
static int config_write_protocol(struct vty *vty)
|
2015-08-26 14:21:40 +02:00
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
if (allow_delete)
|
|
|
|
vty_out(vty, "allow-external-route-update\n");
|
2015-08-26 14:21:40 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (zebra_rnh_ip_default_route)
|
|
|
|
vty_out(vty, "ip nht resolve-via-default\n");
|
2015-08-26 14:21:40 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (zebra_rnh_ipv6_default_route)
|
|
|
|
vty_out(vty, "ipv6 nht resolve-via-default\n");
|
2015-08-26 14:21:40 +02:00
|
|
|
|
2019-01-11 21:11:38 +01:00
|
|
|
if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME)
|
|
|
|
vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold);
|
2017-10-25 16:47:55 +02:00
|
|
|
|
2019-01-11 21:35:45 +01:00
|
|
|
if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS)
|
2018-03-06 20:02:52 +01:00
|
|
|
vty_out(vty, "zebra zapi-packets %u\n",
|
2019-01-11 21:35:45 +01:00
|
|
|
zrouter.packets_to_process);
|
2017-10-25 17:13:42 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get();
|
2015-01-06 19:53:24 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
if (ipv4_multicast_mode != MCAST_NO_CONFIG)
|
|
|
|
vty_out(vty, "ip multicast rpf-lookup-mode %s\n",
|
|
|
|
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");
|
|
|
|
return 1;
|
2015-08-26 14:21:40 +02:00
|
|
|
}
|
|
|
|
|
2017-12-07 16:47:30 +01:00
|
|
|
#ifdef HAVE_NETLINK
|
|
|
|
/* Display default rtm_table for all clients. */
|
|
|
|
DEFUN (show_table,
|
|
|
|
show_table_cmd,
|
|
|
|
"show table",
|
|
|
|
SHOW_STR
|
|
|
|
"default routing table to use for all clients\n")
|
|
|
|
{
|
2019-01-11 20:59:36 +01:00
|
|
|
vty_out(vty, "table %d\n", zrouter.rtm_table_default);
|
2017-12-07 16:47:30 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (config_table,
|
|
|
|
config_table_cmd,
|
|
|
|
"table TABLENO",
|
|
|
|
"Configure target kernel routing table\n"
|
|
|
|
"TABLE integer\n")
|
|
|
|
{
|
2019-01-11 20:59:36 +01:00
|
|
|
zrouter.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10);
|
2017-12-07 16:47:30 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_config_table,
|
|
|
|
no_config_table_cmd,
|
|
|
|
"no table [TABLENO]",
|
|
|
|
NO_STR
|
|
|
|
"Configure target kernel routing table\n"
|
|
|
|
"TABLE integer\n")
|
|
|
|
{
|
2019-01-11 20:59:36 +01:00
|
|
|
zrouter.rtm_table_default = 0;
|
2017-12-07 16:47:30 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DEFUN (show_zebra,
|
|
|
|
show_zebra_cmd,
|
|
|
|
"show zebra",
|
|
|
|
SHOW_STR
|
|
|
|
ZEBRA_STR)
|
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
" Route Route Neighbor LSP LSP\n");
|
|
|
|
vty_out(vty,
|
|
|
|
"VRF Installs Removals Updates Installs Removals\n");
|
|
|
|
|
2018-03-06 20:02:52 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
2017-12-07 16:47:30 +01:00
|
|
|
struct zebra_vrf *zvrf = vrf->info;
|
|
|
|
|
|
|
|
vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64
|
|
|
|
" %10" PRIu64 " %10" PRIu64 "\n",
|
|
|
|
vrf->name, zvrf->installs, zvrf->removals,
|
|
|
|
zvrf->neigh_updates, zvrf->lsp_installs,
|
|
|
|
zvrf->lsp_removals);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ip_forwarding,
|
|
|
|
ip_forwarding_cmd,
|
|
|
|
"ip forwarding",
|
|
|
|
IP_STR
|
|
|
|
"Turn on IP forwarding\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward();
|
|
|
|
if (ret == 0)
|
|
|
|
ret = ipforward_on();
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "Can't turn on IP forwarding\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ip_forwarding,
|
|
|
|
no_ip_forwarding_cmd,
|
|
|
|
"no ip forwarding",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
|
|
|
"Turn off IP forwarding\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward();
|
|
|
|
if (ret != 0)
|
|
|
|
ret = ipforward_off();
|
|
|
|
|
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "Can't turn off IP forwarding\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only display ip forwarding is enabled or not. */
|
|
|
|
DEFUN (show_ip_forwarding,
|
|
|
|
show_ip_forwarding_cmd,
|
|
|
|
"show ip forwarding",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"IP forwarding status\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward();
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
vty_out(vty, "IP forwarding is off\n");
|
|
|
|
else
|
|
|
|
vty_out(vty, "IP forwarding is on\n");
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only display ipv6 forwarding is enabled or not. */
|
|
|
|
DEFUN (show_ipv6_forwarding,
|
|
|
|
show_ipv6_forwarding_cmd,
|
|
|
|
"show ipv6 forwarding",
|
|
|
|
SHOW_STR
|
|
|
|
"IPv6 information\n"
|
|
|
|
"Forwarding status\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward_ipv6();
|
|
|
|
|
|
|
|
switch (ret) {
|
|
|
|
case -1:
|
|
|
|
vty_out(vty, "ipv6 forwarding is unknown\n");
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
vty_out(vty, "ipv6 forwarding is %s\n", "off");
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
vty_out(vty, "ipv6 forwarding is %s\n", "on");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty, "ipv6 forwarding is %s\n", "off");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ipv6_forwarding,
|
|
|
|
ipv6_forwarding_cmd,
|
|
|
|
"ipv6 forwarding",
|
|
|
|
IPV6_STR
|
|
|
|
"Turn on IPv6 forwarding\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward_ipv6();
|
|
|
|
if (ret == 0)
|
|
|
|
ret = ipforward_ipv6_on();
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "Can't turn on IPv6 forwarding\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ipv6_forwarding,
|
|
|
|
no_ipv6_forwarding_cmd,
|
|
|
|
"no ipv6 forwarding",
|
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Turn off IPv6 forwarding\n")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward_ipv6();
|
|
|
|
if (ret != 0)
|
|
|
|
ret = ipforward_ipv6_off();
|
|
|
|
|
|
|
|
if (ret != 0) {
|
|
|
|
vty_out(vty, "Can't turn off IPv6 forwarding\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-08-17 21:50:09 +02:00
|
|
|
/* Display dataplane info */
|
|
|
|
DEFUN (show_dataplane,
|
|
|
|
show_dataplane_cmd,
|
|
|
|
"show zebra dplane [detailed]",
|
|
|
|
SHOW_STR
|
|
|
|
ZEBRA_STR
|
|
|
|
"Zebra dataplane information\n"
|
|
|
|
"Detailed output\n")
|
|
|
|
{
|
|
|
|
int idx = 0;
|
|
|
|
bool detailed = false;
|
|
|
|
|
|
|
|
if (argv_find(argv, argc, "detailed", &idx))
|
|
|
|
detailed = true;
|
|
|
|
|
|
|
|
return dplane_show_helper(vty, detailed);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Display dataplane providers info */
|
|
|
|
DEFUN (show_dataplane_providers,
|
|
|
|
show_dataplane_providers_cmd,
|
|
|
|
"show zebra dplane providers [detailed]",
|
|
|
|
SHOW_STR
|
|
|
|
ZEBRA_STR
|
|
|
|
"Zebra dataplane information\n"
|
|
|
|
"Zebra dataplane provider information\n"
|
|
|
|
"Detailed output\n")
|
|
|
|
{
|
|
|
|
int idx = 0;
|
|
|
|
bool detailed = false;
|
|
|
|
|
|
|
|
if (argv_find(argv, argc, "detailed", &idx))
|
|
|
|
detailed = true;
|
|
|
|
|
|
|
|
return dplane_show_provs_helper(vty, detailed);
|
|
|
|
}
|
|
|
|
|
2018-09-21 20:54:02 +02:00
|
|
|
/* Configure dataplane incoming queue limit */
|
|
|
|
DEFUN (zebra_dplane_queue_limit,
|
|
|
|
zebra_dplane_queue_limit_cmd,
|
|
|
|
"zebra dplane limit (0-10000)",
|
|
|
|
ZEBRA_STR
|
|
|
|
"Zebra dataplane\n"
|
|
|
|
"Limit incoming queued updates\n"
|
|
|
|
"Number of queued updates\n")
|
|
|
|
{
|
|
|
|
uint32_t limit = 0;
|
|
|
|
|
|
|
|
limit = strtoul(argv[3]->arg, NULL, 10);
|
|
|
|
|
|
|
|
dplane_set_in_queue_limit(limit, true);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset dataplane queue limit to default value */
|
|
|
|
DEFUN (no_zebra_dplane_queue_limit,
|
|
|
|
no_zebra_dplane_queue_limit_cmd,
|
|
|
|
"no zebra dplane limit [(0-10000)]",
|
|
|
|
NO_STR
|
|
|
|
ZEBRA_STR
|
|
|
|
"Zebra dataplane\n"
|
|
|
|
"Limit incoming queued updates\n"
|
|
|
|
"Number of queued updates\n")
|
|
|
|
{
|
|
|
|
dplane_set_in_queue_limit(0, false);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2018-08-17 21:50:09 +02:00
|
|
|
|
2019-01-04 15:41:09 +01:00
|
|
|
DEFUN (zebra_show_routing_tables_summary,
|
|
|
|
zebra_show_routing_tables_summary_cmd,
|
|
|
|
"show zebra router table summary",
|
|
|
|
SHOW_STR
|
|
|
|
ZEBRA_STR
|
|
|
|
"The Zebra Router Information\n"
|
|
|
|
"Table Information about this Zebra Router\n"
|
|
|
|
"Summary Information\n")
|
|
|
|
{
|
|
|
|
zebra_router_show_table_summary(vty);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-12-07 16:47:30 +01:00
|
|
|
/* Table configuration write function. */
|
|
|
|
static int config_write_table(struct vty *vty)
|
|
|
|
{
|
2019-01-11 20:59:36 +01:00
|
|
|
if (zrouter.rtm_table_default)
|
|
|
|
vty_out(vty, "table %d\n", zrouter.rtm_table_default);
|
2017-12-07 16:47:30 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* IPForwarding configuration write function. */
|
|
|
|
static int config_write_forwarding(struct vty *vty)
|
|
|
|
{
|
|
|
|
/* FIXME: Find better place for that. */
|
|
|
|
router_id_write(vty);
|
|
|
|
|
|
|
|
if (!ipforward())
|
|
|
|
vty_out(vty, "no ip forwarding\n");
|
|
|
|
if (!ipforward_ipv6())
|
|
|
|
vty_out(vty, "no ipv6 forwarding\n");
|
|
|
|
vty_out(vty, "!\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* IP node for static routes. */
|
2017-07-17 14:03:14 +02:00
|
|
|
static struct cmd_node ip_node = {IP_NODE, "", 1};
|
|
|
|
static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};
|
2017-12-07 16:47:30 +01:00
|
|
|
/* table node for routing tables. */
|
|
|
|
static struct cmd_node table_node = {TABLE_NODE,
|
|
|
|
"", /* This node has no interface. */
|
|
|
|
1};
|
|
|
|
static struct cmd_node forwarding_node = {FORWARDING_NODE,
|
|
|
|
"", /* This node has no interface. */
|
|
|
|
1};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Route VTY. */
|
2017-07-17 14:03:14 +02:00
|
|
|
void zebra_vty_init(void)
|
|
|
|
{
|
2017-12-07 16:47:30 +01:00
|
|
|
/* Install configuration write function. */
|
|
|
|
install_node(&table_node, config_write_table);
|
|
|
|
install_node(&forwarding_node, config_write_forwarding);
|
|
|
|
|
|
|
|
install_element(VIEW_NODE, &show_ip_forwarding_cmd);
|
|
|
|
install_element(CONFIG_NODE, &ip_forwarding_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ip_forwarding_cmd);
|
|
|
|
install_element(ENABLE_NODE, &show_zebra_cmd);
|
|
|
|
|
|
|
|
#ifdef HAVE_NETLINK
|
|
|
|
install_element(VIEW_NODE, &show_table_cmd);
|
|
|
|
install_element(CONFIG_NODE, &config_table_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_config_table_cmd);
|
|
|
|
#endif /* HAVE_NETLINK */
|
|
|
|
|
|
|
|
install_element(VIEW_NODE, &show_ipv6_forwarding_cmd);
|
|
|
|
install_element(CONFIG_NODE, &ipv6_forwarding_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd);
|
|
|
|
|
|
|
|
/* Route-map */
|
|
|
|
zebra_route_map_init();
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
install_node(&ip_node, zebra_ip_config);
|
|
|
|
install_node(&protocol_node, config_write_protocol);
|
|
|
|
|
|
|
|
install_element(CONFIG_NODE, &allow_external_route_update_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_allow_external_route_update_cmd);
|
2018-05-08 13:58:32 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
|
2018-03-28 11:31:22 +02:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
|
2017-10-25 16:47:55 +02:00
|
|
|
install_element(CONFIG_NODE, &zebra_workqueue_timer_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd);
|
2017-10-25 17:13:42 +02:00
|
|
|
install_element(CONFIG_NODE, &zebra_packet_process_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_zebra_packet_process_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
install_element(VIEW_NODE, &show_vrf_cmd);
|
2017-10-08 03:49:27 +02:00
|
|
|
install_element(VIEW_NODE, &show_vrf_vni_cmd);
|
2017-09-13 20:16:12 +02:00
|
|
|
install_element(VIEW_NODE, &show_route_cmd);
|
2018-02-14 04:38:47 +01:00
|
|
|
install_element(VIEW_NODE, &show_route_table_cmd);
|
2018-03-28 11:06:39 +02:00
|
|
|
if (vrf_is_backend_netns())
|
|
|
|
install_element(VIEW_NODE, &show_route_table_vrf_cmd);
|
2017-09-13 22:40:19 +02:00
|
|
|
install_element(VIEW_NODE, &show_route_detail_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_route_summary_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_ip_nht_cmd);
|
2018-12-17 12:18:57 +01:00
|
|
|
install_element(VIEW_NODE, &show_ip_import_check_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
install_element(VIEW_NODE, &show_ip_rpf_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_rpf_addr_cmd);
|
|
|
|
|
|
|
|
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);
|
2018-10-11 19:48:23 +02:00
|
|
|
install_element(VRF_NODE, &ip_nht_default_route_cmd);
|
|
|
|
install_element(VRF_NODE, &no_ip_nht_default_route_cmd);
|
|
|
|
install_element(VRF_NODE, &ipv6_nht_default_route_cmd);
|
|
|
|
install_element(VRF_NODE, &no_ipv6_nht_default_route_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_ipv6_mroute_cmd);
|
|
|
|
|
|
|
|
/* Commands for VRF */
|
|
|
|
install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);
|
|
|
|
|
2017-11-15 10:01:00 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_global_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_evpn_vni_cmd);
|
2018-11-15 18:33:43 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_vni_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_evpn_vni_vni_cmd);
|
2017-11-15 10:01:00 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_rmac_vni_mac_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_rmac_vni_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_rmac_vni_all_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_nh_vni_ip_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_nh_vni_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
|
2018-11-22 09:18:10 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
|
2018-11-04 19:17:29 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_dad_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
|
2018-11-22 10:56:52 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
|
2018-11-04 19:17:29 +01:00
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd);
|
2018-11-04 19:55:39 +01:00
|
|
|
install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd);
|
2017-10-08 03:49:27 +02:00
|
|
|
|
2018-04-23 15:17:19 +02:00
|
|
|
install_element(VIEW_NODE, &show_pbr_ipset_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_pbr_iptable_cmd);
|
|
|
|
|
2017-11-18 09:50:46 +01:00
|
|
|
install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
|
2017-10-08 03:49:27 +02:00
|
|
|
install_element(VRF_NODE, &vrf_vni_mapping_cmd);
|
|
|
|
install_element(VRF_NODE, &no_vrf_vni_mapping_cmd);
|
2018-03-01 11:10:47 +01:00
|
|
|
|
2018-08-17 21:50:09 +02:00
|
|
|
install_element(VIEW_NODE, &show_dataplane_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_dataplane_providers_cmd);
|
2018-09-21 20:54:02 +02:00
|
|
|
install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
|
|
|
|
install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
|
2019-01-04 15:41:09 +01:00
|
|
|
|
|
|
|
install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|