13780 lines
365 KiB
C
13780 lines
365 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/* OSPF VTY interface.
|
|
* Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
|
|
* Copyright (C) 2000 Toshiaki Takada
|
|
*/
|
|
|
|
#include <zebra.h>
|
|
#include <string.h>
|
|
|
|
#include "printfrr.h"
|
|
#include "monotime.h"
|
|
#include "memory.h"
|
|
#include "frrevent.h"
|
|
#include "prefix.h"
|
|
#include "table.h"
|
|
#include "vty.h"
|
|
#include "command.h"
|
|
#include "plist.h"
|
|
#include "log.h"
|
|
#include "zclient.h"
|
|
#include <lib/json.h>
|
|
#include "defaults.h"
|
|
#include "lib/printfrr.h"
|
|
#include "keychain.h"
|
|
#include "frrdistance.h"
|
|
|
|
#include "ospfd/ospfd.h"
|
|
#include "ospfd/ospf_asbr.h"
|
|
#include "ospfd/ospf_lsa.h"
|
|
#include "ospfd/ospf_lsdb.h"
|
|
#include "ospfd/ospf_ism.h"
|
|
#include "ospfd/ospf_interface.h"
|
|
#include "ospfd/ospf_nsm.h"
|
|
#include "ospfd/ospf_neighbor.h"
|
|
#include "ospfd/ospf_flood.h"
|
|
#include "ospfd/ospf_abr.h"
|
|
#include "ospfd/ospf_spf.h"
|
|
#include "ospfd/ospf_route.h"
|
|
#include "ospfd/ospf_zebra.h"
|
|
#include "ospfd/ospf_vty.h"
|
|
#include "ospfd/ospf_dump.h"
|
|
#include "ospfd/ospf_bfd.h"
|
|
#include "ospfd/ospf_ldp_sync.h"
|
|
#include "ospfd/ospf_network.h"
|
|
#include "ospfd/ospf_memory.h"
|
|
|
|
FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
|
|
{ .val_bool = true, .match_profile = "datacenter", },
|
|
{ .val_bool = false },
|
|
);
|
|
|
|
static const char *const ospf_network_type_str[] = {
|
|
"Null", "POINTOPOINT", "BROADCAST", "NBMA", "POINTOMULTIPOINT",
|
|
"VIRTUALLINK", "LOOPBACK"};
|
|
|
|
/* Utility functions. */
|
|
int str2area_id(const char *str, struct in_addr *area_id, int *area_id_fmt)
|
|
{
|
|
char *ep;
|
|
|
|
area_id->s_addr = htonl(strtoul(str, &ep, 10));
|
|
if (*ep && !inet_aton(str, area_id))
|
|
return -1;
|
|
|
|
*area_id_fmt =
|
|
*ep ? OSPF_AREA_ID_FMT_DOTTEDQUAD : OSPF_AREA_ID_FMT_DECIMAL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void area_id2str(char *buf, int length, struct in_addr *area_id,
|
|
int area_id_fmt)
|
|
{
|
|
if (area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
|
|
inet_ntop(AF_INET, area_id, buf, length);
|
|
else
|
|
snprintf(buf, length, "%lu",
|
|
(unsigned long)ntohl(area_id->s_addr));
|
|
}
|
|
|
|
static int str2metric(const char *str, int *metric)
|
|
{
|
|
/* Sanity check. */
|
|
if (str == NULL)
|
|
return 0;
|
|
|
|
*metric = strtol(str, NULL, 10);
|
|
if (*metric < 0 || *metric > 16777214) {
|
|
/* vty_out (vty, "OSPF metric value is invalid\n"); */
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int str2metric_type(const char *str, int *metric_type)
|
|
{
|
|
/* Sanity check. */
|
|
if (str == NULL)
|
|
return 0;
|
|
|
|
if (strncmp(str, "1", 1) == 0)
|
|
*metric_type = EXTERNAL_METRIC_TYPE_1;
|
|
else if (strncmp(str, "2", 1) == 0)
|
|
*metric_type = EXTERNAL_METRIC_TYPE_2;
|
|
else
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int ospf_oi_count(struct interface *ifp)
|
|
{
|
|
struct route_node *rn;
|
|
int i = 0;
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
|
|
if (rn->info)
|
|
i++;
|
|
|
|
return i;
|
|
}
|
|
|
|
#define OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \
|
|
if (argv_find(argv, argc, "vrf", &idx_vrf)) { \
|
|
vrf_name = argv[idx_vrf + 1]->arg; \
|
|
all_vrf = strmatch(vrf_name, "all"); \
|
|
}
|
|
|
|
static int ospf_router_cmd_parse(struct vty *vty, struct cmd_token *argv[],
|
|
const int argc, unsigned short *instance,
|
|
const char **vrf_name)
|
|
{
|
|
int idx_vrf = 0, idx_inst = 0;
|
|
|
|
*instance = 0;
|
|
if (argv_find(argv, argc, "(1-65535)", &idx_inst)) {
|
|
if (ospf_instance == 0) {
|
|
vty_out(vty,
|
|
"%% OSPF is not running in instance mode\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
*instance = strtoul(argv[idx_inst]->arg, NULL, 10);
|
|
}
|
|
|
|
*vrf_name = VRF_DEFAULT_NAME;
|
|
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
|
|
if (ospf_instance != 0) {
|
|
vty_out(vty,
|
|
"%% VRF is not supported in instance mode\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
*vrf_name = argv[idx_vrf + 1]->arg;
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty,
|
|
json_object *json, uint8_t use_vrf)
|
|
{
|
|
if (use_vrf) {
|
|
if (json) {
|
|
json_object_string_add(json, "vrfName",
|
|
ospf_get_name(ospf));
|
|
json_object_int_add(json, "vrfId", ospf->vrf_id);
|
|
} else
|
|
vty_out(vty, "VRF Name: %s\n", ospf_get_name(ospf));
|
|
}
|
|
}
|
|
|
|
#include "ospfd/ospf_vty_clippy.c"
|
|
|
|
DEFUN_NOSH (router_ospf,
|
|
router_ospf_cmd,
|
|
"router ospf [{(1-65535)|vrf NAME}]",
|
|
"Enable a routing process\n"
|
|
"Start OSPF configuration\n"
|
|
"Instance ID\n"
|
|
VRF_CMD_HELP_STR)
|
|
{
|
|
unsigned short instance;
|
|
const char *vrf_name;
|
|
bool created = false;
|
|
struct ospf *ospf;
|
|
int ret;
|
|
|
|
ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name);
|
|
if (ret != CMD_SUCCESS)
|
|
return ret;
|
|
|
|
if (instance != ospf_instance) {
|
|
VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
|
|
return CMD_NOT_MY_INSTANCE;
|
|
}
|
|
|
|
ospf = ospf_get(instance, vrf_name, &created);
|
|
|
|
if (created)
|
|
if (DFLT_OSPF_LOG_ADJACENCY_CHANGES)
|
|
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
zlog_debug(
|
|
"Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
|
|
ospf->instance, ospf_get_name(ospf), ospf->vrf_id,
|
|
ospf->oi_running);
|
|
|
|
VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (no_router_ospf,
|
|
no_router_ospf_cmd,
|
|
"no router ospf [{(1-65535)|vrf NAME}]",
|
|
NO_STR
|
|
"Enable a routing process\n"
|
|
"Start OSPF configuration\n"
|
|
"Instance ID\n"
|
|
VRF_CMD_HELP_STR)
|
|
{
|
|
unsigned short instance;
|
|
const char *vrf_name;
|
|
struct ospf *ospf;
|
|
int ret;
|
|
|
|
ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name);
|
|
if (ret != CMD_SUCCESS)
|
|
return ret;
|
|
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup(instance, vrf_name);
|
|
if (ospf) {
|
|
if (ospf->gr_info.restart_support)
|
|
ospf_gr_nvm_delete(ospf);
|
|
|
|
ospf_finish(ospf);
|
|
} else
|
|
ret = CMD_WARNING_CONFIG_FAILED;
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
DEFPY (ospf_router_id,
|
|
ospf_router_id_cmd,
|
|
"ospf router-id A.B.C.D",
|
|
"OSPF specific commands\n"
|
|
"router-id for the OSPF process\n"
|
|
"OSPF router-id in IP address format\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
|
|
ospf->router_id_static = router_id;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
|
if (area->full_nbrs) {
|
|
vty_out(vty,
|
|
"For this router-id change to take effect, use \"clear ip ospf process\" command\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_router_id_update(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_router_id_old,
|
|
ospf_router_id_old_cmd,
|
|
"router-id A.B.C.D",
|
|
"router-id for the OSPF process\n"
|
|
"OSPF router-id in IP address format\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4 = 1;
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
struct in_addr router_id;
|
|
int ret;
|
|
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &router_id);
|
|
if (!ret) {
|
|
vty_out(vty, "Please specify Router ID by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ospf->router_id_static = router_id;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
|
if (area->full_nbrs) {
|
|
vty_out(vty,
|
|
"For this router-id change to take effect, use \"clear ip ospf process\" command\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_router_id_update(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (no_ospf_router_id,
|
|
no_ospf_router_id_cmd,
|
|
"no ospf router-id [A.B.C.D]",
|
|
NO_STR
|
|
"OSPF specific commands\n"
|
|
"router-id for the OSPF process\n"
|
|
"OSPF router-id in IP address format\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
|
|
if (router_id_str) {
|
|
if (!IPV4_ADDR_SAME(&ospf->router_id_static, &router_id)) {
|
|
vty_out(vty, "%% OSPF router-id doesn't match\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
}
|
|
|
|
ospf->router_id_static.s_addr = 0;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
|
if (area->full_nbrs) {
|
|
vty_out(vty,
|
|
"For this router-id change to take effect, use \"clear ip ospf process\" command\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_router_id_update(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ALIAS_HIDDEN (no_ospf_router_id,
|
|
no_router_id_cmd,
|
|
"no router-id [A.B.C.D]",
|
|
NO_STR
|
|
"router-id for the OSPF process\n"
|
|
"OSPF router-id in IP address format\n")
|
|
|
|
static void ospf_passive_interface_default_update(struct ospf *ospf,
|
|
uint8_t newval)
|
|
{
|
|
struct listnode *ln;
|
|
struct ospf_interface *oi;
|
|
|
|
ospf->passive_interface_default = newval;
|
|
|
|
/* update multicast memberships */
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, ln, oi))
|
|
ospf_if_set_multicast(oi);
|
|
}
|
|
|
|
static void ospf_passive_interface_update(struct interface *ifp,
|
|
struct ospf_if_params *params,
|
|
struct in_addr addr, uint8_t newval)
|
|
{
|
|
struct route_node *rn;
|
|
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, passive_interface)) {
|
|
if (params->passive_interface == newval)
|
|
return;
|
|
|
|
params->passive_interface = newval;
|
|
UNSET_IF_PARAM(params, passive_interface);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
} else {
|
|
params->passive_interface = newval;
|
|
SET_IF_PARAM(params, passive_interface);
|
|
}
|
|
|
|
/*
|
|
* XXX We should call ospf_if_set_multicast on exactly those
|
|
* interfaces for which the passive property changed. It is too much
|
|
* work to determine this set, so we do this for every interface.
|
|
* This is safe and reasonable because ospf_if_set_multicast uses a
|
|
* record of joined groups to avoid systems calls if the desired
|
|
* memberships match the current memership.
|
|
*/
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (oi)
|
|
ospf_if_set_multicast(oi);
|
|
}
|
|
|
|
/*
|
|
* XXX It is not clear what state transitions the interface needs to
|
|
* undergo when going from active to passive and vice versa. Fixing
|
|
* this will require precise identification of interfaces having such a
|
|
* transition.
|
|
*/
|
|
}
|
|
|
|
DEFUN (ospf_passive_interface_default,
|
|
ospf_passive_interface_default_cmd,
|
|
"passive-interface default",
|
|
"Suppress routing updates on an interface\n"
|
|
"Suppress routing updates on interfaces by default\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_passive_interface_default_update(ospf, OSPF_IF_PASSIVE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_passive_interface_addr,
|
|
ospf_passive_interface_addr_cmd,
|
|
"passive-interface IFNAME [A.B.C.D]",
|
|
"Suppress routing updates on an interface\n"
|
|
"Interface's name\n"
|
|
"IPv4 address\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4 = 2;
|
|
struct interface *ifp = NULL;
|
|
struct in_addr addr = {.s_addr = INADDR_ANY};
|
|
struct ospf_if_params *params;
|
|
int ret;
|
|
|
|
vty_out(vty,
|
|
"This command is deprecated, because it is not VRF-aware.\n");
|
|
vty_out(vty,
|
|
"Please, use \"ip ospf passive\" on an interface instead.\n");
|
|
|
|
if (ospf->vrf_id != VRF_UNKNOWN)
|
|
ifp = if_get_by_name(argv[1]->arg, ospf->vrf_id, ospf->name);
|
|
|
|
if (ifp == NULL) {
|
|
vty_out(vty, "interface %s not found.\n", (char *)argv[1]->arg);
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
} else {
|
|
params = IF_DEF_PARAMS(ifp);
|
|
}
|
|
|
|
ospf_passive_interface_update(ifp, params, addr, OSPF_IF_PASSIVE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_passive_interface_default,
|
|
no_ospf_passive_interface_default_cmd,
|
|
"no passive-interface default",
|
|
NO_STR
|
|
"Allow routing updates on an interface\n"
|
|
"Allow routing updates on interfaces by default\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_passive_interface_default_update(ospf, OSPF_IF_ACTIVE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_passive_interface,
|
|
no_ospf_passive_interface_addr_cmd,
|
|
"no passive-interface IFNAME [A.B.C.D]",
|
|
NO_STR
|
|
"Allow routing updates on an interface\n"
|
|
"Interface's name\n"
|
|
"IPv4 address\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4 = 3;
|
|
struct interface *ifp = NULL;
|
|
struct in_addr addr = {.s_addr = INADDR_ANY};
|
|
struct ospf_if_params *params;
|
|
int ret;
|
|
|
|
vty_out(vty,
|
|
"This command is deprecated, because it is not VRF-aware.\n");
|
|
vty_out(vty,
|
|
"Please, use \"no ip ospf passive\" on an interface instead.\n");
|
|
|
|
if (ospf->vrf_id != VRF_UNKNOWN)
|
|
ifp = if_get_by_name(argv[2]->arg, ospf->vrf_id, ospf->name);
|
|
|
|
if (ifp == NULL) {
|
|
vty_out(vty, "interface %s not found.\n", (char *)argv[2]->arg);
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argc == 4) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
} else {
|
|
params = IF_DEF_PARAMS(ifp);
|
|
}
|
|
|
|
ospf_passive_interface_update(ifp, params, addr, OSPF_IF_ACTIVE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_network_area,
|
|
ospf_network_area_cmd,
|
|
"network A.B.C.D/M area <A.B.C.D|(0-4294967295)>",
|
|
"Enable routing on an IP network\n"
|
|
"OSPF network prefix\n"
|
|
"Set the OSPF area ID\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_prefixlen = 1;
|
|
int idx_ipv4_number = 3;
|
|
struct prefix_ipv4 p;
|
|
struct in_addr area_id;
|
|
int ret, format;
|
|
uint32_t count;
|
|
|
|
if (ospf->instance) {
|
|
vty_out(vty,
|
|
"The network command is not supported in multi-instance ospf\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
count = ospf_count_area_params(ospf);
|
|
if (count > 0) {
|
|
vty_out(vty,
|
|
"Please remove all ip ospf area x.x.x.x commands first.\n");
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
zlog_debug(
|
|
"%s ospf vrf %s num of %u ip ospf area x config",
|
|
__func__, ospf_get_name(ospf), count);
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* Get network prefix and Area ID. */
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
ret = ospf_network_set(ospf, &p, area_id, format);
|
|
if (ret == 0) {
|
|
vty_out(vty, "There is already same network statement.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_network_area,
|
|
no_ospf_network_area_cmd,
|
|
"no network A.B.C.D/M area <A.B.C.D|(0-4294967295)>",
|
|
NO_STR
|
|
"Enable routing on an IP network\n"
|
|
"OSPF network prefix\n"
|
|
"Set the OSPF area ID\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_prefixlen = 2;
|
|
int idx_ipv4_number = 4;
|
|
struct prefix_ipv4 p;
|
|
struct in_addr area_id;
|
|
int ret, format;
|
|
|
|
if (ospf->instance) {
|
|
vty_out(vty,
|
|
"The network command is not supported in multi-instance ospf\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* Get network prefix and Area ID. */
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
ret = ospf_network_unset(ospf, &p, area_id);
|
|
if (ret == 0) {
|
|
vty_out(vty,
|
|
"Can't find specified network area configuration.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_range,
|
|
ospf_area_range_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> range A.B.C.D/M [advertise [cost (0-16777215)]]",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Summarize routes matching address/mask (border routers only)\n"
|
|
"Area range prefix\n"
|
|
"Advertise this range (default)\n"
|
|
"User specified metric for this range\n"
|
|
"Advertised metric for this range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
int idx_ipv4_number = 1;
|
|
int idx_ipv4_prefixlen = 3;
|
|
int idx_cost = 6;
|
|
struct prefix_ipv4 p;
|
|
struct in_addr area_id;
|
|
int format;
|
|
uint32_t cost;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
ospf_area_range_set(ospf, area, area->ranges, &p,
|
|
OSPF_AREA_RANGE_ADVERTISE, false);
|
|
if (argc > 5) {
|
|
cost = strtoul(argv[idx_cost]->arg, NULL, 10);
|
|
ospf_area_range_cost_set(ospf, area, area->ranges, &p, cost);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_range_cost,
|
|
ospf_area_range_cost_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> range A.B.C.D/M {cost (0-16777215)|substitute A.B.C.D/M}",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Summarize routes matching address/mask (border routers only)\n"
|
|
"Area range prefix\n"
|
|
"User specified metric for this range\n"
|
|
"Advertised metric for this range\n"
|
|
"Announce area range as another prefix\n"
|
|
"Network prefix to be announced instead of range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
int idx_ipv4_number = 1;
|
|
int idx_ipv4_prefixlen = 3;
|
|
int idx = 4;
|
|
struct prefix_ipv4 p, s;
|
|
struct in_addr area_id;
|
|
int format;
|
|
uint32_t cost;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
ospf_area_range_set(ospf, area, area->ranges, &p,
|
|
OSPF_AREA_RANGE_ADVERTISE, false);
|
|
if (argv_find(argv, argc, "cost", &idx)) {
|
|
cost = strtoul(argv[idx + 1]->arg, NULL, 10);
|
|
ospf_area_range_cost_set(ospf, area, area->ranges, &p, cost);
|
|
}
|
|
|
|
idx = 4;
|
|
if (argv_find(argv, argc, "substitute", &idx)) {
|
|
str2prefix_ipv4(argv[idx + 1]->arg, &s);
|
|
ospf_area_range_substitute_set(ospf, area, &p, &s);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_range_not_advertise,
|
|
ospf_area_range_not_advertise_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> range A.B.C.D/M not-advertise",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Summarize routes matching address/mask (border routers only)\n"
|
|
"Area range prefix\n"
|
|
"DoNotAdvertise this range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
int idx_ipv4_number = 1;
|
|
int idx_ipv4_prefixlen = 3;
|
|
struct prefix_ipv4 p;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
ospf_area_range_set(ospf, area, area->ranges, &p, 0, false);
|
|
ospf_area_range_substitute_unset(ospf, area, &p);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_range,
|
|
no_ospf_area_range_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> range A.B.C.D/M [<cost (0-16777215)|advertise [cost (0-16777215)]|not-advertise>]",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Summarize routes matching address/mask (border routers only)\n"
|
|
"Area range prefix\n"
|
|
"User specified metric for this range\n"
|
|
"Advertised metric for this range\n"
|
|
"Advertise this range (default)\n"
|
|
"User specified metric for this range\n"
|
|
"Advertised metric for this range\n"
|
|
"DoNotAdvertise this range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
int idx_ipv4_number = 2;
|
|
int idx_ipv4_prefixlen = 4;
|
|
struct prefix_ipv4 p;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
ospf_area_range_unset(ospf, area, area->ranges, &p);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_range_substitute,
|
|
no_ospf_area_range_substitute_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> range A.B.C.D/M substitute A.B.C.D/M",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Summarize routes matching address/mask (border routers only)\n"
|
|
"Area range prefix\n"
|
|
"Announce area range as another prefix\n"
|
|
"Network prefix to be announced instead of range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
int idx_ipv4_number = 2;
|
|
int idx_ipv4_prefixlen = 4;
|
|
int idx_ipv4_prefixlen_2 = 6;
|
|
struct prefix_ipv4 p, s;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p);
|
|
str2prefix_ipv4(argv[idx_ipv4_prefixlen_2]->arg, &s);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
ospf_area_range_substitute_unset(ospf, area, &p);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
/* Command Handler Logic in VLink stuff is delicate!!
|
|
|
|
ALTER AT YOUR OWN RISK!!!!
|
|
|
|
Various dummy values are used to represent 'NoChange' state for
|
|
VLink configuration NOT being changed by a VLink command, and
|
|
special syntax is used within the command strings so that the
|
|
typed in command verbs can be seen in the configuration command
|
|
bacckend handler. This is to drastically reduce the verbeage
|
|
required to coe up with a reasonably compatible Cisco VLink command
|
|
|
|
- Matthew Grant <grantma@anathoth.gen.nz>
|
|
Wed, 21 Feb 2001 15:13:52 +1300
|
|
*/
|
|
|
|
/* Configuration data for virtual links
|
|
*/
|
|
struct ospf_vl_config_data {
|
|
struct vty *vty; /* vty stuff */
|
|
struct in_addr area_id; /* area ID from command line */
|
|
int area_id_fmt; /* command line area ID format */
|
|
struct in_addr vl_peer; /* command line vl_peer */
|
|
int auth_type; /* Authehntication type, if given */
|
|
char *auth_key; /* simple password if present */
|
|
int crypto_key_id; /* Cryptographic key ID */
|
|
char *md5_key; /* MD5 authentication key */
|
|
char *keychain; /* Cryptographic keychain */
|
|
int del_keychain;
|
|
int hello_interval; /* Obvious what these are... */
|
|
int retransmit_interval;
|
|
int retransmit_window;
|
|
int transmit_delay;
|
|
int dead_interval;
|
|
};
|
|
|
|
static void ospf_vl_config_data_init(struct ospf_vl_config_data *vl_config,
|
|
struct vty *vty)
|
|
{
|
|
memset(vl_config, 0, sizeof(struct ospf_vl_config_data));
|
|
vl_config->auth_type = OSPF_AUTH_CMD_NOTSEEN;
|
|
vl_config->vty = vty;
|
|
}
|
|
|
|
static struct ospf_vl_data *
|
|
ospf_find_vl_data(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
|
|
{
|
|
struct ospf_area *area;
|
|
struct ospf_vl_data *vl_data;
|
|
struct vty *vty;
|
|
struct in_addr area_id;
|
|
|
|
vty = vl_config->vty;
|
|
area_id = vl_config->area_id;
|
|
|
|
if (area_id.s_addr == OSPF_AREA_BACKBONE) {
|
|
vty_out(vty,
|
|
"Configuring VLs over the backbone is not allowed\n");
|
|
return NULL;
|
|
}
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, vl_config->area_id_fmt);
|
|
|
|
if (area->external_routing != OSPF_AREA_DEFAULT) {
|
|
if (vl_config->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
|
|
vty_out(vty, "Area %pI4 is %s\n", &area_id,
|
|
area->external_routing == OSPF_AREA_NSSA
|
|
? "nssa"
|
|
: "stub");
|
|
else
|
|
vty_out(vty, "Area %ld is %s\n",
|
|
(unsigned long)ntohl(area_id.s_addr),
|
|
area->external_routing == OSPF_AREA_NSSA
|
|
? "nssa"
|
|
: "stub");
|
|
return NULL;
|
|
}
|
|
|
|
if ((vl_data = ospf_vl_lookup(ospf, area, vl_config->vl_peer))
|
|
== NULL) {
|
|
vl_data = ospf_vl_data_new(area, vl_config->vl_peer);
|
|
if (vl_data->vl_oi == NULL) {
|
|
vl_data->vl_oi = ospf_vl_new(ospf, vl_data);
|
|
ospf_vl_add(ospf, vl_data);
|
|
ospf_spf_calculate_schedule(ospf,
|
|
SPF_FLAG_CONFIG_CHANGE);
|
|
}
|
|
}
|
|
return vl_data;
|
|
}
|
|
|
|
|
|
static int ospf_vl_set_security(struct ospf_vl_data *vl_data,
|
|
struct ospf_vl_config_data *vl_config)
|
|
{
|
|
struct crypt_key *ck;
|
|
struct vty *vty;
|
|
struct interface *ifp = vl_data->vl_oi->ifp;
|
|
|
|
vty = vl_config->vty;
|
|
|
|
if (vl_config->auth_type != OSPF_AUTH_CMD_NOTSEEN) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type);
|
|
IF_DEF_PARAMS(ifp)->auth_type = vl_config->auth_type;
|
|
}
|
|
|
|
if (vl_config->auth_key) {
|
|
memset(IF_DEF_PARAMS(ifp)->auth_simple, 0,
|
|
OSPF_AUTH_SIMPLE_SIZE + 1);
|
|
strlcpy((char *)IF_DEF_PARAMS(ifp)->auth_simple,
|
|
vl_config->auth_key,
|
|
sizeof(IF_DEF_PARAMS(ifp)->auth_simple));
|
|
} else if (vl_config->keychain) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), keychain_name);
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, IF_DEF_PARAMS(ifp)->keychain_name);
|
|
IF_DEF_PARAMS(ifp)->keychain_name = XSTRDUP(MTYPE_OSPF_IF_PARAMS, vl_config->keychain);
|
|
} else if (vl_config->md5_key) {
|
|
if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt,
|
|
vl_config->crypto_key_id)
|
|
!= NULL) {
|
|
vty_out(vty, "OSPF: Key %d already exists\n",
|
|
vl_config->crypto_key_id);
|
|
return CMD_WARNING;
|
|
}
|
|
ck = ospf_crypt_key_new();
|
|
ck->key_id = vl_config->crypto_key_id;
|
|
memset(ck->auth_key, 0, OSPF_AUTH_MD5_SIZE + 1);
|
|
strlcpy((char *)ck->auth_key, vl_config->md5_key,
|
|
sizeof(ck->auth_key));
|
|
|
|
ospf_crypt_key_add(IF_DEF_PARAMS(ifp)->auth_crypt, ck);
|
|
} else if (vl_config->crypto_key_id != 0) {
|
|
/* Delete a key */
|
|
|
|
if (ospf_crypt_key_lookup(IF_DEF_PARAMS(ifp)->auth_crypt,
|
|
vl_config->crypto_key_id)
|
|
== NULL) {
|
|
vty_out(vty, "OSPF: Key %d does not exist\n",
|
|
vl_config->crypto_key_id);
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ospf_crypt_key_delete(IF_DEF_PARAMS(ifp)->auth_crypt,
|
|
vl_config->crypto_key_id);
|
|
} else if (vl_config->del_keychain) {
|
|
UNSET_IF_PARAM(IF_DEF_PARAMS(ifp), keychain_name);
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, IF_DEF_PARAMS(ifp)->keychain_name);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static int ospf_vl_set_timers(struct ospf_vl_data *vl_data,
|
|
struct ospf_vl_config_data *vl_config)
|
|
{
|
|
struct interface *ifp = vl_data->vl_oi->ifp;
|
|
/* Virtual Link data initialised to defaults, so only set
|
|
if a value given */
|
|
if (vl_config->hello_interval) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello);
|
|
IF_DEF_PARAMS(ifp)->v_hello = vl_config->hello_interval;
|
|
}
|
|
|
|
if (vl_config->dead_interval) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait);
|
|
IF_DEF_PARAMS(ifp)->v_wait = vl_config->dead_interval;
|
|
}
|
|
|
|
if (vl_config->retransmit_interval) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_interval);
|
|
IF_DEF_PARAMS(ifp)->retransmit_interval =
|
|
vl_config->retransmit_interval;
|
|
}
|
|
|
|
if (vl_config->retransmit_window) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_window);
|
|
IF_DEF_PARAMS(ifp)->retransmit_window =
|
|
vl_config->retransmit_window;
|
|
}
|
|
|
|
if (vl_config->transmit_delay) {
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay);
|
|
IF_DEF_PARAMS(ifp)->transmit_delay = vl_config->transmit_delay;
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
/* The business end of all of the above */
|
|
static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
|
|
{
|
|
struct ospf_vl_data *vl_data;
|
|
int ret;
|
|
|
|
vl_data = ospf_find_vl_data(ospf, vl_config);
|
|
if (!vl_data)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
/* Process this one first as it can have a fatal result, which can
|
|
only logically occur if the virtual link exists already
|
|
Thus a command error does not result in a change to the
|
|
running configuration such as unexpectedly altered timer
|
|
values etc.*/
|
|
ret = ospf_vl_set_security(vl_data, vl_config);
|
|
if (ret != CMD_SUCCESS)
|
|
return ret;
|
|
|
|
/* Set any time based parameters, these area already range checked */
|
|
|
|
ret = ospf_vl_set_timers(vl_data, vl_config);
|
|
if (ret != CMD_SUCCESS)
|
|
return ret;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* This stuff exists to make specifying all the alias commands A LOT simpler
|
|
*/
|
|
#define VLINK_HELPSTR_IPADDR \
|
|
"OSPF area parameters\n" \
|
|
"OSPF area ID in IP address format\n" \
|
|
"OSPF area ID as a decimal value\n" \
|
|
"Configure a virtual link\n" \
|
|
"Router ID of the remote ABR\n"
|
|
|
|
#define VLINK_HELPSTR_AUTHTYPE_SIMPLE \
|
|
"Enable authentication on this virtual link\n" \
|
|
"dummy string \n"
|
|
|
|
#define VLINK_HELPSTR_AUTHTYPE_ALL \
|
|
VLINK_HELPSTR_AUTHTYPE_SIMPLE \
|
|
"Use null authentication\n" \
|
|
"Use message-digest authentication\n"
|
|
|
|
#define VLINK_HELPSTR_TIME_PARAM \
|
|
"Time between HELLO packets\n" \
|
|
"Seconds\n" \
|
|
"Time between retransmitting lost link state advertisements\n" \
|
|
"Seconds\n" \
|
|
"Window for LSA retransmit - Retransmit LSAs expiring in this window\n" \
|
|
"Milliseconds\n" \
|
|
"Link state transmit delay\n" \
|
|
"Seconds\n" \
|
|
"Interval time after which a neighbor is declared down\n" \
|
|
"Seconds\n"
|
|
|
|
#define VLINK_HELPSTR_AUTH_SIMPLE \
|
|
"Authentication password (key)\n" \
|
|
"The OSPF password (key)\n"
|
|
|
|
#define VLINK_HELPSTR_AUTH_MD5 \
|
|
"Message digest authentication password (key)\n" \
|
|
"Key ID\n" \
|
|
"Use MD5 algorithm\n" \
|
|
"The OSPF password (key)\n"
|
|
|
|
DEFUN (ospf_area_vlink,
|
|
ospf_area_vlink_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<key-chain KEYCHAIN_NAME|message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
|
|
VLINK_HELPSTR_IPADDR
|
|
"Enable authentication on this virtual link\n"
|
|
"Use a key-chain for cryptographic authentication keys\n"
|
|
"Key-chain name\n"
|
|
"Use message-digest authentication\n"
|
|
"Use null authentication\n"
|
|
VLINK_HELPSTR_AUTH_MD5
|
|
VLINK_HELPSTR_AUTH_SIMPLE)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
int idx_ipv4 = 3;
|
|
struct ospf_vl_config_data vl_config;
|
|
char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1];
|
|
char md5_key[OSPF_AUTH_MD5_SIZE + 1];
|
|
int ret;
|
|
int idx = 0;
|
|
|
|
ospf_vl_config_data_init(&vl_config, vty);
|
|
|
|
/* Read off first 2 parameters and check them */
|
|
ret = str2area_id(argv[idx_ipv4_number]->arg, &vl_config.area_id,
|
|
&vl_config.area_id_fmt);
|
|
if (ret < 0) {
|
|
vty_out(vty, "OSPF area ID is invalid\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &vl_config.vl_peer);
|
|
if (!ret) {
|
|
vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argc <= 4) {
|
|
/* Thats all folks! - BUGS B. strikes again!!!*/
|
|
|
|
return ospf_vl_set(ospf, &vl_config);
|
|
}
|
|
|
|
if (argv_find(argv, argc, "authentication", &idx)) {
|
|
/* authentication - this option can only occur
|
|
at start of command line */
|
|
vl_config.auth_type = OSPF_AUTH_SIMPLE;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "key-chain", &idx)) {
|
|
vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
|
|
vl_config.keychain = argv[idx+1]->arg;
|
|
} else if (argv_find(argv, argc, "message-digest", &idx)) {
|
|
/* authentication message-digest */
|
|
vl_config.auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
|
|
} else if (argv_find(argv, argc, "null", &idx)) {
|
|
/* "authentication null" */
|
|
vl_config.auth_type = OSPF_AUTH_NULL;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "message-digest-key", &idx)) {
|
|
vl_config.md5_key = NULL;
|
|
vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
|
|
if (vl_config.crypto_key_id < 0)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
strlcpy(md5_key, argv[idx + 3]->arg, sizeof(md5_key));
|
|
vl_config.md5_key = md5_key;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "authentication-key", &idx)) {
|
|
strlcpy(auth_key, argv[idx + 1]->arg, sizeof(auth_key));
|
|
vl_config.auth_key = auth_key;
|
|
}
|
|
|
|
/* Action configuration */
|
|
|
|
return ospf_vl_set(ospf, &vl_config);
|
|
}
|
|
|
|
DEFUN (no_ospf_area_vlink,
|
|
no_ospf_area_vlink_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D [authentication [<key-chain KEYCHAIN_NAME|message-digest|null>]] [<message-digest-key (1-255) md5 KEY|authentication-key AUTH_KEY>]",
|
|
NO_STR
|
|
VLINK_HELPSTR_IPADDR
|
|
"Enable authentication on this virtual link\n"
|
|
"Use a key-chain for cryptographic authentication keys\n"
|
|
"Key-chain name\n"
|
|
"Use message-digest authentication\n"
|
|
"Use null authentication\n"
|
|
VLINK_HELPSTR_AUTH_MD5
|
|
VLINK_HELPSTR_AUTH_SIMPLE)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
int idx_ipv4 = 4;
|
|
struct ospf_area *area;
|
|
struct ospf_vl_config_data vl_config;
|
|
struct ospf_vl_data *vl_data = NULL;
|
|
char auth_key[OSPF_AUTH_SIMPLE_SIZE + 1];
|
|
int idx = 0;
|
|
int ret, format;
|
|
|
|
ospf_vl_config_data_init(&vl_config, vty);
|
|
|
|
ret = str2area_id(argv[idx_ipv4_number]->arg, &vl_config.area_id,
|
|
&format);
|
|
if (ret < 0) {
|
|
vty_out(vty, "OSPF area ID is invalid\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
area = ospf_area_lookup_by_area_id(ospf, vl_config.area_id);
|
|
if (!area) {
|
|
vty_out(vty, "Area does not exist\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &vl_config.vl_peer);
|
|
if (!ret) {
|
|
vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
vl_data = ospf_vl_lookup(ospf, area, vl_config.vl_peer);
|
|
if (!vl_data) {
|
|
vty_out(vty, "Virtual link does not exist\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argc <= 5) {
|
|
/* Basic VLink no command */
|
|
/* Thats all folks! - BUGS B. strikes again!!!*/
|
|
ospf_vl_delete(ospf, vl_data);
|
|
ospf_area_check_free(ospf, vl_config.area_id);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* If we are down here, we are reseting parameters */
|
|
/* Deal with other parameters */
|
|
|
|
if (argv_find(argv, argc, "authentication", &idx)) {
|
|
/* authentication - this option can only occur
|
|
at start of command line */
|
|
vl_config.auth_type = OSPF_AUTH_NOTSET;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "key-chain", &idx)) {
|
|
vl_config.del_keychain = 1;
|
|
vl_config.keychain = NULL;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "message-digest-key", &idx)) {
|
|
vl_config.md5_key = NULL;
|
|
vl_config.crypto_key_id = strtol(argv[idx + 1]->arg, NULL, 10);
|
|
if (vl_config.crypto_key_id < 0)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "authentication-key", &idx)) {
|
|
/* Reset authentication-key to 0 */
|
|
memset(auth_key, 0, OSPF_AUTH_SIMPLE_SIZE + 1);
|
|
vl_config.auth_key = auth_key;
|
|
}
|
|
|
|
/* Action configuration */
|
|
|
|
return ospf_vl_set(ospf, &vl_config);
|
|
}
|
|
|
|
DEFUN (ospf_area_vlink_intervals,
|
|
ospf_area_vlink_intervals_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|retransmit-window (20-10000)|transmit-delay (1-65535)|dead-interval (1-65535)}",
|
|
VLINK_HELPSTR_IPADDR
|
|
VLINK_HELPSTR_TIME_PARAM)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_vl_config_data vl_config;
|
|
int ret = 0;
|
|
|
|
ospf_vl_config_data_init(&vl_config, vty);
|
|
|
|
char *area_id = argv[1]->arg;
|
|
char *router_id = argv[3]->arg;
|
|
|
|
ret = str2area_id(area_id, &vl_config.area_id, &vl_config.area_id_fmt);
|
|
if (ret < 0) {
|
|
vty_out(vty, "OSPF area ID is invalid\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ret = inet_aton(router_id, &vl_config.vl_peer);
|
|
if (!ret) {
|
|
vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
for (int idx = 4; idx < argc; idx++) {
|
|
if (strmatch(argv[idx]->text, "hello-interval"))
|
|
vl_config.hello_interval =
|
|
strtol(argv[++idx]->arg, NULL, 10);
|
|
else if (strmatch(argv[idx]->text, "retransmit-interval"))
|
|
vl_config.retransmit_interval =
|
|
strtol(argv[++idx]->arg, NULL, 10);
|
|
else if (strmatch(argv[idx]->text, "retransmit-window"))
|
|
vl_config.retransmit_window = strtol(argv[++idx]->arg,
|
|
NULL, 10);
|
|
else if (strmatch(argv[idx]->text, "transmit-delay"))
|
|
vl_config.transmit_delay =
|
|
strtol(argv[++idx]->arg, NULL, 10);
|
|
else if (strmatch(argv[idx]->text, "dead-interval"))
|
|
vl_config.dead_interval =
|
|
strtol(argv[++idx]->arg, NULL, 10);
|
|
}
|
|
|
|
/* Action configuration */
|
|
return ospf_vl_set(ospf, &vl_config);
|
|
}
|
|
|
|
DEFUN (no_ospf_area_vlink_intervals,
|
|
no_ospf_area_vlink_intervals_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|retransmit-window (20-1000)|transmit-delay (1-65535)|dead-interval (1-65535)}",
|
|
NO_STR
|
|
VLINK_HELPSTR_IPADDR
|
|
VLINK_HELPSTR_TIME_PARAM)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_vl_config_data vl_config;
|
|
int ret = 0;
|
|
|
|
ospf_vl_config_data_init(&vl_config, vty);
|
|
|
|
char *area_id = argv[2]->arg;
|
|
char *router_id = argv[4]->arg;
|
|
|
|
ret = str2area_id(area_id, &vl_config.area_id, &vl_config.area_id_fmt);
|
|
if (ret < 0) {
|
|
vty_out(vty, "OSPF area ID is invalid\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ret = inet_aton(router_id, &vl_config.vl_peer);
|
|
if (!ret) {
|
|
vty_out(vty, "Please specify valid Router ID as a.b.c.d\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
for (int idx = 5; idx < argc; idx++) {
|
|
if (strmatch(argv[idx]->text, "hello-interval"))
|
|
vl_config.hello_interval = OSPF_HELLO_INTERVAL_DEFAULT;
|
|
else if (strmatch(argv[idx]->text, "retransmit-interval"))
|
|
vl_config.retransmit_interval =
|
|
OSPF_RETRANSMIT_INTERVAL_DEFAULT;
|
|
else if (strmatch(argv[idx]->text, "retransmit-window"))
|
|
vl_config.retransmit_window =
|
|
OSPF_RETRANSMIT_WINDOW_DEFAULT;
|
|
else if (strmatch(argv[idx]->text, "transmit-delay"))
|
|
vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
|
|
else if (strmatch(argv[idx]->text, "dead-interval"))
|
|
vl_config.dead_interval =
|
|
OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
|
|
}
|
|
|
|
/* Action configuration */
|
|
return ospf_vl_set(ospf, &vl_config);
|
|
}
|
|
|
|
DEFUN (ospf_area_shortcut,
|
|
ospf_area_shortcut_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> shortcut <default|enable|disable>",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure the area's shortcutting mode\n"
|
|
"Set default shortcutting behavior\n"
|
|
"Enable shortcutting through the area\n"
|
|
"Disable shortcutting through the area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
int idx_enable_disable = 3;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int mode;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("shortcut", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
if (strncmp(argv[idx_enable_disable]->arg, "de", 2) == 0)
|
|
mode = OSPF_SHORTCUT_DEFAULT;
|
|
else if (strncmp(argv[idx_enable_disable]->arg, "di", 2) == 0)
|
|
mode = OSPF_SHORTCUT_DISABLE;
|
|
else if (strncmp(argv[idx_enable_disable]->arg, "e", 1) == 0)
|
|
mode = OSPF_SHORTCUT_ENABLE;
|
|
else
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
ospf_area_shortcut_set(ospf, area, mode);
|
|
|
|
if (ospf->abr_type != OSPF_ABR_SHORTCUT)
|
|
vty_out(vty,
|
|
"Shortcut area setting will take effect only when the router is configured as Shortcut ABR\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_shortcut,
|
|
no_ospf_area_shortcut_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> shortcut <enable|disable>",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Deconfigure the area's shortcutting mode\n"
|
|
"Deconfigure enabled shortcutting through the area\n"
|
|
"Deconfigure disabled shortcutting through the area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("shortcut", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (!area)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf_area_shortcut_unset(ospf, area);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_area_stub,
|
|
ospf_area_stub_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> stub",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as stub\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
struct in_addr area_id;
|
|
int ret, format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
|
|
ret = ospf_area_stub_set(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
|
|
format);
|
|
if (ret == 0) {
|
|
vty_out(vty,
|
|
"First deconfigure all virtual link through this area\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* Flush the external LSAs from the specified area */
|
|
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
|
|
ospf_area_no_summary_unset(ospf, area_id);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_stub_no_summary,
|
|
ospf_area_stub_no_summary_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> stub no-summary",
|
|
"OSPF stub parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as stub\n"
|
|
"Do not inject inter-area routes into stub\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
struct in_addr area_id;
|
|
int ret, format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
|
|
ret = ospf_area_stub_set(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
|
|
format);
|
|
if (ret == 0) {
|
|
vty_out(vty,
|
|
"%% Area cannot be stub as it contains a virtual link\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ospf_area_no_summary_set(ospf, area_id);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_stub,
|
|
no_ospf_area_stub_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> stub",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as stub\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
|
|
ospf_area_stub_unset(ospf, area_id);
|
|
ospf_area_no_summary_unset(ospf, area_id);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_stub_no_summary,
|
|
no_ospf_area_stub_no_summary_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> stub no-summary",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as stub\n"
|
|
"Do not inject inter-area routes into area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("stub", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
ospf_area_no_summary_unset(ospf, area_id);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (ospf_area_nssa,
|
|
ospf_area_nssa_cmd,
|
|
"area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
|
[{\
|
|
<translate-candidate|translate-never|translate-always>$translator_role\
|
|
|default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
|
|
|no-summary$no_summary\
|
|
|suppress-fa$suppress_fa\
|
|
}]",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as nssa\n"
|
|
"Configure NSSA-ABR for translate election (default)\n"
|
|
"Configure NSSA-ABR to never translate\n"
|
|
"Configure NSSA-ABR to always translate\n"
|
|
"Originate Type 7 default into NSSA area\n"
|
|
"OSPF default metric\n"
|
|
"OSPF metric\n"
|
|
"OSPF metric type for default routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Do not inject inter-area routes into nssa\n"
|
|
"Suppress forwarding address\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct in_addr area_id;
|
|
int ret, format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, area_str);
|
|
|
|
ret = ospf_area_nssa_set(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
|
|
format);
|
|
if (ret == 0) {
|
|
vty_out(vty,
|
|
"%% Area cannot be nssa as it contains a virtual link\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (translator_role) {
|
|
if (strncmp(translator_role, "translate-c", 11) == 0)
|
|
ospf_area_nssa_translator_role_set(
|
|
ospf, area_id, OSPF_NSSA_ROLE_CANDIDATE);
|
|
else if (strncmp(translator_role, "translate-n", 11) == 0)
|
|
ospf_area_nssa_translator_role_set(
|
|
ospf, area_id, OSPF_NSSA_ROLE_NEVER);
|
|
else if (strncmp(translator_role, "translate-a", 11) == 0)
|
|
ospf_area_nssa_translator_role_set(
|
|
ospf, area_id, OSPF_NSSA_ROLE_ALWAYS);
|
|
} else {
|
|
ospf_area_nssa_translator_role_set(ospf, area_id,
|
|
OSPF_NSSA_ROLE_CANDIDATE);
|
|
}
|
|
|
|
if (dflt_originate) {
|
|
int metric_type = DEFAULT_METRIC_TYPE;
|
|
|
|
if (mval_str == NULL)
|
|
mval = -1;
|
|
if (mtype_str)
|
|
(void)str2metric_type(mtype_str, &metric_type);
|
|
ospf_area_nssa_default_originate_set(ospf, area_id, mval,
|
|
metric_type);
|
|
} else
|
|
ospf_area_nssa_default_originate_unset(ospf, area_id);
|
|
|
|
if (no_summary)
|
|
ospf_area_nssa_no_summary_set(ospf, area_id);
|
|
else
|
|
ospf_area_no_summary_unset(ospf, area_id);
|
|
|
|
if (suppress_fa)
|
|
ospf_area_nssa_suppress_fa_set(ospf, area_id);
|
|
else
|
|
ospf_area_nssa_suppress_fa_unset(ospf, area_id);
|
|
|
|
/* Flush the external LSA for the specified area */
|
|
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
|
|
ospf_schedule_abr_task(ospf);
|
|
ospf_schedule_asbr_redist_update(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (no_ospf_area_nssa,
|
|
no_ospf_area_nssa_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
|
[{\
|
|
<translate-candidate|translate-never|translate-always>\
|
|
|default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
|
|
|no-summary\
|
|
|suppress-fa\
|
|
}]",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as nssa\n"
|
|
"Configure NSSA-ABR for translate election (default)\n"
|
|
"Configure NSSA-ABR to never translate\n"
|
|
"Configure NSSA-ABR to always translate\n"
|
|
"Originate Type 7 default into NSSA area\n"
|
|
"OSPF default metric\n"
|
|
"OSPF metric\n"
|
|
"OSPF metric type for default routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Do not inject inter-area routes into nssa\n"
|
|
"Suppress forwarding address\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format, area_str);
|
|
|
|
/* Flush the NSSA LSA for the specified area */
|
|
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA);
|
|
ospf_area_no_summary_unset(ospf, area_id);
|
|
ospf_area_nssa_default_originate_unset(ospf, area_id);
|
|
ospf_area_nssa_suppress_fa_unset(ospf, area_id);
|
|
ospf_area_nssa_unset(ospf, area_id);
|
|
|
|
ospf_schedule_abr_task(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (ospf_area_nssa_range,
|
|
ospf_area_nssa_range_cmd,
|
|
"area <A.B.C.D|(0-4294967295)>$area_str nssa range A.B.C.D/M$prefix [<not-advertise$not_adv|cost (0-16777215)$cost>]",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as nssa\n"
|
|
"Configured address range\n"
|
|
"Specify IPv4 prefix\n"
|
|
"Do not advertise\n"
|
|
"User specified metric for this range\n"
|
|
"Advertised metric for this range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
int advertise = 0;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, area_str);
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
if (area->external_routing != OSPF_AREA_NSSA) {
|
|
vty_out(vty, "%% First configure %s as an NSSA area\n",
|
|
area_str);
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
if (!not_adv)
|
|
advertise = OSPF_AREA_RANGE_ADVERTISE;
|
|
|
|
ospf_area_range_set(ospf, area, area->nssa_ranges,
|
|
(struct prefix_ipv4 *)prefix, advertise, true);
|
|
if (cost_str)
|
|
ospf_area_range_cost_set(ospf, area, area->nssa_ranges,
|
|
(struct prefix_ipv4 *)prefix, cost);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (no_ospf_area_nssa_range,
|
|
no_ospf_area_nssa_range_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)>$area_str nssa range A.B.C.D/M$prefix [<not-advertise|cost (0-16777215)>]",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Configure OSPF area as nssa\n"
|
|
"Configured address range\n"
|
|
"Specify IPv4 prefix\n"
|
|
"Do not advertise\n"
|
|
"User specified metric for this range\n"
|
|
"Advertised metric for this range\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, area_str);
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
if (area->external_routing != OSPF_AREA_NSSA) {
|
|
vty_out(vty, "%% First configure %s as an NSSA area\n",
|
|
area_str);
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
ospf_area_range_unset(ospf, area, area->nssa_ranges,
|
|
(struct prefix_ipv4 *)prefix);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_default_cost,
|
|
ospf_area_default_cost_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> default-cost (0-16777215)",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Set the summary-default cost of a NSSA or stub area\n"
|
|
"Stub's advertised default summary cost\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
int idx_number = 3;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
uint32_t cost;
|
|
int format;
|
|
struct prefix_ipv4 p;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("default-cost", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
cost = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
|
|
if (area->external_routing == OSPF_AREA_DEFAULT) {
|
|
vty_out(vty, "The area is neither stub, nor NSSA\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
area->default_cost = cost;
|
|
|
|
p.family = AF_INET;
|
|
p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
|
|
p.prefixlen = 0;
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
zlog_debug(
|
|
"ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4",
|
|
&area->area_id);
|
|
ospf_abr_announce_network_to_area(&p, area->default_cost, area);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_default_cost,
|
|
no_ospf_area_default_cost_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> default-cost (0-16777215)",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Set the summary-default cost of a NSSA or stub area\n"
|
|
"Stub's advertised default summary cost\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
struct prefix_ipv4 p;
|
|
|
|
VTY_GET_OSPF_AREA_ID_NO_BB("default-cost", area_id, format,
|
|
argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (area == NULL)
|
|
return CMD_SUCCESS;
|
|
|
|
if (area->external_routing == OSPF_AREA_DEFAULT) {
|
|
vty_out(vty, "The area is neither stub, nor NSSA\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
area->default_cost = 1;
|
|
|
|
p.family = AF_INET;
|
|
p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
|
|
p.prefixlen = 0;
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
zlog_debug(
|
|
"ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4",
|
|
&area->area_id);
|
|
ospf_abr_announce_network_to_area(&p, area->default_cost, area);
|
|
|
|
|
|
ospf_area_check_free(ospf, area_id);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_export_list,
|
|
ospf_area_export_list_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST4_NAME",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Set the filter for networks announced to other areas\n"
|
|
"Name of the access-list\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
ospf_area_export_list_set(ospf, area, argv[3]->arg);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_export_list,
|
|
no_ospf_area_export_list_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST4_NAME",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Unset the filter for networks announced to other areas\n"
|
|
"Name of the access-list\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (area == NULL)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf_area_export_list_unset(ospf, area);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_area_import_list,
|
|
ospf_area_import_list_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST4_NAME",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Set the filter for networks from other areas announced to the specified one\n"
|
|
"Name of the access-list\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
ospf_area_import_list_set(ospf, area, argv[3]->arg);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_import_list,
|
|
no_ospf_area_import_list_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST4_NAME",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Unset the filter for networks announced to other areas\n"
|
|
"Name of the access-list\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (area == NULL)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf_area_import_list_unset(ospf, area);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_filter_list,
|
|
ospf_area_filter_list_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST4_NAME <in|out>",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Filter networks between OSPF areas\n"
|
|
"Filter prefixes between OSPF areas\n"
|
|
"Name of an IP prefix-list\n"
|
|
"Filter networks sent to this area\n"
|
|
"Filter networks sent from this area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
int idx_word = 4;
|
|
int idx_in_out = 5;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
struct prefix_list *plist;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
plist = prefix_list_lookup(AFI_IP, argv[idx_word]->arg);
|
|
if (strncmp(argv[idx_in_out]->arg, "in", 2) == 0) {
|
|
PREFIX_LIST_IN(area) = plist;
|
|
if (PREFIX_NAME_IN(area))
|
|
free(PREFIX_NAME_IN(area));
|
|
|
|
PREFIX_NAME_IN(area) = strdup(argv[idx_word]->arg);
|
|
ospf_schedule_abr_task(ospf);
|
|
} else {
|
|
PREFIX_LIST_OUT(area) = plist;
|
|
if (PREFIX_NAME_OUT(area))
|
|
free(PREFIX_NAME_OUT(area));
|
|
|
|
PREFIX_NAME_OUT(area) = strdup(argv[idx_word]->arg);
|
|
ospf_schedule_abr_task(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_filter_list,
|
|
no_ospf_area_filter_list_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST4_NAME <in|out>",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Filter networks between OSPF areas\n"
|
|
"Filter prefixes between OSPF areas\n"
|
|
"Name of an IP prefix-list\n"
|
|
"Filter networks sent to this area\n"
|
|
"Filter networks sent from this area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
int idx_word = 5;
|
|
int idx_in_out = 6;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
if ((area = ospf_area_lookup_by_area_id(ospf, area_id)) == NULL)
|
|
return CMD_SUCCESS;
|
|
|
|
if (strncmp(argv[idx_in_out]->arg, "in", 2) == 0) {
|
|
if (PREFIX_NAME_IN(area))
|
|
if (strcmp(PREFIX_NAME_IN(area), argv[idx_word]->arg)
|
|
!= 0)
|
|
return CMD_SUCCESS;
|
|
|
|
PREFIX_LIST_IN(area) = NULL;
|
|
if (PREFIX_NAME_IN(area))
|
|
free(PREFIX_NAME_IN(area));
|
|
|
|
PREFIX_NAME_IN(area) = NULL;
|
|
|
|
ospf_schedule_abr_task(ospf);
|
|
} else {
|
|
if (PREFIX_NAME_OUT(area))
|
|
if (strcmp(PREFIX_NAME_OUT(area), argv[idx_word]->arg)
|
|
!= 0)
|
|
return CMD_SUCCESS;
|
|
|
|
PREFIX_LIST_OUT(area) = NULL;
|
|
if (PREFIX_NAME_OUT(area))
|
|
free(PREFIX_NAME_OUT(area));
|
|
|
|
PREFIX_NAME_OUT(area) = NULL;
|
|
|
|
ospf_schedule_abr_task(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_area_authentication_message_digest,
|
|
ospf_area_authentication_message_digest_cmd,
|
|
"[no] area <A.B.C.D|(0-4294967295)> authentication message-digest",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Enable authentication\n"
|
|
"Use message-digest authentication\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx = 0;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
argv_find(argv, argc, "area", &idx);
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx + 1]->arg);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
area->auth_type = strmatch(argv[0]->text, "no")
|
|
? OSPF_AUTH_NULL
|
|
: OSPF_AUTH_CRYPTOGRAPHIC;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_area_authentication,
|
|
ospf_area_authentication_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> authentication",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Enable authentication\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 1;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
ospf_area_display_format_set(ospf, area, format);
|
|
area->auth_type = OSPF_AUTH_SIMPLE;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_area_authentication,
|
|
no_ospf_area_authentication_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> authentication",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Enable authentication\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ipv4_number = 2;
|
|
struct ospf_area *area;
|
|
struct in_addr area_id;
|
|
int format;
|
|
|
|
VTY_GET_OSPF_AREA_ID(area_id, format, argv[idx_ipv4_number]->arg);
|
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (area == NULL)
|
|
return CMD_SUCCESS;
|
|
|
|
area->auth_type = OSPF_AUTH_NULL;
|
|
|
|
ospf_area_check_free(ospf, area_id);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_abr_type,
|
|
ospf_abr_type_cmd,
|
|
"ospf abr-type <cisco|ibm|shortcut|standard>",
|
|
"OSPF specific commands\n"
|
|
"Set OSPF ABR type\n"
|
|
"Alternative ABR, cisco implementation\n"
|
|
"Alternative ABR, IBM implementation\n"
|
|
"Shortcut ABR\n"
|
|
"Standard behavior (RFC2328)\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_vendor = 2;
|
|
uint8_t abr_type = OSPF_ABR_UNKNOWN;
|
|
|
|
if (strncmp(argv[idx_vendor]->arg, "c", 1) == 0)
|
|
abr_type = OSPF_ABR_CISCO;
|
|
else if (strncmp(argv[idx_vendor]->arg, "i", 1) == 0)
|
|
abr_type = OSPF_ABR_IBM;
|
|
else if (strncmp(argv[idx_vendor]->arg, "sh", 2) == 0)
|
|
abr_type = OSPF_ABR_SHORTCUT;
|
|
else if (strncmp(argv[idx_vendor]->arg, "st", 2) == 0)
|
|
abr_type = OSPF_ABR_STAND;
|
|
else
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
/* If ABR type value is changed, schedule ABR task. */
|
|
if (ospf->abr_type != abr_type) {
|
|
ospf->abr_type = abr_type;
|
|
ospf_schedule_abr_task(ospf);
|
|
|
|
/* The ABR task might not initiate SPF recalculation if the
|
|
* OSPF flags remain the same. And inter-area routes would not
|
|
* be added/deleted according to the new ABR type. So this
|
|
* needs to be done here too.
|
|
*/
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_abr_type,
|
|
no_ospf_abr_type_cmd,
|
|
"no ospf abr-type [<cisco|ibm|shortcut|standard>]",
|
|
NO_STR
|
|
"OSPF specific commands\n"
|
|
"Set OSPF ABR type\n"
|
|
"Alternative ABR, cisco implementation\n"
|
|
"Alternative ABR, IBM implementation\n"
|
|
"Shortcut ABR\n"
|
|
"Standard ABR\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_vendor = 3;
|
|
uint8_t abr_type = OSPF_ABR_UNKNOWN;
|
|
|
|
if (strncmp(argv[idx_vendor]->arg, "c", 1) == 0)
|
|
abr_type = OSPF_ABR_CISCO;
|
|
else if (strncmp(argv[idx_vendor]->arg, "i", 1) == 0)
|
|
abr_type = OSPF_ABR_IBM;
|
|
else if (strncmp(argv[idx_vendor]->arg, "sh", 2) == 0)
|
|
abr_type = OSPF_ABR_SHORTCUT;
|
|
else if (strncmp(argv[idx_vendor]->arg, "st", 2) == 0)
|
|
abr_type = OSPF_ABR_STAND;
|
|
else
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
/* If ABR type value is changed, schedule ABR task. */
|
|
if (ospf->abr_type == abr_type) {
|
|
ospf->abr_type = OSPF_ABR_DEFAULT;
|
|
ospf_schedule_abr_task(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_log_adjacency_changes,
|
|
ospf_log_adjacency_changes_cmd,
|
|
"log-adjacency-changes",
|
|
"Log changes in adjacency state\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
|
|
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_log_adjacency_changes_detail,
|
|
ospf_log_adjacency_changes_detail_cmd,
|
|
"log-adjacency-changes detail",
|
|
"Log changes in adjacency state\n"
|
|
"Log all state changes\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
|
|
SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_log_adjacency_changes,
|
|
no_ospf_log_adjacency_changes_cmd,
|
|
"no log-adjacency-changes",
|
|
NO_STR
|
|
"Log changes in adjacency state\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
|
|
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_log_adjacency_changes_detail,
|
|
no_ospf_log_adjacency_changes_detail_cmd,
|
|
"no log-adjacency-changes detail",
|
|
NO_STR
|
|
"Log changes in adjacency state\n"
|
|
"Log all state changes\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_compatible_rfc1583,
|
|
ospf_compatible_rfc1583_cmd,
|
|
"compatible rfc1583",
|
|
"OSPF compatibility list\n"
|
|
"compatible with RFC 1583\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
|
|
SET_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE);
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_compatible_rfc1583,
|
|
no_ospf_compatible_rfc1583_cmd,
|
|
"no compatible rfc1583",
|
|
NO_STR
|
|
"OSPF compatibility list\n"
|
|
"compatible with RFC 1583\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
|
|
UNSET_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE);
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ALIAS(ospf_compatible_rfc1583, ospf_rfc1583_flag_cmd,
|
|
"ospf rfc1583compatibility",
|
|
"OSPF specific commands\n"
|
|
"Enable the RFC1583Compatibility flag\n")
|
|
|
|
ALIAS(no_ospf_compatible_rfc1583, no_ospf_rfc1583_flag_cmd,
|
|
"no ospf rfc1583compatibility", NO_STR
|
|
"OSPF specific commands\n"
|
|
"Disable the RFC1583Compatibility flag\n")
|
|
|
|
static void ospf_table_reinstall_routes(struct ospf *ospf,
|
|
struct route_table *rt)
|
|
{
|
|
struct route_node *rn;
|
|
|
|
if (!rt)
|
|
return;
|
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
|
struct ospf_route *or;
|
|
|
|
or = rn->info;
|
|
if (!or)
|
|
continue;
|
|
|
|
if (or->type == OSPF_DESTINATION_NETWORK)
|
|
ospf_zebra_add(ospf, (struct prefix_ipv4 *)&rn->p, or);
|
|
else if (or->type == OSPF_DESTINATION_DISCARD)
|
|
ospf_zebra_add_discard(ospf,
|
|
(struct prefix_ipv4 *)&rn->p);
|
|
}
|
|
}
|
|
|
|
static void ospf_reinstall_routes(struct ospf *ospf)
|
|
{
|
|
ospf_table_reinstall_routes(ospf, ospf->new_table);
|
|
ospf_table_reinstall_routes(ospf, ospf->new_external_route);
|
|
}
|
|
|
|
DEFPY (ospf_send_extra_data,
|
|
ospf_send_extra_data_cmd,
|
|
"[no] ospf send-extra-data zebra",
|
|
NO_STR
|
|
OSPF_STR
|
|
"Extra data to Zebra for display/use\n"
|
|
"To zebra\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (no && CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
|
UNSET_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA);
|
|
ospf_reinstall_routes(ospf);
|
|
} else if (!CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
|
SET_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA);
|
|
ospf_reinstall_routes(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static int ospf_timers_spf_set(struct vty *vty, unsigned int delay,
|
|
unsigned int hold, unsigned int max)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (ospf->spf_delay != delay || ospf->spf_holdtime != hold ||
|
|
ospf->spf_max_holdtime != max)
|
|
ospf->spf_hold_multiplier = 1;
|
|
|
|
ospf->spf_delay = delay;
|
|
ospf->spf_holdtime = hold;
|
|
ospf->spf_max_holdtime = max;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_timers_min_ls_interval,
|
|
ospf_timers_min_ls_interval_cmd,
|
|
"timers throttle lsa all (0-5000)",
|
|
"Adjust routing timers\n"
|
|
"Throttling adaptive timer\n"
|
|
"LSA delay between transmissions\n"
|
|
"All LSA types\n"
|
|
"Delay (msec) between sending LSAs\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 4;
|
|
unsigned int interval;
|
|
|
|
if (argc < 5) {
|
|
vty_out(vty, "Insufficient arguments\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
interval = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
ospf->min_ls_interval = interval;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_timers_min_ls_interval,
|
|
no_ospf_timers_min_ls_interval_cmd,
|
|
"no timers throttle lsa all [(0-5000)]",
|
|
NO_STR
|
|
"Adjust routing timers\n"
|
|
"Throttling adaptive timer\n"
|
|
"LSA delay between transmissions\n"
|
|
"All LSA types\n"
|
|
"Delay (msec) between sending LSAs\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
ospf->min_ls_interval = OSPF_MIN_LS_INTERVAL;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_timers_throttle_spf,
|
|
ospf_timers_throttle_spf_cmd,
|
|
"timers throttle spf (0-600000) (0-600000) (0-600000)",
|
|
"Adjust routing timers\n"
|
|
"Throttling adaptive timer\n"
|
|
"OSPF SPF timers\n"
|
|
"Delay (msec) from first change received till SPF calculation\n"
|
|
"Initial hold time (msec) between consecutive SPF calculations\n"
|
|
"Maximum hold time (msec)\n")
|
|
{
|
|
int idx_number = 3;
|
|
int idx_number_2 = 4;
|
|
int idx_number_3 = 5;
|
|
unsigned int delay, hold, max;
|
|
|
|
if (argc < 6) {
|
|
vty_out(vty, "Insufficient arguments\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
delay = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
hold = strtoul(argv[idx_number_2]->arg, NULL, 10);
|
|
max = strtoul(argv[idx_number_3]->arg, NULL, 10);
|
|
|
|
return ospf_timers_spf_set(vty, delay, hold, max);
|
|
}
|
|
|
|
DEFUN (no_ospf_timers_throttle_spf,
|
|
no_ospf_timers_throttle_spf_cmd,
|
|
"no timers throttle spf [(0-600000)(0-600000)(0-600000)]",
|
|
NO_STR
|
|
"Adjust routing timers\n"
|
|
"Throttling adaptive timer\n"
|
|
"OSPF SPF timers\n"
|
|
"Delay (msec) from first change received till SPF calculation\n"
|
|
"Initial hold time (msec) between consecutive SPF calculations\n"
|
|
"Maximum hold time (msec)\n")
|
|
{
|
|
return ospf_timers_spf_set(vty, OSPF_SPF_DELAY_DEFAULT,
|
|
OSPF_SPF_HOLDTIME_DEFAULT,
|
|
OSPF_SPF_MAX_HOLDTIME_DEFAULT);
|
|
}
|
|
|
|
|
|
DEFUN (ospf_timers_lsa_min_arrival,
|
|
ospf_timers_lsa_min_arrival_cmd,
|
|
"timers lsa min-arrival (0-600000)",
|
|
"Adjust routing timers\n"
|
|
"OSPF LSA timers\n"
|
|
"Minimum delay in receiving new version of a LSA\n"
|
|
"Delay in milliseconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
ospf->min_ls_arrival = strtoul(argv[argc - 1]->arg, NULL, 10);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_timers_lsa_min_arrival,
|
|
no_ospf_timers_lsa_min_arrival_cmd,
|
|
"no timers lsa min-arrival [(0-600000)]",
|
|
NO_STR
|
|
"Adjust routing timers\n"
|
|
"OSPF LSA timers\n"
|
|
"Minimum delay in receiving new version of a LSA\n"
|
|
"Delay in milliseconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
unsigned int minarrival;
|
|
|
|
if (argc > 4) {
|
|
minarrival = strtoul(argv[argc - 1]->arg, NULL, 10);
|
|
|
|
if (ospf->min_ls_arrival != minarrival
|
|
|| minarrival == OSPF_MIN_LS_ARRIVAL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ospf_neighbor, ospf_neighbor_cmd,
|
|
"[no] neighbor A.B.C.D$nbr_address [{priority (0-255)$priority | poll-interval (1-65535)$interval}]",
|
|
NO_STR
|
|
NEIGHBOR_STR
|
|
"Neighbor IP address\n"
|
|
"Neighbor Priority\n"
|
|
"Priority\n"
|
|
"Dead Neighbor Polling interval\n"
|
|
"Seconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (no)
|
|
ospf_nbr_nbma_unset(ospf, nbr_address);
|
|
else {
|
|
ospf_nbr_nbma_set(ospf, nbr_address);
|
|
if (priority_str)
|
|
ospf_nbr_nbma_priority_set(ospf, nbr_address, priority);
|
|
|
|
if (interval_str)
|
|
ospf_nbr_nbma_poll_interval_set(ospf, nbr_address,
|
|
interval);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_refresh_timer,
|
|
ospf_refresh_timer_cmd,
|
|
"refresh timer (10-1800)",
|
|
"Adjust refresh parameters\n"
|
|
"Set refresh timer\n"
|
|
"Timer value in seconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 2;
|
|
unsigned int interval;
|
|
|
|
interval = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
interval = (interval / OSPF_LSA_REFRESHER_GRANULARITY)
|
|
* OSPF_LSA_REFRESHER_GRANULARITY;
|
|
|
|
ospf_timers_refresh_set(ospf, interval);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_refresh_timer,
|
|
no_ospf_refresh_timer_val_cmd,
|
|
"no refresh timer [(10-1800)]",
|
|
NO_STR
|
|
"Adjust refresh parameters\n"
|
|
"Unset refresh timer\n"
|
|
"Timer value in seconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 3;
|
|
unsigned int interval;
|
|
|
|
if (argc == 1) {
|
|
interval = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
if (ospf->lsa_refresh_interval != interval
|
|
|| interval == OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_timers_refresh_unset(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_auto_cost_reference_bandwidth,
|
|
ospf_auto_cost_reference_bandwidth_cmd,
|
|
"auto-cost reference-bandwidth (1-4294967)",
|
|
"Calculate OSPF interface cost according to bandwidth\n"
|
|
"Use reference bandwidth method to assign OSPF cost\n"
|
|
"The reference bandwidth in terms of Mbits per second\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
|
|
int idx_number = 2;
|
|
uint32_t refbw;
|
|
struct interface *ifp;
|
|
|
|
refbw = strtol(argv[idx_number]->arg, NULL, 10);
|
|
if (refbw < 1 || refbw > 4294967) {
|
|
vty_out(vty, "reference-bandwidth value is invalid\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* If reference bandwidth is changed. */
|
|
if ((refbw) == ospf->ref_bandwidth)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf->ref_bandwidth = refbw;
|
|
FOR_ALL_INTERFACES (vrf, ifp)
|
|
ospf_if_recalculate_output_cost(ifp);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_auto_cost_reference_bandwidth,
|
|
no_ospf_auto_cost_reference_bandwidth_cmd,
|
|
"no auto-cost reference-bandwidth [(1-4294967)]",
|
|
NO_STR
|
|
"Calculate OSPF interface cost according to bandwidth\n"
|
|
"Use reference bandwidth method to assign OSPF cost\n"
|
|
"The reference bandwidth in terms of Mbits per second\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
|
|
struct interface *ifp;
|
|
|
|
if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
|
|
vty_out(vty, "%% OSPF: Reference bandwidth is changed.\n");
|
|
vty_out(vty,
|
|
" Please ensure reference bandwidth is consistent across all routers\n");
|
|
|
|
FOR_ALL_INTERFACES (vrf, ifp)
|
|
ospf_if_recalculate_output_cost(ifp);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_write_multiplier,
|
|
ospf_write_multiplier_cmd,
|
|
"ospf write-multiplier (1-100)",
|
|
"OSPF specific commands\n"
|
|
"Write multiplier\n"
|
|
"Maximum number of interface serviced per write\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number;
|
|
uint32_t write_oi_count;
|
|
|
|
if (argc == 3)
|
|
idx_number = 2;
|
|
else
|
|
idx_number = 1;
|
|
|
|
write_oi_count = strtol(argv[idx_number]->arg, NULL, 10);
|
|
if (write_oi_count < 1 || write_oi_count > 100) {
|
|
vty_out(vty, "write-multiplier value is invalid\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ospf->write_oi_count = write_oi_count;
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ALIAS(ospf_write_multiplier, write_multiplier_cmd, "write-multiplier (1-100)",
|
|
"Write multiplier\n"
|
|
"Maximum number of interface serviced per write\n")
|
|
|
|
DEFUN (no_ospf_write_multiplier,
|
|
no_ospf_write_multiplier_cmd,
|
|
"no ospf write-multiplier (1-100)",
|
|
NO_STR
|
|
"OSPF specific commands\n"
|
|
"Write multiplier\n"
|
|
"Maximum number of interface serviced per write\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT;
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ALIAS(no_ospf_write_multiplier, no_write_multiplier_cmd,
|
|
"no write-multiplier [(1-100)]", NO_STR
|
|
"Write multiplier\n"
|
|
"Maximum number of interface serviced per write\n")
|
|
|
|
DEFUN(ospf_ti_lfa, ospf_ti_lfa_cmd, "fast-reroute ti-lfa [node-protection]",
|
|
"Fast Reroute for MPLS and IP resilience\n"
|
|
"Topology Independent LFA (Loop-Free Alternate)\n"
|
|
"TI-LFA node protection (default is link protection)\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->ti_lfa_enabled = true;
|
|
|
|
if (argc == 3)
|
|
ospf->ti_lfa_protection_type = OSPF_TI_LFA_NODE_PROTECTION;
|
|
else
|
|
ospf->ti_lfa_protection_type = OSPF_TI_LFA_LINK_PROTECTION;
|
|
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN(no_ospf_ti_lfa, no_ospf_ti_lfa_cmd,
|
|
"no fast-reroute ti-lfa [node-protection]",
|
|
NO_STR
|
|
"Fast Reroute for MPLS and IP resilience\n"
|
|
"Topology Independent LFA (Loop-Free Alternate)\n"
|
|
"TI-LFA node protection (default is link protection)\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->ti_lfa_enabled = false;
|
|
|
|
ospf->ti_lfa_protection_type = OSPF_TI_LFA_UNDEFINED_PROTECTION;
|
|
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_CONFIG_CHANGE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static void ospf_maxpath_set(struct vty *vty, struct ospf *ospf, uint16_t paths)
|
|
{
|
|
if (ospf->max_multipath == paths)
|
|
return;
|
|
|
|
ospf->max_multipath = paths;
|
|
|
|
/* Send deletion notification to zebra to delete all
|
|
* ospf specific routes and reinitiat SPF to reflect
|
|
* the new max multipath.
|
|
*/
|
|
ospf_restart_spf(ospf);
|
|
}
|
|
|
|
/* Ospf Maximum multiple paths config support */
|
|
DEFUN (ospf_max_multipath,
|
|
ospf_max_multipath_cmd,
|
|
"maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
|
|
"Max no of multiple paths for ECMP support\n"
|
|
"Number of paths\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 1;
|
|
uint16_t maxpaths;
|
|
|
|
maxpaths = strtol(argv[idx_number]->arg, NULL, 10);
|
|
|
|
ospf_maxpath_set(vty, ospf, maxpaths);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_max_multipath,
|
|
no_ospf_max_multipath_cmd,
|
|
"no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM)"]",
|
|
NO_STR
|
|
"Max no of multiple paths for ECMP support\n"
|
|
"Number of paths\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
uint16_t maxpaths = MULTIPATH_NUM;
|
|
|
|
ospf_maxpath_set(vty, ospf, maxpaths);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static const char *const ospf_abr_type_descr_str[] = {
|
|
"Unknown", "Standard (RFC2328)", "Alternative IBM",
|
|
"Alternative Cisco", "Alternative Shortcut"
|
|
};
|
|
|
|
static const char *const ospf_shortcut_mode_descr_str[] = {
|
|
"Default", "Enabled", "Disabled"
|
|
};
|
|
|
|
static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area,
|
|
json_object *json_areas, bool use_json)
|
|
{
|
|
json_object *json_area = NULL;
|
|
char buf[PREFIX_STRLEN];
|
|
|
|
if (use_json)
|
|
json_area = json_object_new_object();
|
|
|
|
/* Show Area ID. */
|
|
if (!use_json)
|
|
vty_out(vty, " Area ID: %pI4", &area->area_id);
|
|
|
|
/* Show Area type/mode. */
|
|
if (OSPF_IS_AREA_BACKBONE(area)) {
|
|
if (use_json)
|
|
json_object_boolean_true_add(json_area, "backbone");
|
|
else
|
|
vty_out(vty, " (Backbone)\n");
|
|
} else {
|
|
if (use_json) {
|
|
if (area->external_routing == OSPF_AREA_STUB) {
|
|
if (area->no_summary)
|
|
json_object_boolean_true_add(
|
|
json_area, "stubNoSummary");
|
|
if (area->shortcut_configured)
|
|
json_object_boolean_true_add(
|
|
json_area, "stubShortcut");
|
|
} else if (area->external_routing == OSPF_AREA_NSSA) {
|
|
if (area->no_summary)
|
|
json_object_boolean_true_add(
|
|
json_area, "nssaNoSummary");
|
|
if (area->shortcut_configured)
|
|
json_object_boolean_true_add(
|
|
json_area, "nssaShortcut");
|
|
}
|
|
|
|
json_object_string_add(
|
|
json_area, "shortcuttingMode",
|
|
ospf_shortcut_mode_descr_str
|
|
[area->shortcut_configured]);
|
|
if (area->shortcut_capability)
|
|
json_object_boolean_true_add(json_area,
|
|
"sBitConcensus");
|
|
} else {
|
|
if (area->external_routing == OSPF_AREA_STUB)
|
|
vty_out(vty, " (Stub%s%s)",
|
|
area->no_summary ? ", no summary" : "",
|
|
area->shortcut_configured ? "; " : "");
|
|
else if (area->external_routing == OSPF_AREA_NSSA)
|
|
vty_out(vty, " (NSSA%s%s)",
|
|
area->no_summary ? ", no summary" : "",
|
|
area->shortcut_configured ? "; " : "");
|
|
|
|
vty_out(vty, "\n");
|
|
vty_out(vty, " Shortcutting mode: %s",
|
|
ospf_shortcut_mode_descr_str
|
|
[area->shortcut_configured]);
|
|
vty_out(vty, ", S-bit consensus: %s\n",
|
|
area->shortcut_capability ? "ok" : "no");
|
|
}
|
|
}
|
|
|
|
/* Show number of interfaces */
|
|
if (use_json) {
|
|
json_object_int_add(json_area, "areaIfTotalCounter",
|
|
listcount(area->oiflist));
|
|
json_object_int_add(json_area, "areaIfActiveCounter",
|
|
area->act_ints);
|
|
} else
|
|
vty_out(vty,
|
|
" Number of interfaces in this area: Total: %d, Active: %d\n",
|
|
listcount(area->oiflist), area->act_ints);
|
|
|
|
if (area->external_routing == OSPF_AREA_NSSA) {
|
|
if (use_json) {
|
|
json_object_boolean_true_add(json_area, "nssa");
|
|
if (!IS_OSPF_ABR(area->ospf))
|
|
json_object_boolean_false_add(json_area, "abr");
|
|
else if (area->NSSATranslatorState) {
|
|
json_object_boolean_true_add(json_area, "abr");
|
|
if (area->NSSATranslatorRole
|
|
== OSPF_NSSA_ROLE_CANDIDATE)
|
|
json_object_boolean_true_add(
|
|
json_area,
|
|
"nssaTranslatorElected");
|
|
else if (area->NSSATranslatorRole
|
|
== OSPF_NSSA_ROLE_ALWAYS)
|
|
json_object_boolean_true_add(
|
|
json_area,
|
|
"nssaTranslatorAlways");
|
|
else
|
|
json_object_boolean_true_add(
|
|
json_area,
|
|
"nssaTranslatorNever");
|
|
} else {
|
|
json_object_boolean_true_add(json_area, "abr");
|
|
if (area->NSSATranslatorRole
|
|
== OSPF_NSSA_ROLE_CANDIDATE)
|
|
json_object_boolean_false_add(
|
|
json_area,
|
|
"nssaTranslatorElected");
|
|
else
|
|
json_object_boolean_true_add(
|
|
json_area,
|
|
"nssaTranslatorNever");
|
|
}
|
|
} else {
|
|
vty_out(vty,
|
|
" It is an NSSA configuration.\n Elected NSSA/ABR performs type-7/type-5 LSA translation.\n");
|
|
if (!IS_OSPF_ABR(area->ospf))
|
|
vty_out(vty,
|
|
" It is not ABR, therefore not Translator.\n");
|
|
else if (area->NSSATranslatorState) {
|
|
vty_out(vty, " We are an ABR and ");
|
|
if (area->NSSATranslatorRole
|
|
== OSPF_NSSA_ROLE_CANDIDATE)
|
|
vty_out(vty,
|
|
"the NSSA Elected Translator.\n");
|
|
else if (area->NSSATranslatorRole
|
|
== OSPF_NSSA_ROLE_ALWAYS)
|
|
vty_out(vty,
|
|
"always an NSSA Translator.\n");
|
|
else
|
|
vty_out(vty,
|
|
"never an NSSA Translator.\n");
|
|
} else {
|
|
vty_out(vty, " We are an ABR, but ");
|
|
if (area->NSSATranslatorRole
|
|
== OSPF_NSSA_ROLE_CANDIDATE)
|
|
vty_out(vty,
|
|
"not the NSSA Elected Translator.\n");
|
|
else
|
|
vty_out(vty,
|
|
"never an NSSA Translator.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Stub-router state for this area */
|
|
if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) {
|
|
char timebuf[OSPF_TIME_DUMP_SIZE];
|
|
|
|
if (use_json) {
|
|
json_object_boolean_true_add(
|
|
json_area, "originStubMaxDistRouterLsa");
|
|
if (CHECK_FLAG(area->stub_router_state,
|
|
OSPF_AREA_ADMIN_STUB_ROUTED))
|
|
json_object_boolean_true_add(
|
|
json_area, "indefiniteActiveAdmin");
|
|
if (area->t_stub_router) {
|
|
long time_store;
|
|
time_store =
|
|
monotime_until(
|
|
&area->t_stub_router->u.sands,
|
|
NULL)
|
|
/ 1000LL;
|
|
json_object_int_add(
|
|
json_area,
|
|
"activeStartupRemainderMsecs",
|
|
time_store);
|
|
}
|
|
} else {
|
|
vty_out(vty,
|
|
" Originating stub / maximum-distance Router-LSA\n");
|
|
if (CHECK_FLAG(area->stub_router_state,
|
|
OSPF_AREA_ADMIN_STUB_ROUTED))
|
|
vty_out(vty,
|
|
" Administratively activated (indefinitely)\n");
|
|
if (area->t_stub_router)
|
|
vty_out(vty,
|
|
" Active from startup, %s remaining\n",
|
|
ospf_timer_dump(area->t_stub_router,
|
|
timebuf,
|
|
sizeof(timebuf)));
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
/* Show number of fully adjacent neighbors. */
|
|
json_object_int_add(json_area, "nbrFullAdjacentCounter",
|
|
area->full_nbrs);
|
|
|
|
/* Show authentication type. */
|
|
if (area->auth_type == OSPF_AUTH_NULL)
|
|
json_object_string_add(json_area, "authentication",
|
|
"authenticationNone");
|
|
else if (area->auth_type == OSPF_AUTH_SIMPLE)
|
|
json_object_string_add(json_area, "authentication",
|
|
"authenticationSimplePassword");
|
|
else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC)
|
|
json_object_string_add(json_area, "authentication",
|
|
"authenticationMessageDigest");
|
|
|
|
if (!OSPF_IS_AREA_BACKBONE(area))
|
|
json_object_int_add(json_area,
|
|
"virtualAdjacenciesPassingCounter",
|
|
area->full_vls);
|
|
|
|
/* Show SPF calculation times. */
|
|
json_object_int_add(json_area, "spfExecutedCounter",
|
|
area->spf_calculation);
|
|
json_object_int_add(json_area, "lsaNumber", area->lsdb->total);
|
|
json_object_int_add(
|
|
json_area, "lsaRouterNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaRouterChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_ROUTER_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaNetworkNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_NETWORK_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaNetworkChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_NETWORK_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaSummaryNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_SUMMARY_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaSummaryChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_SUMMARY_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaAsbrNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_ASBR_SUMMARY_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaAsbrChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_ASBR_SUMMARY_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaNssaNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_AS_NSSA_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaNssaChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_AS_NSSA_LSA));
|
|
} else {
|
|
/* Show number of fully adjacent neighbors. */
|
|
vty_out(vty,
|
|
" Number of fully adjacent neighbors in this area: %d\n",
|
|
area->full_nbrs);
|
|
|
|
/* Show authentication type. */
|
|
vty_out(vty, " Area has ");
|
|
if (area->auth_type == OSPF_AUTH_NULL)
|
|
vty_out(vty, "no authentication\n");
|
|
else if (area->auth_type == OSPF_AUTH_SIMPLE)
|
|
vty_out(vty, "simple password authentication\n");
|
|
else if (area->auth_type == OSPF_AUTH_CRYPTOGRAPHIC)
|
|
vty_out(vty, "message digest authentication\n");
|
|
|
|
if (!OSPF_IS_AREA_BACKBONE(area))
|
|
vty_out(vty,
|
|
" Number of full virtual adjacencies going through this area: %d\n",
|
|
area->full_vls);
|
|
|
|
/* Show SPF calculation times. */
|
|
vty_out(vty, " SPF algorithm executed %d times\n",
|
|
area->spf_calculation);
|
|
|
|
/* Show number of LSA. */
|
|
vty_out(vty, " Number of LSA %ld\n", area->lsdb->total);
|
|
vty_out(vty,
|
|
" Number of router LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_ROUTER_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_ROUTER_LSA));
|
|
vty_out(vty,
|
|
" Number of network LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_NETWORK_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_NETWORK_LSA));
|
|
vty_out(vty,
|
|
" Number of summary LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_SUMMARY_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_SUMMARY_LSA));
|
|
vty_out(vty,
|
|
" Number of ASBR summary LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_ASBR_SUMMARY_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_ASBR_SUMMARY_LSA));
|
|
vty_out(vty, " Number of NSSA LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_AS_NSSA_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_AS_NSSA_LSA));
|
|
}
|
|
|
|
if (use_json) {
|
|
json_object_int_add(
|
|
json_area, "lsaOpaqueLinkNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_LINK_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaOpaqueLinkChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_LINK_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaOpaqueAreaNumber",
|
|
ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_AREA_LSA));
|
|
json_object_int_add(
|
|
json_area, "lsaOpaqueAreaChecksum",
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA));
|
|
} else {
|
|
vty_out(vty,
|
|
" Number of opaque link LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_LINK_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_LINK_LSA));
|
|
vty_out(vty,
|
|
" Number of opaque area LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(area->lsdb, OSPF_OPAQUE_AREA_LSA),
|
|
ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA));
|
|
}
|
|
|
|
if (area->fr_info.configured) {
|
|
if (use_json)
|
|
json_object_string_add(json_area, "areaFloodReduction",
|
|
"configured");
|
|
else
|
|
vty_out(vty, " Flood Reduction is configured.\n");
|
|
}
|
|
|
|
if (area->fr_info.enabled) {
|
|
if (use_json) {
|
|
json_object_boolean_true_add(
|
|
json_area, "areaFloodReductionEnabled");
|
|
if (area->fr_info.router_lsas_recv_dc_bit)
|
|
json_object_boolean_true_add(
|
|
json_area, "lsasRecvDCbitSet");
|
|
if (area->fr_info.area_ind_lsa_recvd)
|
|
json_object_string_add(json_area,
|
|
"areaIndicationLsaRecv",
|
|
"received");
|
|
if (area->fr_info.indication_lsa_self)
|
|
json_object_string_addf(
|
|
json_area, "areaIndicationLsa", "%pI4",
|
|
&area->fr_info.indication_lsa_self->data
|
|
->id);
|
|
} else {
|
|
vty_out(vty, " Flood Reduction is enabled.\n");
|
|
vty_out(vty, " No of LSAs rcv'd with DC bit set %d\n",
|
|
area->fr_info.router_lsas_recv_dc_bit);
|
|
if (area->fr_info.area_ind_lsa_recvd)
|
|
vty_out(vty, " Ind LSA by other abr.\n");
|
|
if (area->fr_info.indication_lsa_self)
|
|
vty_out(vty, " Ind LSA generated %pI4\n",
|
|
&area->fr_info.indication_lsa_self->data
|
|
->id);
|
|
}
|
|
}
|
|
|
|
if (use_json)
|
|
json_object_object_add(json_areas,
|
|
inet_ntop(AF_INET, &area->area_id,
|
|
buf, sizeof(buf)),
|
|
json_area);
|
|
else
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
|
|
json_object *json, uint8_t use_vrf)
|
|
{
|
|
struct listnode *node, *nnode;
|
|
struct ospf_area *area;
|
|
struct timeval result;
|
|
char timebuf[OSPF_TIME_DUMP_SIZE];
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_areas = NULL;
|
|
|
|
if (json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
json_areas = json_object_new_object();
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (json) {
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
} else {
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
/* Show Router ID. */
|
|
if (json) {
|
|
json_object_string_addf(json_vrf, "routerId", "%pI4",
|
|
&ospf->router_id);
|
|
} else {
|
|
vty_out(vty, " OSPF Routing Process, Router ID: %pI4\n",
|
|
&ospf->router_id);
|
|
}
|
|
|
|
/* Graceful shutdown */
|
|
if (ospf->t_deferred_shutdown) {
|
|
if (json) {
|
|
long time_store;
|
|
time_store =
|
|
monotime_until(
|
|
&ospf->t_deferred_shutdown->u.sands,
|
|
NULL)
|
|
/ 1000LL;
|
|
json_object_int_add(json_vrf, "deferredShutdownMsecs",
|
|
time_store);
|
|
} else {
|
|
vty_out(vty,
|
|
" Deferred shutdown in progress, %s remaining\n",
|
|
ospf_timer_dump(ospf->t_deferred_shutdown,
|
|
timebuf, sizeof(timebuf)));
|
|
}
|
|
}
|
|
|
|
/* Show capability. */
|
|
if (json) {
|
|
json_object_boolean_true_add(json_vrf, "tosRoutesOnly");
|
|
json_object_boolean_true_add(json_vrf, "rfc2328Conform");
|
|
if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
|
|
json_object_boolean_true_add(json_vrf,
|
|
"rfc1583Compatibility");
|
|
}
|
|
} else {
|
|
vty_out(vty, " Supports only single TOS (TOS0) routes\n");
|
|
vty_out(vty, " This implementation conforms to RFC2328\n");
|
|
vty_out(vty, " RFC1583Compatibility flag is %s\n",
|
|
CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)
|
|
? "enabled"
|
|
: "disabled");
|
|
}
|
|
|
|
if (json) {
|
|
if (CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) {
|
|
json_object_boolean_true_add(json_vrf, "opaqueCapable");
|
|
}
|
|
} else {
|
|
vty_out(vty, " OpaqueCapability flag is %s\n",
|
|
CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)
|
|
? "enabled"
|
|
: "disabled");
|
|
}
|
|
|
|
/* Show stub-router configuration */
|
|
if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED
|
|
|| ospf->stub_router_shutdown_time
|
|
!= OSPF_STUB_ROUTER_UNCONFIGURED) {
|
|
if (json) {
|
|
json_object_boolean_true_add(json_vrf,
|
|
"stubAdvertisement");
|
|
if (ospf->stub_router_startup_time
|
|
!= OSPF_STUB_ROUTER_UNCONFIGURED)
|
|
json_object_int_add(
|
|
json_vrf, "postStartEnabledSecs",
|
|
ospf->stub_router_startup_time);
|
|
if (ospf->stub_router_shutdown_time
|
|
!= OSPF_STUB_ROUTER_UNCONFIGURED)
|
|
json_object_int_add(
|
|
json_vrf, "preShutdownEnabledSecs",
|
|
ospf->stub_router_shutdown_time);
|
|
} else {
|
|
vty_out(vty,
|
|
" Stub router advertisement is configured\n");
|
|
if (ospf->stub_router_startup_time
|
|
!= OSPF_STUB_ROUTER_UNCONFIGURED)
|
|
vty_out(vty,
|
|
" Enabled for %us after start-up\n",
|
|
ospf->stub_router_startup_time);
|
|
if (ospf->stub_router_shutdown_time
|
|
!= OSPF_STUB_ROUTER_UNCONFIGURED)
|
|
vty_out(vty,
|
|
" Enabled for %us prior to full shutdown\n",
|
|
ospf->stub_router_shutdown_time);
|
|
}
|
|
}
|
|
|
|
/* Show SPF timers. */
|
|
if (json) {
|
|
json_object_int_add(json_vrf, "spfScheduleDelayMsecs",
|
|
ospf->spf_delay);
|
|
json_object_int_add(json_vrf, "holdtimeMinMsecs",
|
|
ospf->spf_holdtime);
|
|
json_object_int_add(json_vrf, "holdtimeMaxMsecs",
|
|
ospf->spf_max_holdtime);
|
|
json_object_int_add(json_vrf, "holdtimeMultplier",
|
|
ospf->spf_hold_multiplier);
|
|
} else {
|
|
vty_out(vty,
|
|
" Initial SPF scheduling delay %d millisec(s)\n"
|
|
" Minimum hold time between consecutive SPFs %d millisec(s)\n"
|
|
" Maximum hold time between consecutive SPFs %d millisec(s)\n"
|
|
" Hold time multiplier is currently %d\n",
|
|
ospf->spf_delay, ospf->spf_holdtime,
|
|
ospf->spf_max_holdtime, ospf->spf_hold_multiplier);
|
|
}
|
|
|
|
if (json) {
|
|
if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) {
|
|
long time_store = 0;
|
|
|
|
time_store =
|
|
monotime_since(&ospf->ts_spf, NULL) / 1000LL;
|
|
json_object_int_add(json_vrf, "spfLastExecutedMsecs",
|
|
time_store);
|
|
|
|
time_store = (1000 * ospf->ts_spf_duration.tv_sec)
|
|
+ (ospf->ts_spf_duration.tv_usec / 1000);
|
|
json_object_int_add(json_vrf, "spfLastDurationMsecs",
|
|
time_store);
|
|
} else
|
|
json_object_boolean_true_add(json_vrf, "spfHasNotRun");
|
|
} else {
|
|
vty_out(vty, " SPF algorithm ");
|
|
if (ospf->ts_spf.tv_sec || ospf->ts_spf.tv_usec) {
|
|
monotime_since(&ospf->ts_spf, &result);
|
|
vty_out(vty, "last executed %s ago\n",
|
|
ospf_timeval_dump(&result, timebuf,
|
|
sizeof(timebuf)));
|
|
vty_out(vty, " Last SPF duration %s\n",
|
|
ospf_timeval_dump(&ospf->ts_spf_duration,
|
|
timebuf, sizeof(timebuf)));
|
|
} else
|
|
vty_out(vty, "has not been run\n");
|
|
}
|
|
|
|
if (json) {
|
|
if (ospf->t_spf_calc) {
|
|
long time_store;
|
|
time_store =
|
|
monotime_until(&ospf->t_spf_calc->u.sands, NULL)
|
|
/ 1000LL;
|
|
json_object_int_add(json_vrf, "spfTimerDueInMsecs",
|
|
time_store);
|
|
}
|
|
|
|
json_object_int_add(json_vrf, "lsaMinIntervalMsecs",
|
|
ospf->min_ls_interval);
|
|
json_object_int_add(json_vrf, "lsaMinArrivalMsecs",
|
|
ospf->min_ls_arrival);
|
|
/* Show write multiplier values */
|
|
json_object_int_add(json_vrf, "writeMultiplier",
|
|
ospf->write_oi_count);
|
|
/* Show refresh parameters. */
|
|
json_object_int_add(json_vrf, "refreshTimerMsecs",
|
|
ospf->lsa_refresh_interval * 1000);
|
|
|
|
/* show max multipath */
|
|
json_object_int_add(json_vrf, "maximumPaths",
|
|
ospf->max_multipath);
|
|
|
|
/* show administrative distance */
|
|
json_object_int_add(json_vrf, "preference",
|
|
ospf->distance_all
|
|
? ospf->distance_all
|
|
: ZEBRA_OSPF_DISTANCE_DEFAULT);
|
|
} else {
|
|
vty_out(vty, " SPF timer %s%s\n",
|
|
(ospf->t_spf_calc ? "due in " : "is "),
|
|
ospf_timer_dump(ospf->t_spf_calc, timebuf,
|
|
sizeof(timebuf)));
|
|
|
|
vty_out(vty, " LSA minimum interval %d msecs\n",
|
|
ospf->min_ls_interval);
|
|
vty_out(vty, " LSA minimum arrival %d msecs\n",
|
|
ospf->min_ls_arrival);
|
|
|
|
/* Show write multiplier values */
|
|
vty_out(vty, " Write Multiplier set to %d \n",
|
|
ospf->write_oi_count);
|
|
|
|
/* Show refresh parameters. */
|
|
vty_out(vty, " Refresh timer %d secs\n",
|
|
ospf->lsa_refresh_interval);
|
|
|
|
/* show max multipath */
|
|
vty_out(vty, " Maximum multiple paths(ECMP) supported %d\n",
|
|
ospf->max_multipath);
|
|
|
|
/* show administrative distance */
|
|
vty_out(vty, " Administrative distance %u\n",
|
|
ospf->distance_all ? ospf->distance_all
|
|
: ZEBRA_OSPF_DISTANCE_DEFAULT);
|
|
}
|
|
|
|
if (ospf->fr_configured) {
|
|
if (json)
|
|
json_object_string_add(json_vrf, "floodReduction",
|
|
"configured");
|
|
else
|
|
vty_out(vty, " Flood Reduction is configured.\n");
|
|
}
|
|
|
|
/* Show ABR/ASBR flags. */
|
|
if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ABR)) {
|
|
if (json)
|
|
json_object_string_add(
|
|
json_vrf, "abrType",
|
|
ospf_abr_type_descr_str[ospf->abr_type]);
|
|
else
|
|
vty_out(vty,
|
|
" This router is an ABR, ABR type is: %s\n",
|
|
ospf_abr_type_descr_str[ospf->abr_type]);
|
|
}
|
|
if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ASBR)) {
|
|
if (json)
|
|
json_object_string_add(
|
|
json_vrf, "asbrRouter",
|
|
"injectingExternalRoutingInformation");
|
|
else
|
|
vty_out(vty,
|
|
" This router is an ASBR (injecting external routing information)\n");
|
|
}
|
|
|
|
/* Show Number of AS-external-LSAs. */
|
|
if (json) {
|
|
json_object_int_add(
|
|
json_vrf, "lsaExternalCounter",
|
|
ospf_lsdb_count(ospf->lsdb, OSPF_AS_EXTERNAL_LSA));
|
|
json_object_int_add(
|
|
json_vrf, "lsaExternalChecksum",
|
|
ospf_lsdb_checksum(ospf->lsdb, OSPF_AS_EXTERNAL_LSA));
|
|
} else {
|
|
vty_out(vty,
|
|
" Number of external LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(ospf->lsdb, OSPF_AS_EXTERNAL_LSA),
|
|
ospf_lsdb_checksum(ospf->lsdb, OSPF_AS_EXTERNAL_LSA));
|
|
}
|
|
|
|
if (json) {
|
|
json_object_int_add(
|
|
json_vrf, "lsaAsopaqueCounter",
|
|
ospf_lsdb_count(ospf->lsdb, OSPF_OPAQUE_AS_LSA));
|
|
json_object_int_add(
|
|
json_vrf, "lsaAsOpaqueChecksum",
|
|
ospf_lsdb_checksum(ospf->lsdb, OSPF_OPAQUE_AS_LSA));
|
|
} else {
|
|
vty_out(vty,
|
|
" Number of opaque AS LSA %ld. Checksum Sum 0x%08x\n",
|
|
ospf_lsdb_count(ospf->lsdb, OSPF_OPAQUE_AS_LSA),
|
|
ospf_lsdb_checksum(ospf->lsdb, OSPF_OPAQUE_AS_LSA));
|
|
}
|
|
|
|
/* Show number of areas attached. */
|
|
if (json)
|
|
json_object_int_add(json_vrf, "attachedAreaCounter",
|
|
listcount(ospf->areas));
|
|
else
|
|
vty_out(vty, " Number of areas attached to this router: %d\n",
|
|
listcount(ospf->areas));
|
|
|
|
if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
|
|
if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL)) {
|
|
if (json)
|
|
json_object_boolean_true_add(
|
|
json_vrf, "adjacencyChangesLoggedAll");
|
|
else
|
|
vty_out(vty,
|
|
" All adjacency changes are logged\n");
|
|
} else {
|
|
if (json)
|
|
json_object_boolean_true_add(
|
|
json_vrf, "adjacencyChangesLogged");
|
|
else
|
|
vty_out(vty, " Adjacency changes are logged\n");
|
|
}
|
|
}
|
|
|
|
/* show LDP-Sync status */
|
|
ospf_ldp_sync_show_info(vty, ospf, json_vrf, json ? 1 : 0);
|
|
|
|
/* Socket buffer sizes */
|
|
if (json) {
|
|
if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
|
|
json_object_int_add(json_vrf, "recvSockBufsize",
|
|
ospf->recv_sock_bufsize);
|
|
if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
|
|
json_object_int_add(json_vrf, "sendSockBufsize",
|
|
ospf->send_sock_bufsize);
|
|
} else {
|
|
if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
|
|
vty_out(vty, " Receive socket bufsize: %u\n",
|
|
ospf->recv_sock_bufsize);
|
|
if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
|
|
vty_out(vty, " Send socket bufsize: %u\n",
|
|
ospf->send_sock_bufsize);
|
|
}
|
|
|
|
/* Show each area status. */
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
|
|
show_ip_ospf_area(vty, area, json_areas, json ? 1 : 0);
|
|
|
|
if (json) {
|
|
if (use_vrf) {
|
|
json_object_object_add(json_vrf, "areas", json_areas);
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else {
|
|
json_object_object_add(json, "areas", json_areas);
|
|
}
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf,
|
|
show_ip_ospf_cmd,
|
|
"show ip ospf [vrf <NAME|all>] [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
bool uj = use_json(argc, argv);
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0;
|
|
json_object *json = NULL;
|
|
uint8_t use_vrf = 0;
|
|
|
|
if (listcount(om->ospf) == 0)
|
|
return CMD_SUCCESS;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
bool ospf_output = false;
|
|
|
|
use_vrf = 1;
|
|
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ospf_output = true;
|
|
ret = show_ip_ospf_common(vty, ospf, json,
|
|
use_vrf);
|
|
}
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else if (!ospf_output)
|
|
vty_out(vty, "%% OSPF is not enabled\n");
|
|
return ret;
|
|
}
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if ((ospf == NULL) || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
} else {
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
/* Display default ospf (instance 0) info */
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf default\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf) {
|
|
show_ip_ospf_common(vty, ospf, json, use_vrf);
|
|
if (uj)
|
|
vty_out(vty, "%s\n",
|
|
json_object_to_json_string_ext(
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
}
|
|
|
|
if (uj)
|
|
json_object_free(json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance,
|
|
show_ip_ospf_instance_cmd,
|
|
"show ip ospf (1-65535) [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
JSON_STR)
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool uj = use_json(argc, argv);
|
|
int ret = CMD_SUCCESS;
|
|
json_object *json = NULL;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
ret = show_ip_ospf_common(vty, ospf, json, 0);
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void ospf_interface_auth_show(struct vty *vty, struct ospf_interface *oi,
|
|
json_object *json, bool use_json)
|
|
{
|
|
int auth_type;
|
|
|
|
auth_type = OSPF_IF_PARAM(oi, auth_type);
|
|
|
|
switch (auth_type) {
|
|
case OSPF_AUTH_NULL:
|
|
if (use_json)
|
|
json_object_string_add(json, "authentication",
|
|
"authenticationNone");
|
|
else
|
|
vty_out(vty, " Authentication NULL is enabled\n");
|
|
break;
|
|
case OSPF_AUTH_SIMPLE: {
|
|
if (use_json)
|
|
json_object_string_add(json, "authentication",
|
|
"authenticationSimplePassword");
|
|
else
|
|
vty_out(vty,
|
|
" Simple password authentication enabled\n");
|
|
break;
|
|
}
|
|
case OSPF_AUTH_CRYPTOGRAPHIC: {
|
|
struct crypt_key *ckey;
|
|
|
|
if (OSPF_IF_PARAM(oi, keychain_name)) {
|
|
if (use_json) {
|
|
json_object_string_add(json, "authentication",
|
|
"authenticationKeyChain");
|
|
json_object_string_add(json, "keychain",
|
|
OSPF_IF_PARAM(oi, keychain_name));
|
|
} else {
|
|
vty_out(vty,
|
|
" Cryptographic authentication enabled\n");
|
|
struct keychain *keychain = keychain_lookup(OSPF_IF_PARAM(oi, keychain_name));
|
|
|
|
if (keychain) {
|
|
struct key *key = key_lookup_for_send(keychain);
|
|
|
|
if (key) {
|
|
vty_out(vty, " Sending SA: Key %u, Algorithm %s - key chain %s\n",
|
|
key->index, keychain_get_algo_name_by_id(key->hash_algo),
|
|
OSPF_IF_PARAM(oi, keychain_name));
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (list_isempty(OSPF_IF_PARAM(oi, auth_crypt)))
|
|
return;
|
|
|
|
ckey = listgetdata(listtail(OSPF_IF_PARAM(oi, auth_crypt)));
|
|
if (ckey) {
|
|
if (use_json) {
|
|
json_object_string_add(json, "authentication",
|
|
"authenticationMessageDigest");
|
|
} else {
|
|
vty_out(vty,
|
|
" Cryptographic authentication enabled\n");
|
|
vty_out(vty, " Algorithm:MD5\n");
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
|
|
struct interface *ifp,
|
|
json_object *json_interface_sub,
|
|
bool use_json)
|
|
{
|
|
int is_up;
|
|
struct ospf_neighbor *nbr;
|
|
struct route_node *rn;
|
|
uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed;
|
|
struct ospf_if_params *params;
|
|
|
|
/* Is interface up? */
|
|
if (use_json) {
|
|
is_up = if_is_operative(ifp);
|
|
if (is_up)
|
|
json_object_boolean_true_add(json_interface_sub,
|
|
"ifUp");
|
|
else
|
|
json_object_boolean_false_add(json_interface_sub,
|
|
"ifDown");
|
|
|
|
json_object_int_add(json_interface_sub, "ifIndex",
|
|
ifp->ifindex);
|
|
json_object_int_add(json_interface_sub, "mtuBytes", ifp->mtu);
|
|
json_object_int_add(json_interface_sub, "bandwidthMbit",
|
|
bandwidth);
|
|
json_object_string_add(json_interface_sub, "ifFlags",
|
|
if_flag_dump(ifp->flags));
|
|
} else {
|
|
vty_out(vty, "%s is %s\n", ifp->name,
|
|
((is_up = if_is_operative(ifp)) ? "up" : "down"));
|
|
vty_out(vty, " ifindex %u, MTU %u bytes, BW %u Mbit %s\n",
|
|
ifp->ifindex, ifp->mtu, bandwidth,
|
|
if_flag_dump(ifp->flags));
|
|
}
|
|
|
|
/* Is interface OSPF enabled? */
|
|
if (use_json) {
|
|
if (ospf_oi_count(ifp) == 0) {
|
|
json_object_boolean_false_add(json_interface_sub,
|
|
"ospfEnabled");
|
|
return;
|
|
} else if (!is_up) {
|
|
json_object_boolean_false_add(json_interface_sub,
|
|
"ospfRunning");
|
|
return;
|
|
} else
|
|
json_object_boolean_true_add(json_interface_sub,
|
|
"ospfEnabled");
|
|
} else {
|
|
if (ospf_oi_count(ifp) == 0) {
|
|
vty_out(vty, " OSPF not enabled on this interface\n");
|
|
return;
|
|
} else if (!is_up) {
|
|
vty_out(vty,
|
|
" OSPF is enabled, but not running on this interface\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (oi == NULL)
|
|
continue;
|
|
|
|
if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) {
|
|
if (use_json)
|
|
json_object_boolean_true_add(json_interface_sub,
|
|
"ifUnnumbered");
|
|
else
|
|
vty_out(vty, " This interface is UNNUMBERED,");
|
|
} else {
|
|
struct in_addr dest;
|
|
const char *dstr;
|
|
|
|
/* Show OSPF interface information. */
|
|
if (use_json) {
|
|
json_object_string_addf(
|
|
json_interface_sub, "ipAddress", "%pI4",
|
|
&oi->address->u.prefix4);
|
|
json_object_int_add(json_interface_sub,
|
|
"ipAddressPrefixlen",
|
|
oi->address->prefixlen);
|
|
} else
|
|
vty_out(vty, " Internet Address %pFX,",
|
|
oi->address);
|
|
|
|
/* For Vlinks, showing the peer address is
|
|
* probably more informative than the local
|
|
* interface that is being used */
|
|
if (oi->type == OSPF_IFTYPE_VIRTUALLINK) {
|
|
dstr = "Peer";
|
|
dest = oi->vl_data->peer_addr;
|
|
} else if (CONNECTED_PEER(oi->connected)
|
|
&& oi->connected->destination) {
|
|
dstr = "Peer";
|
|
dest = oi->connected->destination->u.prefix4;
|
|
} else {
|
|
dstr = "Broadcast";
|
|
dest.s_addr = ipv4_broadcast_addr(
|
|
oi->connected->address->u.prefix4.s_addr,
|
|
oi->connected->address->prefixlen);
|
|
}
|
|
|
|
if (use_json) {
|
|
json_object_string_add(json_interface_sub,
|
|
"ospfIfType", dstr);
|
|
|
|
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
|
|
json_object_string_addf(
|
|
json_interface_sub, "vlinkPeer",
|
|
"%pI4", &dest);
|
|
else
|
|
json_object_string_addf(
|
|
json_interface_sub,
|
|
"localIfUsed", "%pI4", &dest);
|
|
} else
|
|
vty_out(vty, " %s %pI4,", dstr,
|
|
&dest);
|
|
}
|
|
if (use_json) {
|
|
json_object_string_add(json_interface_sub, "area",
|
|
ospf_area_desc_string(oi->area));
|
|
|
|
if (OSPF_IF_PARAM(oi, mtu_ignore))
|
|
json_object_boolean_true_add(
|
|
json_interface_sub,
|
|
"mtuMismatchDetect");
|
|
|
|
json_object_string_addf(json_interface_sub, "routerId",
|
|
"%pI4", &ospf->router_id);
|
|
json_object_string_add(json_interface_sub,
|
|
"networkType",
|
|
ospf_network_type_str[oi->type]);
|
|
json_object_int_add(json_interface_sub, "cost",
|
|
oi->output_cost);
|
|
json_object_int_add(json_interface_sub,
|
|
"transmitDelaySecs",
|
|
OSPF_IF_PARAM(oi, transmit_delay));
|
|
json_object_string_add(json_interface_sub, "state",
|
|
lookup_msg(ospf_ism_state_msg,
|
|
oi->state, NULL));
|
|
json_object_int_add(json_interface_sub, "priority",
|
|
PRIORITY(oi));
|
|
json_object_boolean_add(
|
|
json_interface_sub, "opaqueCapable",
|
|
OSPF_IF_PARAM(oi, opaque_capable));
|
|
} else {
|
|
vty_out(vty, " Area %s\n",
|
|
ospf_area_desc_string(oi->area));
|
|
|
|
vty_out(vty, " MTU mismatch detection: %s\n",
|
|
OSPF_IF_PARAM(oi, mtu_ignore) ? "disabled"
|
|
: "enabled");
|
|
|
|
vty_out(vty,
|
|
" Router ID %pI4, Network Type %s, Cost: %d\n",
|
|
&ospf->router_id,
|
|
ospf_network_type_str[oi->type],
|
|
oi->output_cost);
|
|
|
|
vty_out(vty,
|
|
" Transmit Delay is %d sec, State %s, Priority %d\n",
|
|
OSPF_IF_PARAM(oi, transmit_delay),
|
|
lookup_msg(ospf_ism_state_msg, oi->state, NULL),
|
|
PRIORITY(oi));
|
|
if (!OSPF_IF_PARAM(oi, opaque_capable))
|
|
vty_out(vty,
|
|
" Opaque LSA capability disabled on interface\n");
|
|
}
|
|
|
|
/* Show DR information. */
|
|
if (DR(oi).s_addr == INADDR_ANY) {
|
|
if (!use_json)
|
|
vty_out(vty,
|
|
" No backup designated router on this network\n");
|
|
} else {
|
|
nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi));
|
|
if (nbr) {
|
|
if (use_json) {
|
|
json_object_string_addf(
|
|
json_interface_sub, "drId",
|
|
"%pI4", &nbr->router_id);
|
|
json_object_string_addf(
|
|
json_interface_sub, "drAddress",
|
|
"%pI4",
|
|
&nbr->address.u.prefix4);
|
|
} else {
|
|
vty_out(vty,
|
|
" Designated Router (ID) %pI4",
|
|
&nbr->router_id);
|
|
vty_out(vty,
|
|
" Interface Address %pFX\n",
|
|
&nbr->address);
|
|
}
|
|
}
|
|
nbr = NULL;
|
|
|
|
nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &BDR(oi));
|
|
if (nbr == NULL) {
|
|
if (!use_json)
|
|
vty_out(vty,
|
|
" No backup designated router on this network\n");
|
|
} else {
|
|
if (use_json) {
|
|
json_object_string_addf(
|
|
json_interface_sub, "bdrId",
|
|
"%pI4", &nbr->router_id);
|
|
json_object_string_addf(
|
|
json_interface_sub,
|
|
"bdrAddress", "%pI4",
|
|
&nbr->address.u.prefix4);
|
|
} else {
|
|
vty_out(vty,
|
|
" Backup Designated Router (ID) %pI4,",
|
|
&nbr->router_id);
|
|
vty_out(vty, " Interface Address %pI4\n",
|
|
&nbr->address.u.prefix4);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Next network-LSA sequence number we'll use, if we're elected
|
|
* DR */
|
|
if (oi->params
|
|
&& ntohl(oi->params->network_lsa_seqnum)
|
|
!= OSPF_INITIAL_SEQUENCE_NUMBER) {
|
|
if (use_json)
|
|
json_object_int_add(
|
|
json_interface_sub,
|
|
"networkLsaSequence",
|
|
ntohl(oi->params->network_lsa_seqnum));
|
|
else
|
|
vty_out(vty,
|
|
" Saved Network-LSA sequence number 0x%x\n",
|
|
ntohl(oi->params->network_lsa_seqnum));
|
|
}
|
|
|
|
if (use_json) {
|
|
if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
|
|
|| OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
|
|
if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
|
|
json_object_boolean_true_add(
|
|
json_interface_sub,
|
|
"mcastMemberOspfAllRouters");
|
|
if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
|
|
json_object_boolean_true_add(
|
|
json_interface_sub,
|
|
"mcastMemberOspfDesignatedRouters");
|
|
}
|
|
} else {
|
|
vty_out(vty, " Multicast group memberships:");
|
|
if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
|
|
|| OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
|
|
if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
|
|
vty_out(vty, " OSPFAllRouters");
|
|
if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
|
|
vty_out(vty, " OSPFDesignatedRouters");
|
|
} else
|
|
vty_out(vty, " <None>");
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
if (use_json) {
|
|
if (OSPF_IF_PARAM(oi, fast_hello) == 0)
|
|
json_object_int_add(
|
|
json_interface_sub, "timerMsecs",
|
|
OSPF_IF_PARAM(oi, v_hello) * 1000);
|
|
else
|
|
json_object_int_add(
|
|
json_interface_sub, "timerMsecs",
|
|
1000 / OSPF_IF_PARAM(oi, fast_hello));
|
|
json_object_int_add(json_interface_sub, "timerDeadSecs",
|
|
OSPF_IF_PARAM(oi, v_wait));
|
|
json_object_int_add(json_interface_sub, "timerWaitSecs",
|
|
OSPF_IF_PARAM(oi, v_wait));
|
|
json_object_int_add(
|
|
json_interface_sub, "timerRetransmitSecs",
|
|
OSPF_IF_PARAM(oi, retransmit_interval));
|
|
json_object_int_add(json_interface_sub,
|
|
"timerRetransmitWindowMsecs",
|
|
OSPF_IF_PARAM(oi,
|
|
retransmit_window));
|
|
} else {
|
|
vty_out(vty, " Timer intervals configured,");
|
|
vty_out(vty, " Hello ");
|
|
if (OSPF_IF_PARAM(oi, fast_hello) == 0)
|
|
vty_out(vty, "%ds,",
|
|
OSPF_IF_PARAM(oi, v_hello));
|
|
else
|
|
vty_out(vty, "%dms,",
|
|
1000 / OSPF_IF_PARAM(oi, fast_hello));
|
|
vty_out(vty, " Dead %ds, Wait %ds, Retransmit %d\n",
|
|
OSPF_IF_PARAM(oi, v_wait),
|
|
OSPF_IF_PARAM(oi, v_wait),
|
|
OSPF_IF_PARAM(oi, retransmit_interval));
|
|
}
|
|
|
|
if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE) {
|
|
char timebuf[OSPF_TIME_DUMP_SIZE];
|
|
if (use_json) {
|
|
long time_store = 0;
|
|
if (oi->t_hello)
|
|
time_store =
|
|
monotime_until(
|
|
&oi->t_hello->u.sands,
|
|
NULL)
|
|
/ 1000LL;
|
|
json_object_int_add(json_interface_sub,
|
|
"timerHelloInMsecs",
|
|
time_store);
|
|
} else
|
|
vty_out(vty, " Hello due in %s\n",
|
|
ospf_timer_dump(oi->t_hello, timebuf,
|
|
sizeof(timebuf)));
|
|
} else /* passive-interface is set */
|
|
{
|
|
if (use_json)
|
|
json_object_boolean_true_add(
|
|
json_interface_sub,
|
|
"timerPassiveIface");
|
|
else
|
|
vty_out(vty,
|
|
" No Hellos (Passive interface)\n");
|
|
}
|
|
|
|
if (use_json) {
|
|
json_object_int_add(json_interface_sub, "nbrCount",
|
|
ospf_nbr_count(oi, 0));
|
|
json_object_int_add(json_interface_sub,
|
|
"nbrAdjacentCount",
|
|
ospf_nbr_count(oi, NSM_Full));
|
|
} else
|
|
vty_out(vty,
|
|
" Neighbor Count is %d, Adjacent neighbor count is %d\n",
|
|
ospf_nbr_count(oi, 0),
|
|
ospf_nbr_count(oi, NSM_Full));
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
if (params &&
|
|
OSPF_IF_PARAM_CONFIGURED(params, v_gr_hello_delay)) {
|
|
if (use_json)
|
|
json_object_int_add(json_interface_sub,
|
|
"grHelloDelaySecs",
|
|
params->v_gr_hello_delay);
|
|
else
|
|
vty_out(vty,
|
|
" Graceful Restart hello delay: %us\n",
|
|
params->v_gr_hello_delay);
|
|
}
|
|
|
|
ospf_interface_bfd_show(vty, ifp, json_interface_sub);
|
|
|
|
if (use_json)
|
|
json_object_boolean_add(json_interface_sub,
|
|
"prefixSuppression",
|
|
OSPF_IF_PARAM(oi,
|
|
prefix_suppression));
|
|
else if (OSPF_IF_PARAM(oi, prefix_suppression))
|
|
vty_out(vty,
|
|
" Suppress advertisement of interface IP prefix\n");
|
|
|
|
/* OSPF Authentication information */
|
|
ospf_interface_auth_show(vty, oi, json_interface_sub, use_json);
|
|
|
|
/* Point-to-Multipoint Interface options. */
|
|
if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
|
|
if (use_json)
|
|
json_object_boolean_add(json_interface_sub,
|
|
"p2mpDelayReflood",
|
|
oi->p2mp_delay_reflood);
|
|
else
|
|
vty_out(vty,
|
|
" %sDelay reflooding LSAs received on P2MP interface\n",
|
|
oi->p2mp_delay_reflood ? "" : "Don't ");
|
|
if (use_json)
|
|
json_object_boolean_add(json_interface_sub,
|
|
"p2mpNonBroadcast",
|
|
oi->p2mp_non_broadcast);
|
|
else
|
|
vty_out(vty,
|
|
" P2MP interface does %ssupport broadcast\n",
|
|
oi->p2mp_non_broadcast ? "not " : "");
|
|
}
|
|
|
|
if (oi->nbr_filter) {
|
|
if (use_json)
|
|
json_object_string_add(json_interface_sub,
|
|
"nbrFilterPrefixList",
|
|
prefix_list_name(
|
|
oi->nbr_filter));
|
|
else
|
|
vty_out(vty,
|
|
" Neighbor filter prefix-list: %s\n",
|
|
prefix_list_name(oi->nbr_filter));
|
|
} else {
|
|
if (use_json)
|
|
json_object_string_add(json_interface_sub,
|
|
"nbrFilterPrefixList",
|
|
"N/A");
|
|
}
|
|
|
|
/* Non-Traffic interface counters
|
|
*/
|
|
if (use_json)
|
|
json_object_int_add(json_interface_sub,
|
|
"lsaRetransmissions",
|
|
oi->ls_rxmt_lsa);
|
|
else
|
|
vty_out(vty, " LSA retransmissions: %u\n",
|
|
oi->ls_rxmt_lsa);
|
|
}
|
|
}
|
|
|
|
static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
|
|
char *intf_name, uint8_t use_vrf,
|
|
json_object *json, bool use_json)
|
|
{
|
|
struct interface *ifp;
|
|
struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_interface_sub = NULL, *json_interface = NULL;
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
json_interface = json_object_new_object();
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
if (intf_name == NULL) {
|
|
/* Show All Interfaces.*/
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
|
if (ospf_oi_count(ifp)) {
|
|
if (use_json) {
|
|
json_interface_sub =
|
|
json_object_new_object();
|
|
}
|
|
show_ip_ospf_interface_sub(vty, ospf, ifp,
|
|
json_interface_sub,
|
|
use_json);
|
|
|
|
if (use_json) {
|
|
json_object_object_add(
|
|
json_interface, ifp->name,
|
|
json_interface_sub);
|
|
}
|
|
}
|
|
}
|
|
if (use_json)
|
|
json_object_object_add(json_vrf, "interfaces",
|
|
json_interface);
|
|
} else {
|
|
/* Interface name is specified. */
|
|
ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
|
|
if (ifp == NULL) {
|
|
if (use_json) {
|
|
json_object_boolean_true_add(json_vrf,
|
|
"noSuchIface");
|
|
json_object_free(json_interface);
|
|
} else
|
|
vty_out(vty, "No such interface name\n");
|
|
} else {
|
|
if (use_json)
|
|
json_interface_sub = json_object_new_object();
|
|
|
|
show_ip_ospf_interface_sub(
|
|
vty, ospf, ifp, json_interface_sub, use_json);
|
|
|
|
if (use_json) {
|
|
json_object_object_add(json_interface,
|
|
ifp->name,
|
|
json_interface_sub);
|
|
json_object_object_add(json_vrf, "interfaces",
|
|
json_interface);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
if (use_vrf) {
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
}
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
|
|
struct ospf_interface *oi,
|
|
json_object *json_interface_sub,
|
|
bool use_json)
|
|
{
|
|
if (use_json) {
|
|
json_object_int_add(json_interface_sub, "ifIndex",
|
|
oi->ifp->ifindex);
|
|
json_object_int_add(json_interface_sub, "helloIn",
|
|
oi->hello_in);
|
|
json_object_int_add(json_interface_sub, "helloOut",
|
|
oi->hello_out);
|
|
json_object_int_add(json_interface_sub, "dbDescIn",
|
|
oi->db_desc_in);
|
|
json_object_int_add(json_interface_sub, "dbDescOut",
|
|
oi->db_desc_out);
|
|
json_object_int_add(json_interface_sub, "lsReqIn",
|
|
oi->ls_req_in);
|
|
json_object_int_add(json_interface_sub, "lsReqOut",
|
|
oi->ls_req_out);
|
|
json_object_int_add(json_interface_sub, "lsUpdIn",
|
|
oi->ls_upd_in);
|
|
json_object_int_add(json_interface_sub, "lsUpdOut",
|
|
oi->ls_upd_out);
|
|
json_object_int_add(json_interface_sub, "lsAckIn",
|
|
oi->ls_ack_in);
|
|
json_object_int_add(json_interface_sub, "lsAckOut",
|
|
oi->ls_ack_out);
|
|
json_object_int_add(json_interface_sub, "packetsQueued",
|
|
listcount(oi->obuf));
|
|
} else {
|
|
vty_out(vty,
|
|
"%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %12lu\n",
|
|
oi->ifp->name, oi->hello_in, oi->hello_out,
|
|
oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
|
|
oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
|
|
oi->ls_ack_in, oi->ls_ack_out, listcount(oi->obuf));
|
|
}
|
|
}
|
|
|
|
/* OSPFv2 Packet Counters */
|
|
static int show_ip_ospf_interface_traffic_common(
|
|
struct vty *vty, struct ospf *ospf, char *intf_name, json_object *json,
|
|
int display_once, uint8_t use_vrf, bool use_json)
|
|
{
|
|
struct vrf *vrf = NULL;
|
|
struct interface *ifp = NULL;
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_interface_sub = NULL;
|
|
|
|
if (!use_json && !display_once) {
|
|
vty_out(vty, "\n");
|
|
vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
|
|
"Interface", " HELLO", " DB-Desc", " LS-Req",
|
|
" LS-Update", " LS-Ack", " Packets");
|
|
vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s%-17s\n", "",
|
|
" Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
|
|
" Rx/Tx", " Queued");
|
|
vty_out(vty,
|
|
"-------------------------------------------------------------------------------------------------------------\n");
|
|
} else if (use_json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
if (intf_name == NULL) {
|
|
vrf = vrf_lookup_by_id(ospf->vrf_id);
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
|
struct route_node *rn;
|
|
struct ospf_interface *oi;
|
|
|
|
if (ospf_oi_count(ifp) == 0)
|
|
continue;
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn;
|
|
rn = route_next(rn)) {
|
|
oi = rn->info;
|
|
|
|
if (oi == NULL)
|
|
continue;
|
|
|
|
if (use_json) {
|
|
json_interface_sub =
|
|
json_object_new_object();
|
|
}
|
|
|
|
show_ip_ospf_interface_traffic_sub(
|
|
vty, oi, json_interface_sub, use_json);
|
|
if (use_json) {
|
|
json_object_object_add(
|
|
json_vrf, ifp->name,
|
|
json_interface_sub);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
/* Interface name is specified. */
|
|
ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
|
|
if (ifp != NULL) {
|
|
struct route_node *rn;
|
|
struct ospf_interface *oi;
|
|
|
|
if (ospf_oi_count(ifp) == 0) {
|
|
vty_out(vty,
|
|
" OSPF not enabled on this interface %s\n",
|
|
ifp->name);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn;
|
|
rn = route_next(rn)) {
|
|
oi = rn->info;
|
|
|
|
if (oi == NULL)
|
|
continue;
|
|
|
|
if (use_json) {
|
|
json_interface_sub =
|
|
json_object_new_object();
|
|
}
|
|
|
|
show_ip_ospf_interface_traffic_sub(
|
|
vty, oi, json_interface_sub, use_json);
|
|
if (use_json) {
|
|
json_object_object_add(
|
|
json_vrf, ifp->name,
|
|
json_interface_sub);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_interface,
|
|
show_ip_ospf_interface_cmd,
|
|
"show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Interface information\n"
|
|
"Interface name\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
bool uj = use_json(argc, argv);
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL, *intf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0, idx_intf = 0;
|
|
uint8_t use_vrf = 0;
|
|
json_object *json = NULL;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (argv_find(argv, argc, "INTERFACE", &idx_intf))
|
|
intf_name = argv[idx_intf]->arg;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = show_ip_ospf_interface_common(
|
|
vty, ospf, intf_name, use_vrf, json,
|
|
uj);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else if (!ospf)
|
|
vty_out(vty, "%% OSPF is not enabled\n");
|
|
|
|
return ret;
|
|
}
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
ret = show_ip_ospf_interface_common(vty, ospf, intf_name,
|
|
use_vrf, json, uj);
|
|
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf default\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
ret = show_ip_ospf_interface_common(vty, ospf, intf_name,
|
|
use_vrf, json, uj);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_interface,
|
|
show_ip_ospf_instance_interface_cmd,
|
|
"show ip ospf (1-65535) interface [INTERFACE] [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Interface information\n"
|
|
"Interface name\n"
|
|
JSON_STR)
|
|
{
|
|
int idx_number = 3;
|
|
int idx_intf = 0;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool uj = use_json(argc, argv);
|
|
char *intf_name = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
json_object *json = NULL;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
if (argv_find(argv, argc, "INTERFACE", &idx_intf))
|
|
intf_name = argv[idx_intf]->arg;
|
|
|
|
ret = show_ip_ospf_interface_common(vty, ospf, intf_name, 0, json, uj);
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_interface_traffic,
|
|
show_ip_ospf_interface_traffic_cmd,
|
|
"show ip ospf [vrf <NAME|all>] interface traffic [INTERFACE] [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Interface information\n"
|
|
"Protocol Packet counters\n"
|
|
"Interface name\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf = NULL;
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL, *intf_name = NULL;
|
|
bool all_vrf = false;
|
|
int inst = 0;
|
|
int idx_vrf = 0, idx_intf = 0;
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
int display_once = 0;
|
|
uint8_t use_vrf = 0;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (argv_find(argv, argc, "INTERFACE", &idx_intf))
|
|
intf_name = argv[idx_intf]->arg;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
|
|
ret = show_ip_ospf_interface_traffic_common(
|
|
vty, ospf, intf_name, json,
|
|
display_once, use_vrf, uj);
|
|
display_once = 1;
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
json_object_free(json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ret = show_ip_ospf_interface_traffic_common(
|
|
vty, ospf, intf_name, json, display_once, use_vrf, uj);
|
|
} else {
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
json_object_free(json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ret = show_ip_ospf_interface_traffic_common(
|
|
vty, ospf, intf_name, json, display_once, use_vrf, uj);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static void show_ip_ospf_neighbour_header(struct vty *vty)
|
|
{
|
|
vty_out(vty, "\n%-15s %-3s %-15s %-15s %-9s %-15s %-32s %5s %5s %5s\n",
|
|
"Neighbor ID", "Pri", "State", "Up Time", "Dead Time",
|
|
"Address", "Interface", "RXmtL", "RqstL", "DBsmL");
|
|
}
|
|
|
|
static void show_ip_ospf_neighbour_brief(struct vty *vty,
|
|
struct ospf_neighbor *nbr,
|
|
struct ospf_neighbor *prev_nbr,
|
|
json_object *json, bool use_json)
|
|
{
|
|
char msgbuf[16];
|
|
char timebuf[OSPF_TIME_DUMP_SIZE];
|
|
json_object *json_neighbor = NULL, *json_neigh_array = NULL;
|
|
struct timeval res = {.tv_sec = 0, .tv_usec = 0};
|
|
long time_val = 0;
|
|
char uptime[OSPF_TIME_DUMP_SIZE];
|
|
|
|
if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec)
|
|
time_val =
|
|
monotime_since(&nbr->ts_last_progress, &res) / 1000LL;
|
|
|
|
if (use_json) {
|
|
char neigh_str[INET_ADDRSTRLEN];
|
|
|
|
if (prev_nbr && !IPV4_ADDR_SAME(&prev_nbr->src, &nbr->src)) {
|
|
/* Start new neigh list */
|
|
json_neigh_array = NULL;
|
|
}
|
|
|
|
if (nbr->state == NSM_Attempt &&
|
|
nbr->router_id.s_addr == INADDR_ANY)
|
|
strlcpy(neigh_str, "neighbor", sizeof(neigh_str));
|
|
else
|
|
inet_ntop(AF_INET, &nbr->router_id, neigh_str,
|
|
sizeof(neigh_str));
|
|
|
|
json_object_object_get_ex(json, neigh_str, &json_neigh_array);
|
|
|
|
if (!json_neigh_array) {
|
|
json_neigh_array = json_object_new_array();
|
|
json_object_object_add(json, neigh_str,
|
|
json_neigh_array);
|
|
}
|
|
|
|
json_neighbor = json_object_new_object();
|
|
|
|
ospf_nbr_ism_state_message(nbr, msgbuf, sizeof(msgbuf));
|
|
json_object_string_add(json_neighbor, "nbrState", msgbuf);
|
|
|
|
json_object_int_add(json_neighbor, "nbrPriority",
|
|
nbr->priority);
|
|
|
|
json_object_string_add(
|
|
json_neighbor, "converged",
|
|
lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
|
|
json_object_string_add(json_neighbor, "role",
|
|
lookup_msg(ospf_ism_state_msg,
|
|
ospf_nbr_ism_state(nbr),
|
|
NULL));
|
|
if (nbr->t_inactivity) {
|
|
long time_store;
|
|
|
|
time_store = monotime_until(&nbr->t_inactivity->u.sands,
|
|
NULL) /
|
|
1000LL;
|
|
json_object_int_add(json_neighbor, "upTimeInMsec",
|
|
time_val);
|
|
json_object_int_add(json_neighbor,
|
|
"routerDeadIntervalTimerDueMsec",
|
|
time_store);
|
|
json_object_string_add(
|
|
json_neighbor, "upTime",
|
|
ospf_timeval_dump(&res, uptime,
|
|
sizeof(uptime)));
|
|
json_object_string_add(
|
|
json_neighbor, "deadTime",
|
|
ospf_timer_dump(nbr->t_inactivity, timebuf,
|
|
sizeof(timebuf)));
|
|
} else {
|
|
json_object_string_add(json_neighbor, "deadTimeMsecs",
|
|
"inactive");
|
|
json_object_string_add(json_neighbor,
|
|
"routerDeadIntervalTimerDueMsec",
|
|
"inactive");
|
|
}
|
|
json_object_string_addf(json_neighbor, "ifaceAddress", "%pI4",
|
|
&nbr->src);
|
|
json_object_string_add(json_neighbor, "ifaceName",
|
|
IF_NAME(nbr->oi));
|
|
json_object_int_add(json_neighbor,
|
|
"linkStateRetransmissionListCounter",
|
|
ospf_ls_retransmit_count(nbr));
|
|
json_object_int_add(json_neighbor,
|
|
"linkStateRequestListCounter",
|
|
ospf_ls_request_count(nbr));
|
|
json_object_int_add(json_neighbor, "databaseSummaryListCounter",
|
|
ospf_db_summary_count(nbr));
|
|
|
|
json_object_array_add(json_neigh_array, json_neighbor);
|
|
} else {
|
|
ospf_nbr_ism_state_message(nbr, msgbuf, sizeof(msgbuf));
|
|
|
|
if (nbr->state == NSM_Attempt &&
|
|
nbr->router_id.s_addr == INADDR_ANY)
|
|
vty_out(vty, "%-15s %3d %-15s ", "-", nbr->priority,
|
|
msgbuf);
|
|
else
|
|
vty_out(vty, "%-15pI4 %3d %-15s ", &nbr->router_id,
|
|
nbr->priority, msgbuf);
|
|
|
|
vty_out(vty, "%-15s ",
|
|
ospf_timeval_dump(&res, uptime, sizeof(uptime)));
|
|
|
|
vty_out(vty, "%9s ",
|
|
ospf_timer_dump(nbr->t_inactivity, timebuf,
|
|
sizeof(timebuf)));
|
|
vty_out(vty, "%-15pI4 ", &nbr->src);
|
|
vty_out(vty, "%-32s %5ld %5ld %5d\n", IF_NAME(nbr->oi),
|
|
ospf_ls_retransmit_count(nbr),
|
|
ospf_ls_request_count(nbr), ospf_db_summary_count(nbr));
|
|
}
|
|
}
|
|
|
|
static void show_ip_ospf_neighbor_sub(struct vty *vty,
|
|
struct ospf_interface *oi,
|
|
json_object *json, bool use_json)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_neighbor *nbr, *prev_nbr = NULL;
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
|
|
nbr = rn->info;
|
|
|
|
if (!nbr)
|
|
continue;
|
|
|
|
/* Do not show myself. */
|
|
if (nbr == oi->nbr_self)
|
|
continue;
|
|
/* Down state is not shown. */
|
|
if (nbr->state == NSM_Down)
|
|
continue;
|
|
|
|
prev_nbr = nbr;
|
|
|
|
show_ip_ospf_neighbour_brief(vty, nbr, prev_nbr, json,
|
|
use_json);
|
|
}
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_common(struct vty *vty, struct ospf *ospf,
|
|
json_object *json, bool use_json,
|
|
uint8_t use_vrf)
|
|
{
|
|
struct ospf_interface *oi;
|
|
struct listnode *node;
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_nbr_sub = NULL;
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
json_nbr_sub = json_object_new_object();
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
if (!use_json)
|
|
show_ip_ospf_neighbour_header(vty);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
|
if (ospf_interface_neighbor_count(oi) == 0)
|
|
continue;
|
|
show_ip_ospf_neighbor_sub(vty, oi, json_nbr_sub, use_json);
|
|
}
|
|
|
|
if (use_json) {
|
|
json_object_object_add(json_vrf, "neighbors", json_nbr_sub);
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_neighbor,
|
|
show_ip_ospf_neighbor_cmd,
|
|
"show ip ospf [vrf <NAME|all>] neighbor [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Neighbor list\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
bool uj = use_json(argc, argv);
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0;
|
|
uint8_t use_vrf = 0;
|
|
json_object *json = NULL;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = show_ip_ospf_neighbor_common(
|
|
vty, ospf, json, uj, use_vrf);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else if (!ospf)
|
|
vty_out(vty, "OSPF is not enabled\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf default\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf) {
|
|
ret = show_ip_ospf_neighbor_common(vty, ospf, json, uj,
|
|
use_vrf);
|
|
|
|
if (uj) {
|
|
vty_out(vty, "%s\n",
|
|
json_object_to_json_string_ext(
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
}
|
|
}
|
|
|
|
if (uj)
|
|
json_object_free(json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
DEFUN (show_ip_ospf_instance_neighbor,
|
|
show_ip_ospf_instance_neighbor_cmd,
|
|
"show ip ospf (1-65535) neighbor [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
JSON_STR)
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
ret = show_ip_ospf_neighbor_common(vty, ospf, json, uj, 0);
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
|
|
json_object *json, bool use_json,
|
|
uint8_t use_vrf)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_interface *oi;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_neighbor_sub = NULL;
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
if (!use_json)
|
|
show_ip_ospf_neighbour_header(vty);
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json_vrf, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
|
struct listnode *nbr_node;
|
|
struct ospf_nbr_nbma *nbr_nbma;
|
|
|
|
show_ip_ospf_neighbor_sub(vty, oi, json_vrf, use_json);
|
|
|
|
/* print Down neighbor status */
|
|
for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nbr_node, nbr_nbma)) {
|
|
if (nbr_nbma->nbr == NULL
|
|
|| nbr_nbma->nbr->state == NSM_Down) {
|
|
if (use_json) {
|
|
json_neighbor_sub =
|
|
json_object_new_object();
|
|
json_object_int_add(json_neighbor_sub,
|
|
"nbrNbmaPriority",
|
|
nbr_nbma->priority);
|
|
json_object_boolean_true_add(
|
|
json_neighbor_sub,
|
|
"nbrNbmaDown");
|
|
json_object_string_add(
|
|
json_neighbor_sub,
|
|
"nbrNbmaIfaceName",
|
|
IF_NAME(oi));
|
|
json_object_int_add(
|
|
json_neighbor_sub,
|
|
"nbrNbmaRetransmitCounter", 0);
|
|
json_object_int_add(
|
|
json_neighbor_sub,
|
|
"nbrNbmaRequestCounter", 0);
|
|
json_object_int_add(
|
|
json_neighbor_sub,
|
|
"nbrNbmaDbSummaryCounter", 0);
|
|
json_object_object_add(
|
|
json_vrf,
|
|
inet_ntop(AF_INET,
|
|
&nbr_nbma->addr, buf,
|
|
sizeof(buf)),
|
|
json_neighbor_sub);
|
|
} else {
|
|
vty_out(vty, "%-15s %3d %-15s %9s ",
|
|
"-", nbr_nbma->priority, "Down",
|
|
"-");
|
|
vty_out(vty,
|
|
"%-32pI4 %-20s %5d %5d %5d\n",
|
|
&nbr_nbma->addr,
|
|
IF_NAME(oi), 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_neighbor_all,
|
|
show_ip_ospf_neighbor_all_cmd,
|
|
"show ip ospf [vrf <NAME|all>] neighbor all [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Neighbor list\n"
|
|
"include down status neighbor\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
bool uj = use_json(argc, argv);
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0;
|
|
uint8_t use_vrf = 0;
|
|
json_object *json = NULL;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = show_ip_ospf_neighbor_all_common(
|
|
vty, ospf, json, uj, use_vrf);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
json_object_free(json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
json_object_free(json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf) {
|
|
ret = show_ip_ospf_neighbor_all_common(vty, ospf, json, uj,
|
|
use_vrf);
|
|
if (uj) {
|
|
vty_out(vty, "%s\n",
|
|
json_object_to_json_string_ext(
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
}
|
|
}
|
|
|
|
if (uj)
|
|
json_object_free(json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_neighbor_all,
|
|
show_ip_ospf_instance_neighbor_all_cmd,
|
|
"show ip ospf (1-65535) neighbor all [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
"include down status neighbor\n"
|
|
JSON_STR)
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
ret = show_ip_ospf_neighbor_all_common(vty, ospf, json, uj, 0);
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
|
|
const char *ifname, bool use_json,
|
|
uint8_t use_vrf)
|
|
{
|
|
struct interface *ifp;
|
|
struct route_node *rn;
|
|
json_object *json = NULL;
|
|
|
|
if (use_json)
|
|
json = json_object_new_object();
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json, use_vrf);
|
|
|
|
ifp = if_lookup_by_name(ifname, ospf->vrf_id);
|
|
if (!ifp) {
|
|
if (use_json)
|
|
json_object_boolean_true_add(json, "noSuchIface");
|
|
else
|
|
vty_out(vty, "No such interface.\n");
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (oi == NULL)
|
|
continue;
|
|
|
|
show_ip_ospf_neighbor_sub(vty, oi, json, use_json);
|
|
}
|
|
|
|
if (use_json)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_instance_neighbor_int,
|
|
show_ip_ospf_instance_neighbor_int_cmd,
|
|
"show ip ospf (1-65535)$instance neighbor IFNAME$ifname [json$json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
"Interface name\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
|
|
if (!json)
|
|
show_ip_ospf_neighbour_header(vty);
|
|
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
if (!json)
|
|
show_ip_ospf_neighbour_header(vty);
|
|
|
|
return show_ip_ospf_neighbor_int_common(vty, ospf, ifname, !!json, 0);
|
|
}
|
|
|
|
static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
|
|
struct ospf_interface *oi,
|
|
struct ospf_nbr_nbma *nbr_nbma,
|
|
bool use_json, json_object *json)
|
|
{
|
|
char timebuf[OSPF_TIME_DUMP_SIZE];
|
|
json_object *json_sub = NULL;
|
|
|
|
if (use_json)
|
|
json_sub = json_object_new_object();
|
|
else /* Show neighbor ID. */
|
|
vty_out(vty, " Neighbor %s,", "-");
|
|
|
|
/* Show interface address. */
|
|
if (use_json)
|
|
json_object_string_addf(json_sub, "ifaceAddress", "%pI4",
|
|
&nbr_nbma->addr);
|
|
else
|
|
vty_out(vty, " interface address %pI4\n",
|
|
&nbr_nbma->addr);
|
|
|
|
/* Show Area ID. */
|
|
if (use_json) {
|
|
json_object_string_add(json_sub, "areaId",
|
|
ospf_area_desc_string(oi->area));
|
|
json_object_string_add(json_sub, "iface", IF_NAME(oi));
|
|
} else
|
|
vty_out(vty, " In the area %s via interface %s\n",
|
|
ospf_area_desc_string(oi->area), IF_NAME(oi));
|
|
|
|
/* Show neighbor priority and state. */
|
|
if (use_json) {
|
|
json_object_int_add(json_sub, "nbrPriority",
|
|
nbr_nbma->priority);
|
|
json_object_string_add(json_sub, "nbrState", "down");
|
|
} else
|
|
vty_out(vty, " Neighbor priority is %d, State is %s,",
|
|
nbr_nbma->priority, "Down");
|
|
|
|
/* Show state changes. */
|
|
if (use_json)
|
|
json_object_int_add(json_sub, "stateChangeCounter",
|
|
nbr_nbma->state_change);
|
|
else
|
|
vty_out(vty, " %d state changes\n", nbr_nbma->state_change);
|
|
|
|
/* Show PollInterval */
|
|
if (use_json)
|
|
json_object_int_add(json_sub, "pollInterval", nbr_nbma->v_poll);
|
|
else
|
|
vty_out(vty, " Poll interval %d\n", nbr_nbma->v_poll);
|
|
|
|
/* Show poll-interval timer. */
|
|
if (nbr_nbma->t_poll) {
|
|
if (use_json) {
|
|
long time_store;
|
|
time_store = monotime_until(&nbr_nbma->t_poll->u.sands,
|
|
NULL) / 1000LL;
|
|
json_object_int_add(json_sub,
|
|
"pollIntervalTimerDueMsec",
|
|
time_store);
|
|
} else
|
|
vty_out(vty, " Poll timer due in %s\n",
|
|
ospf_timer_dump(nbr_nbma->t_poll, timebuf,
|
|
sizeof(timebuf)));
|
|
}
|
|
|
|
/* Show poll-interval timer thread. */
|
|
if (use_json) {
|
|
if (nbr_nbma->t_poll != NULL)
|
|
json_object_string_add(json_sub,
|
|
"pollIntervalTimerThread", "on");
|
|
} else
|
|
vty_out(vty, " Thread Poll Timer %s\n",
|
|
nbr_nbma->t_poll != NULL ? "on" : "off");
|
|
|
|
if (use_json)
|
|
json_object_object_add(json, "noNbrId", json_sub);
|
|
}
|
|
|
|
static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
|
|
struct ospf_interface *oi,
|
|
struct ospf_neighbor *nbr,
|
|
struct ospf_neighbor *prev_nbr,
|
|
json_object *json, bool use_json)
|
|
{
|
|
char timebuf[OSPF_TIME_DUMP_SIZE];
|
|
json_object *json_neigh = NULL, *json_neigh_array = NULL;
|
|
char neigh_str[INET_ADDRSTRLEN] = {0};
|
|
char neigh_state[16] = {0};
|
|
struct ospf_neighbor *nbr_dr, *nbr_bdr;
|
|
|
|
if (use_json) {
|
|
if (prev_nbr &&
|
|
!IPV4_ADDR_SAME(&prev_nbr->src, &nbr->src)) {
|
|
json_neigh_array = NULL;
|
|
}
|
|
|
|
if (nbr->state == NSM_Attempt
|
|
&& nbr->router_id.s_addr == INADDR_ANY)
|
|
strlcpy(neigh_str, "noNbrId", sizeof(neigh_str));
|
|
else
|
|
inet_ntop(AF_INET, &nbr->router_id,
|
|
neigh_str, sizeof(neigh_str));
|
|
|
|
json_object_object_get_ex(json, neigh_str, &json_neigh_array);
|
|
|
|
if (!json_neigh_array) {
|
|
json_neigh_array = json_object_new_array();
|
|
json_object_object_add(json, neigh_str,
|
|
json_neigh_array);
|
|
}
|
|
|
|
json_neigh = json_object_new_object();
|
|
|
|
} else {
|
|
/* Show neighbor ID. */
|
|
if (nbr->state == NSM_Attempt
|
|
&& nbr->router_id.s_addr == INADDR_ANY)
|
|
vty_out(vty, " Neighbor %s,", "-");
|
|
else
|
|
vty_out(vty, " Neighbor %pI4,",
|
|
&nbr->router_id);
|
|
}
|
|
|
|
/* Show interface address. */
|
|
if (use_json)
|
|
json_object_string_addf(json_neigh, "ifaceAddress", "%pI4",
|
|
&nbr->address.u.prefix4);
|
|
else
|
|
vty_out(vty, " interface address %pI4\n",
|
|
&nbr->address.u.prefix4);
|
|
|
|
/* Show Area ID. */
|
|
if (use_json) {
|
|
json_object_string_add(json_neigh, "areaId",
|
|
ospf_area_desc_string(oi->area));
|
|
json_object_string_add(json_neigh, "ifaceName", oi->ifp->name);
|
|
if (oi->address)
|
|
json_object_string_addf(json_neigh, "localIfaceAddress",
|
|
"%pI4",
|
|
&oi->address->u.prefix4);
|
|
} else {
|
|
vty_out(vty, " In the area %s via interface %s",
|
|
ospf_area_desc_string(oi->area), oi->ifp->name);
|
|
if (oi->address)
|
|
vty_out(vty, " local interface IP %pI4\n",
|
|
&oi->address->u.prefix4);
|
|
else
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Show neighbor priority and state. */
|
|
ospf_nbr_ism_state_message(nbr, neigh_state, sizeof(neigh_state));
|
|
if (use_json) {
|
|
json_object_int_add(json_neigh, "nbrPriority", nbr->priority);
|
|
json_object_string_add(json_neigh, "nbrState", neigh_state);
|
|
json_object_string_add(json_neigh, "role",
|
|
lookup_msg(ospf_ism_state_msg,
|
|
ospf_nbr_ism_state(nbr),
|
|
NULL));
|
|
} else {
|
|
vty_out(vty,
|
|
" Neighbor priority is %d, State is %s, Role is %s,",
|
|
nbr->priority, neigh_state,
|
|
lookup_msg(ospf_ism_state_msg, ospf_nbr_ism_state(nbr),
|
|
NULL));
|
|
}
|
|
|
|
/* Show state changes. */
|
|
if (use_json)
|
|
json_object_int_add(json_neigh, "stateChangeCounter",
|
|
nbr->state_change);
|
|
else
|
|
vty_out(vty, " %d state changes\n", nbr->state_change);
|
|
|
|
/* Show LSA retransmissions. */
|
|
if (use_json)
|
|
json_object_int_add(json_neigh, "lsaRetransmissions",
|
|
nbr->ls_rxmt_lsa);
|
|
else
|
|
vty_out(vty, " %u LSA retransmissions\n", nbr->ls_rxmt_lsa);
|
|
|
|
if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec) {
|
|
struct timeval res;
|
|
long time_store;
|
|
|
|
time_store =
|
|
monotime_since(&nbr->ts_last_progress, &res) / 1000LL;
|
|
if (use_json) {
|
|
json_object_int_add(json_neigh, "lastPrgrsvChangeMsec",
|
|
time_store);
|
|
} else {
|
|
vty_out(vty,
|
|
" Most recent state change statistics:\n");
|
|
vty_out(vty, " Progressive change %s ago\n",
|
|
ospf_timeval_dump(&res, timebuf,
|
|
sizeof(timebuf)));
|
|
}
|
|
}
|
|
|
|
if (nbr->ts_last_regress.tv_sec || nbr->ts_last_regress.tv_usec) {
|
|
struct timeval res;
|
|
long time_store;
|
|
|
|
time_store =
|
|
monotime_since(&nbr->ts_last_regress, &res) / 1000LL;
|
|
if (use_json) {
|
|
json_object_int_add(json_neigh,
|
|
"lastRegressiveChangeMsec",
|
|
time_store);
|
|
if (nbr->last_regress_str)
|
|
json_object_string_add(
|
|
json_neigh,
|
|
"lastRegressiveChangeReason",
|
|
nbr->last_regress_str);
|
|
} else {
|
|
vty_out(vty,
|
|
" Regressive change %s ago, due to %s\n",
|
|
ospf_timeval_dump(&res, timebuf,
|
|
sizeof(timebuf)),
|
|
(nbr->last_regress_str ? nbr->last_regress_str
|
|
: "??"));
|
|
}
|
|
}
|
|
|
|
/* Show Designated Router ID. */
|
|
if (DR(oi).s_addr == INADDR_ANY) {
|
|
if (!use_json)
|
|
vty_out(vty,
|
|
" No designated router on this network\n");
|
|
} else {
|
|
nbr_dr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi));
|
|
if (nbr_dr) {
|
|
if (use_json)
|
|
json_object_string_addf(
|
|
json_neigh, "routerDesignatedId",
|
|
"%pI4", &nbr_dr->router_id);
|
|
else
|
|
vty_out(vty, " DR is %pI4,",
|
|
&nbr_dr->router_id);
|
|
}
|
|
}
|
|
|
|
/* Show Backup Designated Router ID. */
|
|
nbr_bdr = ospf_nbr_lookup_by_addr(oi->nbrs, &BDR(oi));
|
|
if (nbr_bdr == NULL) {
|
|
if (!use_json)
|
|
vty_out(vty,
|
|
" No backup designated router on this network\n");
|
|
} else {
|
|
if (use_json)
|
|
json_object_string_addf(json_neigh,
|
|
"routerDesignatedBackupId",
|
|
"%pI4", &nbr_bdr->router_id);
|
|
else
|
|
vty_out(vty, " BDR is %pI4\n", &nbr_bdr->router_id);
|
|
}
|
|
|
|
/* Show options. */
|
|
if (use_json) {
|
|
json_object_int_add(json_neigh, "optionsCounter", nbr->options);
|
|
json_object_string_add(json_neigh, "optionsList",
|
|
ospf_options_dump(nbr->options));
|
|
} else
|
|
vty_out(vty, " Options %d %s\n", nbr->options,
|
|
ospf_options_dump(nbr->options));
|
|
|
|
/* Show Router Dead interval timer. */
|
|
if (use_json) {
|
|
if (nbr->t_inactivity) {
|
|
long time_store;
|
|
time_store = monotime_until(&nbr->t_inactivity->u.sands,
|
|
NULL)
|
|
/ 1000LL;
|
|
json_object_int_add(json_neigh,
|
|
"routerDeadIntervalTimerDueMsec",
|
|
time_store);
|
|
} else
|
|
json_object_int_add(
|
|
json_neigh,
|
|
"routerDeadIntervalTimerDueMsec", -1);
|
|
} else
|
|
vty_out(vty, " Dead timer due in %s\n",
|
|
ospf_timer_dump(nbr->t_inactivity, timebuf,
|
|
sizeof(timebuf)));
|
|
|
|
/* Show Database Summary list. */
|
|
if (use_json)
|
|
json_object_int_add(json_neigh, "databaseSummaryListCounter",
|
|
ospf_db_summary_count(nbr));
|
|
else
|
|
vty_out(vty, " Database Summary List %d\n",
|
|
ospf_db_summary_count(nbr));
|
|
|
|
/* Show Link State Request list. */
|
|
if (use_json)
|
|
json_object_int_add(json_neigh, "linkStateRequestListCounter",
|
|
ospf_ls_request_count(nbr));
|
|
else
|
|
vty_out(vty, " Link State Request List %ld\n",
|
|
ospf_ls_request_count(nbr));
|
|
|
|
/* Show Link State Retransmission list. */
|
|
if (use_json)
|
|
json_object_int_add(json_neigh,
|
|
"linkStateRetransmissionListCounter",
|
|
ospf_ls_retransmit_count(nbr));
|
|
else
|
|
vty_out(vty, " Link State Retransmission List %ld\n",
|
|
ospf_ls_retransmit_count(nbr));
|
|
|
|
/* Show inactivity timer thread. */
|
|
if (use_json) {
|
|
if (nbr->t_inactivity != NULL)
|
|
json_object_string_add(json_neigh,
|
|
"threadInactivityTimer", "on");
|
|
} else
|
|
vty_out(vty, " Thread Inactivity Timer %s\n",
|
|
nbr->t_inactivity != NULL ? "on" : "off");
|
|
|
|
/* Show Database Description retransmission thread. */
|
|
if (use_json) {
|
|
if (nbr->t_db_desc != NULL)
|
|
json_object_string_add(
|
|
json_neigh,
|
|
"threadDatabaseDescriptionRetransmission",
|
|
"on");
|
|
} else
|
|
vty_out(vty,
|
|
" Thread Database Description Retransmision %s\n",
|
|
nbr->t_db_desc != NULL ? "on" : "off");
|
|
|
|
/* Show Link State Request Retransmission thread. */
|
|
if (use_json) {
|
|
if (nbr->t_ls_req != NULL)
|
|
json_object_string_add(
|
|
json_neigh,
|
|
"threadLinkStateRequestRetransmission", "on");
|
|
} else
|
|
vty_out(vty,
|
|
" Thread Link State Request Retransmission %s\n",
|
|
nbr->t_ls_req != NULL ? "on" : "off");
|
|
|
|
/* Show Link State Update Retransmission thread. */
|
|
if (use_json) {
|
|
if (nbr->t_ls_rxmt != NULL)
|
|
json_object_string_add(
|
|
json_neigh,
|
|
"threadLinkStateUpdateRetransmission",
|
|
"on");
|
|
} else
|
|
vty_out(vty,
|
|
" Thread Link State Update Retransmission %s\n\n",
|
|
nbr->t_ls_rxmt != NULL ? "on" : "off");
|
|
|
|
if (!use_json) {
|
|
vty_out(vty, " Graceful restart Helper info:\n");
|
|
|
|
if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) {
|
|
vty_out(vty,
|
|
" Graceful Restart HELPER Status : Inprogress.\n");
|
|
|
|
vty_out(vty,
|
|
" Graceful Restart grace period time: %d (seconds).\n",
|
|
nbr->gr_helper_info.recvd_grace_period);
|
|
vty_out(vty, " Graceful Restart reason: %s.\n",
|
|
ospf_restart_reason2str(
|
|
nbr->gr_helper_info.gr_restart_reason));
|
|
} else {
|
|
vty_out(vty,
|
|
" Graceful Restart HELPER Status : None\n");
|
|
}
|
|
|
|
if (nbr->gr_helper_info.rejected_reason
|
|
!= OSPF_HELPER_REJECTED_NONE)
|
|
vty_out(vty, " Helper rejected reason: %s.\n",
|
|
ospf_rejected_reason2str(
|
|
nbr->gr_helper_info.rejected_reason));
|
|
|
|
if (nbr->gr_helper_info.helper_exit_reason
|
|
!= OSPF_GR_HELPER_EXIT_NONE)
|
|
vty_out(vty, " Last helper exit reason: %s.\n\n",
|
|
ospf_exit_reason2str(
|
|
nbr->gr_helper_info.helper_exit_reason));
|
|
else
|
|
vty_out(vty, "\n");
|
|
} else {
|
|
json_object_string_add(json_neigh, "grHelperStatus",
|
|
OSPF_GR_IS_ACTIVE_HELPER(nbr) ?
|
|
"Inprogress"
|
|
: "None");
|
|
if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) {
|
|
json_object_int_add(
|
|
json_neigh, "graceInterval",
|
|
nbr->gr_helper_info.recvd_grace_period);
|
|
json_object_string_add(
|
|
json_neigh, "grRestartReason",
|
|
ospf_restart_reason2str(
|
|
nbr->gr_helper_info.gr_restart_reason));
|
|
}
|
|
|
|
if (nbr->gr_helper_info.rejected_reason
|
|
!= OSPF_HELPER_REJECTED_NONE)
|
|
json_object_string_add(
|
|
json_neigh, "helperRejectReason",
|
|
ospf_rejected_reason2str(
|
|
nbr->gr_helper_info.rejected_reason));
|
|
|
|
if (nbr->gr_helper_info.helper_exit_reason
|
|
!= OSPF_GR_HELPER_EXIT_NONE)
|
|
json_object_string_add(
|
|
json_neigh, "helperExitReason",
|
|
ospf_exit_reason2str(
|
|
nbr->gr_helper_info
|
|
.helper_exit_reason));
|
|
}
|
|
|
|
bfd_sess_show(vty, json_neigh, nbr->bfd_session);
|
|
|
|
if (use_json)
|
|
json_object_array_add(json_neigh_array, json_neigh);
|
|
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
|
|
struct in_addr *router_id,
|
|
bool use_json, uint8_t use_vrf,
|
|
bool is_detail,
|
|
json_object *json_vrf)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_neighbor *nbr;
|
|
struct ospf_interface *oi;
|
|
json_object *json = NULL;
|
|
|
|
if (use_json)
|
|
json = json_object_new_object();
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json, use_vrf);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
|
nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, router_id);
|
|
|
|
if (!nbr)
|
|
continue;
|
|
|
|
if (is_detail)
|
|
show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, NULL,
|
|
json, use_json);
|
|
else
|
|
show_ip_ospf_neighbour_brief(vty, nbr, NULL, json,
|
|
use_json);
|
|
}
|
|
|
|
if (json_vrf && use_json) {
|
|
json_object_object_add(
|
|
json_vrf,
|
|
(ospf->vrf_id == VRF_DEFAULT) ? "default" : ospf->name,
|
|
json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
if (use_json)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_neighbor_id,
|
|
show_ip_ospf_neighbor_id_cmd,
|
|
"show ip ospf [vrf NAME$vrf_name] neighbor A.B.C.D$router_id [detail$detail] [json$json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"Neighbor list\n"
|
|
"Neighbor ID\n"
|
|
"Detailed output\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
struct listnode *node;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
|
|
if (vrf_name && !strmatch(vrf_name, "all")) {
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (!json)
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
else
|
|
vty_json_empty(vty, NULL);
|
|
return CMD_SUCCESS;
|
|
}
|
|
ret = show_ip_ospf_neighbor_id_common(
|
|
vty, ospf, &router_id, !!json, 0, !!detail, NULL);
|
|
} else {
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (json)
|
|
json_vrf = json_object_new_object();
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = show_ip_ospf_neighbor_id_common(
|
|
vty, ospf, &router_id, !!json, 0, !!detail,
|
|
json_vrf);
|
|
}
|
|
if (json)
|
|
vty_json(vty, json_vrf);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_instance_neighbor_id, show_ip_ospf_instance_neighbor_id_cmd,
|
|
"show ip ospf (1-65535)$instance neighbor A.B.C.D$router_id [detail$detail] [json$json]",
|
|
SHOW_STR IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
"Neighbor ID\n"
|
|
"Detailed output\n" JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json, 0,
|
|
!!detail, NULL);
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
|
|
struct ospf *ospf,
|
|
json_object *json, bool use_json,
|
|
uint8_t use_vrf)
|
|
{
|
|
struct ospf_interface *oi;
|
|
struct listnode *node;
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_nbr_sub = NULL;
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
|
|
json_nbr_sub = json_object_new_object();
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
|
struct route_node *rn;
|
|
struct ospf_neighbor *nbr, *prev_nbr = NULL;
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
|
|
nbr = rn->info;
|
|
|
|
if (!nbr)
|
|
continue;
|
|
|
|
if (nbr != oi->nbr_self) {
|
|
if (nbr->state != NSM_Down) {
|
|
show_ip_ospf_neighbor_detail_sub(
|
|
vty, oi, nbr, prev_nbr,
|
|
json_nbr_sub, use_json);
|
|
}
|
|
}
|
|
prev_nbr = nbr;
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
json_object_object_add(json_vrf, "neighbors",
|
|
json_nbr_sub);
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_neighbor_detail,
|
|
show_ip_ospf_neighbor_detail_cmd,
|
|
"show ip ospf [vrf <NAME|all>$vrf_name] neighbor detail [json$json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Neighbor list\n"
|
|
"detail of all neighbors\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
struct listnode *node = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
uint8_t use_vrf = 0;
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (json)
|
|
json_vrf = json_object_new_object();
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (strmatch(vrf_name, "all")) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = show_ip_ospf_neighbor_detail_common(
|
|
vty, ospf, json_vrf, !!json, use_vrf);
|
|
}
|
|
if (json)
|
|
vty_json(vty, json_vrf);
|
|
|
|
return ret;
|
|
}
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (json)
|
|
vty_json(vty, json_vrf);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
return CMD_SUCCESS;
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (json)
|
|
vty_json(vty, json_vrf);
|
|
else
|
|
vty_out(vty, "%% OSPF is not enabled\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf)
|
|
ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json_vrf,
|
|
!!json, use_vrf);
|
|
|
|
if (json)
|
|
vty_json(vty, json_vrf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_neighbor_detail,
|
|
show_ip_ospf_instance_neighbor_detail_cmd,
|
|
"show ip ospf (1-65535) neighbor detail [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
"detail of all neighbors\n"
|
|
JSON_STR)
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json, uj, 0);
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
|
|
struct ospf *ospf,
|
|
json_object *json,
|
|
bool use_json,
|
|
uint8_t use_vrf)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_interface *oi;
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
|
struct route_node *rn;
|
|
struct ospf_neighbor *nbr, *prev_nbr = NULL;
|
|
struct ospf_nbr_nbma *nbr_nbma;
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
|
|
nbr = rn->info;
|
|
|
|
if (!nbr)
|
|
continue;
|
|
|
|
if (nbr != oi->nbr_self)
|
|
if (nbr->state != NSM_Down)
|
|
show_ip_ospf_neighbor_detail_sub(
|
|
vty, oi, rn->info, prev_nbr,
|
|
json_vrf, use_json);
|
|
prev_nbr = nbr;
|
|
}
|
|
|
|
if (!OSPF_IF_NON_BROADCAST(oi))
|
|
continue;
|
|
|
|
struct listnode *nd;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nd, nbr_nbma)) {
|
|
if (nbr_nbma->nbr == NULL ||
|
|
nbr_nbma->nbr->state == NSM_Down)
|
|
show_ip_ospf_nbr_nbma_detail_sub(
|
|
vty, oi, nbr_nbma, use_json, json_vrf);
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else {
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_neighbor_detail_all,
|
|
show_ip_ospf_neighbor_detail_all_cmd,
|
|
"show ip ospf [vrf <NAME|all>] neighbor detail all [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Neighbor list\n"
|
|
"detail of all neighbors\n"
|
|
"include down status neighbor\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
bool uj = use_json(argc, argv);
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0;
|
|
uint8_t use_vrf = 0;
|
|
json_object *json = NULL;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = show_ip_ospf_neighbor_detail_all_common(
|
|
vty, ospf, json, uj, use_vrf);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
json_object_free(json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
json_object_free(json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf) {
|
|
ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, json,
|
|
uj, use_vrf);
|
|
if (uj) {
|
|
vty_out(vty, "%s\n",
|
|
json_object_to_json_string_ext(
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
}
|
|
}
|
|
|
|
if (uj)
|
|
json_object_free(json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_neighbor_detail_all,
|
|
show_ip_ospf_instance_neighbor_detail_all_cmd,
|
|
"show ip ospf (1-65535) neighbor detail all [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
"detail of all neighbors\n"
|
|
"include down status neighbor\n"
|
|
JSON_STR)
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
ret = show_ip_ospf_neighbor_detail_all_common(vty, ospf, json, uj, 0);
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
|
|
struct ospf *ospf,
|
|
const char *ifname,
|
|
bool use_json,
|
|
json_object *json_vrf)
|
|
{
|
|
struct ospf_interface *oi;
|
|
struct interface *ifp;
|
|
struct route_node *rn, *nrn;
|
|
struct ospf_neighbor *nbr;
|
|
json_object *json = NULL;
|
|
|
|
if (use_json) {
|
|
json = json_object_new_object();
|
|
if (json_vrf)
|
|
json_object_object_add(json_vrf,
|
|
(ospf->vrf_id == VRF_DEFAULT)
|
|
? "default"
|
|
: ospf->name,
|
|
json);
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (use_json)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ifp = if_lookup_by_name(ifname, ospf->vrf_id);
|
|
if (!ifp) {
|
|
if (!use_json) {
|
|
vty_out(vty, "No such interface.\n");
|
|
} else {
|
|
if (!json_vrf)
|
|
vty_json(vty, json);
|
|
}
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
oi = rn->info;
|
|
|
|
if (!oi)
|
|
continue;
|
|
|
|
for (nrn = route_top(oi->nbrs); nrn; nrn = route_next(nrn)) {
|
|
nbr = nrn->info;
|
|
|
|
if (!nbr)
|
|
continue;
|
|
|
|
if (nbr == oi->nbr_self)
|
|
continue;
|
|
|
|
if (nbr->state == NSM_Down)
|
|
continue;
|
|
|
|
show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, NULL,
|
|
json, use_json);
|
|
}
|
|
}
|
|
|
|
if (use_json) {
|
|
if (!json_vrf)
|
|
vty_json(vty, json);
|
|
} else {
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_neighbor_int,
|
|
show_ip_ospf_neighbor_int_cmd,
|
|
"show ip ospf [vrf NAME$vrf_name] neighbor IFNAME$ifname [json$json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"Neighbor list\n"
|
|
"Interface name\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
int ret = CMD_SUCCESS;
|
|
struct interface *ifp = NULL;
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
struct vrf *vrf = NULL;
|
|
|
|
if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
|
|
vrf_name = NULL;
|
|
if (vrf_name) {
|
|
vrf = vrf_lookup_by_name(vrf_name);
|
|
if (vrf)
|
|
vrf_id = vrf->vrf_id;
|
|
}
|
|
ospf = ospf_lookup_by_vrf_id(vrf_id);
|
|
|
|
if (!ospf || !ospf->oi_running) {
|
|
if (json)
|
|
vty_json_empty(vty, NULL);
|
|
return ret;
|
|
}
|
|
|
|
if (!json)
|
|
show_ip_ospf_neighbour_header(vty);
|
|
|
|
ifp = if_lookup_by_name(ifname, vrf_id);
|
|
if (!ifp) {
|
|
if (json)
|
|
vty_json_empty(vty, NULL);
|
|
else
|
|
vty_out(vty, "No such interface.\n");
|
|
return ret;
|
|
}
|
|
|
|
ret = show_ip_ospf_neighbor_int_common(vty, ospf, ifname, !!json, 0);
|
|
return ret;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_neighbor_int_detail,
|
|
show_ip_ospf_neighbor_int_detail_cmd,
|
|
"show ip ospf [vrf NAME$vrf_name] neighbor IFNAME$ifname detail [json$json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"Neighbor list\n"
|
|
"Interface name\n"
|
|
"detail of all neighbors\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
struct listnode *node = NULL;
|
|
int ret = CMD_SUCCESS;
|
|
bool ospf_output = false;
|
|
|
|
if (vrf_name && !strmatch(vrf_name, "all")) {
|
|
int inst = 0;
|
|
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (!json)
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
else
|
|
vty_json_empty(vty, NULL);
|
|
return CMD_SUCCESS;
|
|
}
|
|
return show_ip_ospf_neighbor_int_detail_common(
|
|
vty, ospf, ifname, !!json, NULL);
|
|
}
|
|
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (json)
|
|
json_vrf = json_object_new_object();
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ospf_output = true;
|
|
ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, ifname,
|
|
!!json, json_vrf);
|
|
}
|
|
|
|
if (json) {
|
|
vty_json(vty, json_vrf);
|
|
return ret;
|
|
}
|
|
|
|
if (!ospf_output)
|
|
vty_out(vty, "%% OSPF instance not found\n");
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFPY(show_ip_ospf_instance_neighbor_int_detail,
|
|
show_ip_ospf_instance_neighbor_int_detail_cmd,
|
|
"show ip ospf (1-65535)$instance neighbor IFNAME$ifname detail [json$json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Neighbor list\n"
|
|
"Interface name\n"
|
|
"detail of all neighbors\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
return show_ip_ospf_neighbor_int_detail_common(vty, ospf, ifname,
|
|
!!json, NULL);
|
|
}
|
|
|
|
/* Show functions */
|
|
static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self,
|
|
json_object *json_lsa)
|
|
{
|
|
struct router_lsa *rl;
|
|
struct summary_lsa *sl;
|
|
struct as_external_lsa *asel;
|
|
struct prefix_ipv4 p;
|
|
|
|
if (lsa == NULL)
|
|
return 0;
|
|
|
|
/* If self option is set, check LSA self flag. */
|
|
if (self == 0 || IS_LSA_SELF(lsa)) {
|
|
|
|
if (!json_lsa) {
|
|
/* LSA common part show. */
|
|
vty_out(vty, "%-15pI4", &lsa->data->id);
|
|
vty_out(vty, "%-15pI4 %4d 0x%08lx 0x%04x",
|
|
&lsa->data->adv_router, LS_AGE(lsa),
|
|
(unsigned long)ntohl(lsa->data->ls_seqnum),
|
|
ntohs(lsa->data->checksum));
|
|
} else {
|
|
char seqnum[10];
|
|
char checksum[10];
|
|
|
|
snprintf(seqnum, sizeof(seqnum), "%x",
|
|
ntohl(lsa->data->ls_seqnum));
|
|
snprintf(checksum, sizeof(checksum), "%x",
|
|
ntohs(lsa->data->checksum));
|
|
json_object_string_addf(json_lsa, "lsId", "%pI4",
|
|
&lsa->data->id);
|
|
json_object_string_addf(json_lsa, "advertisedRouter",
|
|
"%pI4", &lsa->data->adv_router);
|
|
json_object_int_add(json_lsa, "lsaAge", LS_AGE(lsa));
|
|
json_object_string_add(json_lsa, "sequenceNumber",
|
|
seqnum);
|
|
json_object_string_add(json_lsa, "checksum", checksum);
|
|
}
|
|
|
|
/* LSA specific part show. */
|
|
switch (lsa->data->type) {
|
|
case OSPF_ROUTER_LSA:
|
|
rl = (struct router_lsa *)lsa->data;
|
|
|
|
if (!json_lsa)
|
|
vty_out(vty, " %-d", ntohs(rl->links));
|
|
else
|
|
json_object_int_add(json_lsa,
|
|
"numOfRouterLinks",
|
|
ntohs(rl->links));
|
|
break;
|
|
case OSPF_SUMMARY_LSA:
|
|
sl = (struct summary_lsa *)lsa->data;
|
|
|
|
p.family = AF_INET;
|
|
p.prefix = sl->header.id;
|
|
p.prefixlen = ip_masklen(sl->mask);
|
|
apply_mask_ipv4(&p);
|
|
|
|
if (!json_lsa)
|
|
vty_out(vty, " %pFX", &p);
|
|
else {
|
|
json_object_string_addf(
|
|
json_lsa, "summaryAddress", "%pFX", &p);
|
|
}
|
|
break;
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
case OSPF_AS_NSSA_LSA:
|
|
asel = (struct as_external_lsa *)lsa->data;
|
|
|
|
p.family = AF_INET;
|
|
p.prefix = asel->header.id;
|
|
p.prefixlen = ip_masklen(asel->mask);
|
|
apply_mask_ipv4(&p);
|
|
|
|
if (!json_lsa)
|
|
vty_out(vty, " %s %pFX [0x%lx]",
|
|
IS_EXTERNAL_METRIC(asel->e[0].tos)
|
|
? "E2"
|
|
: "E1",
|
|
&p,
|
|
(unsigned long)ntohl(
|
|
asel->e[0].route_tag));
|
|
else {
|
|
json_object_string_add(
|
|
json_lsa, "metricType",
|
|
IS_EXTERNAL_METRIC(asel->e[0].tos)
|
|
? "E2"
|
|
: "E1");
|
|
json_object_string_addf(json_lsa, "route",
|
|
"%pFX", &p);
|
|
json_object_int_add(
|
|
json_lsa, "tag",
|
|
(unsigned long)ntohl(
|
|
asel->e[0].route_tag));
|
|
}
|
|
break;
|
|
case OSPF_NETWORK_LSA:
|
|
case OSPF_ASBR_SUMMARY_LSA:
|
|
case OSPF_OPAQUE_LINK_LSA:
|
|
case OSPF_OPAQUE_AREA_LSA:
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!json_lsa)
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static const char *const show_database_desc[] = {
|
|
"unknown",
|
|
"Router Link States",
|
|
"Net Link States",
|
|
"Summary Link States",
|
|
"ASBR-Summary Link States",
|
|
"AS External Link States",
|
|
"Group Membership LSA",
|
|
"NSSA-external Link States",
|
|
"Type-8 LSA",
|
|
"Link-Local Opaque-LSA",
|
|
"Area-Local Opaque-LSA",
|
|
"AS-external Opaque-LSA",
|
|
};
|
|
|
|
static const char * const show_database_desc_json[] = {
|
|
"unknown",
|
|
"routerLinkStates",
|
|
"networkLinkStates",
|
|
"summaryLinkStates",
|
|
"asbrSummaryLinkStates",
|
|
"asExternalLinkStates",
|
|
"groupMembershipLsa",
|
|
"nssaExternalLinkStates",
|
|
"type8Lsa",
|
|
"linkLocalOpaqueLsa",
|
|
"areaLocalOpaqueLsa",
|
|
"asExternalOpaqueLsa",
|
|
};
|
|
|
|
static const char *const show_database_desc_count_json[] = {
|
|
"unknownCount",
|
|
"routerLinkStatesCount",
|
|
"networkLinkStatesCount",
|
|
"summaryLinkStatesCount",
|
|
"asbrSummaryLinkStatesCount",
|
|
"asExternalLinkStatesCount",
|
|
"groupMembershipLsaCount",
|
|
"nssaExternalLinkStatesCount",
|
|
"type8LsaCount",
|
|
"linkLocalOpaqueLsaCount",
|
|
"areaLocalOpaqueLsaCount",
|
|
"asExternalOpaqueLsaCount",
|
|
};
|
|
|
|
static const char *const show_database_header[] = {
|
|
"",
|
|
"Link ID ADV Router Age Seq# CkSum Link count",
|
|
"Link ID ADV Router Age Seq# CkSum",
|
|
"Link ID ADV Router Age Seq# CkSum Route",
|
|
"Link ID ADV Router Age Seq# CkSum",
|
|
"Link ID ADV Router Age Seq# CkSum Route",
|
|
" --- header for Group Member ----",
|
|
"Link ID ADV Router Age Seq# CkSum Route",
|
|
" --- type-8 ---",
|
|
"Opaque-Type/Id ADV Router Age Seq# CkSum",
|
|
"Opaque-Type/Id ADV Router Age Seq# CkSum",
|
|
"Opaque-Type/Id ADV Router Age Seq# CkSum",
|
|
};
|
|
|
|
static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
struct router_lsa *rlsa = (struct router_lsa *)lsa->data;
|
|
|
|
if (!json) {
|
|
if (IS_LSA_SELF(lsa))
|
|
vty_out(vty, " LS age: %d%s\n", LS_AGE(lsa),
|
|
CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE)
|
|
? "(S-DNA)"
|
|
: "");
|
|
else
|
|
vty_out(vty, " LS age: %d%s\n", LS_AGE(lsa),
|
|
CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE)
|
|
? "(DNA)"
|
|
: "");
|
|
vty_out(vty, " Options: 0x%-2x : %s\n", lsa->data->options,
|
|
ospf_options_dump(lsa->data->options));
|
|
vty_out(vty, " LS Flags: 0x%-2x %s\n", lsa->flags,
|
|
((lsa->flags & OSPF_LSA_LOCAL_XLT)
|
|
? "(Translated from Type-7)"
|
|
: ""));
|
|
|
|
if (lsa->data->type == OSPF_ROUTER_LSA) {
|
|
vty_out(vty, " Flags: 0x%x", rlsa->flags);
|
|
|
|
if (rlsa->flags)
|
|
vty_out(vty, " :%s%s%s%s",
|
|
IS_ROUTER_LSA_BORDER(rlsa) ? " ABR"
|
|
: "",
|
|
IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR"
|
|
: "",
|
|
IS_ROUTER_LSA_VIRTUAL(rlsa)
|
|
? " VL-endpoint"
|
|
: "",
|
|
IS_ROUTER_LSA_SHORTCUT(rlsa)
|
|
? " Shortcut"
|
|
: "");
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
vty_out(vty, " LS Type: %s\n",
|
|
lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL));
|
|
vty_out(vty, " Link State ID: %pI4 %s\n",
|
|
&lsa->data->id,
|
|
lookup_msg(ospf_link_state_id_type_msg, lsa->data->type,
|
|
NULL));
|
|
vty_out(vty, " Advertising Router: %pI4\n",
|
|
&lsa->data->adv_router);
|
|
vty_out(vty, " LS Seq Number: %08lx\n",
|
|
(unsigned long)ntohl(lsa->data->ls_seqnum));
|
|
vty_out(vty, " Checksum: 0x%04x\n",
|
|
ntohs(lsa->data->checksum));
|
|
vty_out(vty, " Length: %d\n\n", ntohs(lsa->data->length));
|
|
} else {
|
|
char seqnum[10];
|
|
char checksum[10];
|
|
|
|
snprintf(seqnum, 10, "%x", ntohl(lsa->data->ls_seqnum));
|
|
snprintf(checksum, 10, "%x", ntohs(lsa->data->checksum));
|
|
|
|
json_object_int_add(json, "lsaAge", LS_AGE(lsa));
|
|
json_object_string_add(json, "options",
|
|
ospf_options_dump(lsa->data->options));
|
|
json_object_int_add(json, "lsaFlags", lsa->flags);
|
|
|
|
if (lsa->flags & OSPF_LSA_LOCAL_XLT)
|
|
json_object_boolean_true_add(json,
|
|
"translatedFromType7");
|
|
|
|
if (lsa->data->type == OSPF_ROUTER_LSA) {
|
|
json_object_int_add(json, "flags", rlsa->flags);
|
|
|
|
if (rlsa->flags) {
|
|
if (IS_ROUTER_LSA_BORDER(rlsa))
|
|
json_object_boolean_true_add(json,
|
|
"abr");
|
|
if (IS_ROUTER_LSA_EXTERNAL(rlsa))
|
|
json_object_boolean_true_add(json,
|
|
"asbr");
|
|
if (IS_ROUTER_LSA_VIRTUAL(rlsa))
|
|
json_object_boolean_true_add(
|
|
json, "vlEndpoint");
|
|
if (IS_ROUTER_LSA_SHORTCUT(rlsa))
|
|
json_object_boolean_true_add(
|
|
json, "shortcut");
|
|
}
|
|
}
|
|
|
|
json_object_string_add(
|
|
json, "lsaType",
|
|
lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL));
|
|
json_object_string_addf(json, "linkStateId", "%pI4",
|
|
&lsa->data->id);
|
|
json_object_string_addf(json, "advertisingRouter", "%pI4",
|
|
&lsa->data->adv_router);
|
|
json_object_string_add(json, "lsaSeqNumber", seqnum);
|
|
json_object_string_add(json, "checksum", checksum);
|
|
json_object_int_add(json, "length", ntohs(lsa->data->length));
|
|
}
|
|
}
|
|
|
|
static const char *const link_type_desc[] = {
|
|
"(null)",
|
|
"another Router (point-to-point)",
|
|
"a Transit Network",
|
|
"Stub Network",
|
|
"a Virtual Link",
|
|
};
|
|
|
|
static const char *const link_id_desc[] = {
|
|
"(null)", "Neighboring Router ID", "Designated Router address",
|
|
"Net", "Neighboring Router ID",
|
|
};
|
|
|
|
static const char *const link_data_desc[] = {
|
|
"(null)", "Router Interface address", "Router Interface address",
|
|
"Network Mask", "Router Interface address",
|
|
};
|
|
|
|
static const char *const link_id_desc_json[] = {
|
|
"null", "neighborRouterId", "designatedRouterAddress",
|
|
"networkAddress", "neighborRouterId",
|
|
};
|
|
|
|
static const char *const link_data_desc_json[] = {
|
|
"null", "routerInterfaceAddress", "routerInterfaceAddress",
|
|
"networkMask", "routerInterfaceAddress",
|
|
};
|
|
|
|
/* Show router-LSA each Link information. */
|
|
static void show_ip_ospf_database_router_links(struct vty *vty,
|
|
struct router_lsa *rl,
|
|
json_object *json)
|
|
{
|
|
int len, type;
|
|
unsigned short i;
|
|
json_object *json_links = NULL;
|
|
json_object *json_link = NULL;
|
|
int metric = 0;
|
|
char buf[PREFIX_STRLEN];
|
|
|
|
if (json)
|
|
json_links = json_object_new_object();
|
|
|
|
len = ntohs(rl->header.length) - 4;
|
|
for (i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) {
|
|
type = rl->link[i].type;
|
|
|
|
if (json) {
|
|
char link[16];
|
|
|
|
snprintf(link, sizeof(link), "link%u", i);
|
|
json_link = json_object_new_object();
|
|
json_object_string_add(json_link, "linkType",
|
|
link_type_desc[type]);
|
|
json_object_string_add(json_link,
|
|
link_id_desc_json[type],
|
|
inet_ntop(AF_INET,
|
|
&rl->link[i].link_id,
|
|
buf, sizeof(buf)));
|
|
json_object_string_add(
|
|
json_link, link_data_desc_json[type],
|
|
inet_ntop(AF_INET, &rl->link[i].link_data,
|
|
buf, sizeof(buf)));
|
|
json_object_int_add(json_link, "numOfTosMetrics",
|
|
metric);
|
|
json_object_int_add(json_link, "tos0Metric",
|
|
ntohs(rl->link[i].metric));
|
|
json_object_object_add(json_links, link, json_link);
|
|
} else {
|
|
vty_out(vty, " Link connected to: %s\n",
|
|
link_type_desc[type]);
|
|
vty_out(vty, " (Link ID) %s: %pI4\n",
|
|
link_id_desc[type],
|
|
&rl->link[i].link_id);
|
|
vty_out(vty, " (Link Data) %s: %pI4\n",
|
|
link_data_desc[type],
|
|
&rl->link[i].link_data);
|
|
vty_out(vty, " Number of TOS metrics: 0\n");
|
|
vty_out(vty, " TOS 0 Metric: %d\n",
|
|
ntohs(rl->link[i].metric));
|
|
vty_out(vty, "\n");
|
|
}
|
|
}
|
|
if (json)
|
|
json_object_object_add(json, "routerLinks", json_links);
|
|
}
|
|
|
|
/* Show router-LSA detail information. */
|
|
static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
if (lsa != NULL) {
|
|
struct router_lsa *rl = (struct router_lsa *)lsa->data;
|
|
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
|
|
if (!json)
|
|
vty_out(vty, " Number of Links: %d\n\n",
|
|
ntohs(rl->links));
|
|
else
|
|
json_object_int_add(json, "numOfLinks",
|
|
ntohs(rl->links));
|
|
|
|
show_ip_ospf_database_router_links(vty, rl, json);
|
|
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Show network-LSA detail information. */
|
|
static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
int length, i;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_attached_rt = NULL;
|
|
json_object *json_router = NULL;
|
|
|
|
if (json)
|
|
json_attached_rt = json_object_new_object();
|
|
|
|
if (lsa != NULL) {
|
|
struct network_lsa *nl = (struct network_lsa *)lsa->data;
|
|
struct in_addr *addr;
|
|
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
|
|
if (!json)
|
|
vty_out(vty, " Network Mask: /%d\n",
|
|
ip_masklen(nl->mask));
|
|
else
|
|
json_object_int_add(json, "networkMask",
|
|
ip_masklen(nl->mask));
|
|
|
|
length = lsa->size - OSPF_LSA_HEADER_SIZE - 4;
|
|
addr = &nl->routers[0];
|
|
for (i = 0; length > 0 && addr;
|
|
length -= 4, addr = &nl->routers[++i])
|
|
if (!json) {
|
|
vty_out(vty, " Attached Router: %pI4\n",
|
|
addr);
|
|
vty_out(vty, "\n");
|
|
} else {
|
|
json_router = json_object_new_object();
|
|
json_object_string_add(
|
|
json_router, "attachedRouterId",
|
|
inet_ntop(AF_INET, addr, buf,
|
|
sizeof(buf)));
|
|
json_object_object_add(json_attached_rt,
|
|
inet_ntop(AF_INET, addr,
|
|
buf,
|
|
sizeof(buf)),
|
|
json_router);
|
|
}
|
|
}
|
|
|
|
if (json)
|
|
json_object_object_add(json, "attchedRouters",
|
|
json_attached_rt);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Show summary-LSA detail information. */
|
|
static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
if (lsa != NULL) {
|
|
struct summary_lsa *sl = (struct summary_lsa *)lsa->data;
|
|
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
|
|
if (!json) {
|
|
vty_out(vty, " Network Mask: /%d\n",
|
|
ip_masklen(sl->mask));
|
|
vty_out(vty, " TOS: 0 Metric: %d\n",
|
|
GET_METRIC(sl->metric));
|
|
vty_out(vty, "\n");
|
|
} else {
|
|
json_object_int_add(json, "networkMask",
|
|
ip_masklen(sl->mask));
|
|
json_object_int_add(json, "tos0Metric",
|
|
GET_METRIC(sl->metric));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Show summary-ASBR-LSA detail information. */
|
|
static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
if (lsa != NULL) {
|
|
struct summary_lsa *sl = (struct summary_lsa *)lsa->data;
|
|
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
|
|
if (!json) {
|
|
vty_out(vty, " Network Mask: /%d\n",
|
|
ip_masklen(sl->mask));
|
|
vty_out(vty, " TOS: 0 Metric: %d\n",
|
|
GET_METRIC(sl->metric));
|
|
vty_out(vty, "\n");
|
|
} else {
|
|
json_object_int_add(json, "networkMask",
|
|
ip_masklen(sl->mask));
|
|
json_object_int_add(json, "tos0Metric",
|
|
GET_METRIC(sl->metric));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Show AS-external-LSA detail information. */
|
|
static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
int tos = 0;
|
|
|
|
if (lsa != NULL) {
|
|
struct as_external_lsa *al =
|
|
(struct as_external_lsa *)lsa->data;
|
|
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
|
|
if (!json) {
|
|
vty_out(vty, " Network Mask: /%d\n",
|
|
ip_masklen(al->mask));
|
|
vty_out(vty, " Metric Type: %s\n",
|
|
IS_EXTERNAL_METRIC(al->e[0].tos)
|
|
? "2 (Larger than any link state path)"
|
|
: "1");
|
|
vty_out(vty, " TOS: 0\n");
|
|
vty_out(vty, " Metric: %d\n",
|
|
GET_METRIC(al->e[0].metric));
|
|
vty_out(vty, " Forward Address: %pI4\n",
|
|
&al->e[0].fwd_addr);
|
|
vty_out(vty,
|
|
" External Route Tag: %" ROUTE_TAG_PRI "\n\n",
|
|
(route_tag_t)ntohl(al->e[0].route_tag));
|
|
} else {
|
|
json_object_int_add(json, "networkMask",
|
|
ip_masklen(al->mask));
|
|
json_object_string_add(
|
|
json, "metricType",
|
|
IS_EXTERNAL_METRIC(al->e[0].tos)
|
|
? "E2 (Larger than any link state path)"
|
|
: "E1");
|
|
json_object_int_add(json, "tos", tos);
|
|
json_object_int_add(json, "metric",
|
|
GET_METRIC(al->e[0].metric));
|
|
json_object_string_addf(json, "forwardAddress", "%pI4",
|
|
&(al->e[0].fwd_addr));
|
|
json_object_int_add(
|
|
json, "externalRouteTag",
|
|
(route_tag_t)ntohl(al->e[0].route_tag));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Show AS-NSSA-LSA detail information. */
|
|
static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
int tos = 0;
|
|
|
|
if (lsa != NULL) {
|
|
struct as_external_lsa *al =
|
|
(struct as_external_lsa *)lsa->data;
|
|
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
|
|
if (!json) {
|
|
vty_out(vty, " Network Mask: /%d\n",
|
|
ip_masklen(al->mask));
|
|
vty_out(vty, " Metric Type: %s\n",
|
|
IS_EXTERNAL_METRIC(al->e[0].tos)
|
|
? "2 (Larger than any link state path)"
|
|
: "1");
|
|
vty_out(vty, " TOS: 0\n");
|
|
vty_out(vty, " Metric: %d\n",
|
|
GET_METRIC(al->e[0].metric));
|
|
vty_out(vty, " NSSA: Forward Address: %pI4\n",
|
|
&al->e[0].fwd_addr);
|
|
vty_out(vty,
|
|
" External Route Tag: %" ROUTE_TAG_PRI
|
|
"\n\n",
|
|
(route_tag_t)ntohl(al->e[0].route_tag));
|
|
} else {
|
|
json_object_int_add(json, "networkMask",
|
|
ip_masklen(al->mask));
|
|
json_object_string_add(
|
|
json, "metricType",
|
|
IS_EXTERNAL_METRIC(al->e[0].tos)
|
|
? "E2 (Larger than any link state path)"
|
|
: "E1");
|
|
json_object_int_add(json, "tos", tos);
|
|
json_object_int_add(json, "metric",
|
|
GET_METRIC(al->e[0].metric));
|
|
json_object_string_addf(json, "nssaForwardAddress",
|
|
"%pI4", &al->e[0].fwd_addr);
|
|
json_object_int_add(
|
|
json, "externalRouteTag",
|
|
(route_tag_t)ntohl(al->e[0].route_tag));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
|
|
json_object *json)
|
|
{
|
|
if (lsa != NULL) {
|
|
show_ip_ospf_database_header(vty, lsa, json);
|
|
show_opaque_info_detail(vty, lsa, json);
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int (*show_function[])(struct vty *, struct ospf_lsa *, json_object *) = {
|
|
NULL,
|
|
show_router_lsa_detail,
|
|
show_network_lsa_detail,
|
|
show_summary_lsa_detail,
|
|
show_summary_asbr_lsa_detail,
|
|
show_as_external_lsa_detail,
|
|
show_func_dummy,
|
|
show_as_nssa_lsa_detail, /* almost same as external */
|
|
NULL, /* type-8 */
|
|
show_opaque_lsa_detail,
|
|
show_opaque_lsa_detail,
|
|
show_opaque_lsa_detail,
|
|
};
|
|
|
|
static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp,
|
|
struct in_addr *id, struct in_addr *adv_router)
|
|
{
|
|
memset(lp, 0, sizeof(struct prefix_ls));
|
|
lp->family = AF_UNSPEC;
|
|
if (id == NULL)
|
|
lp->prefixlen = 0;
|
|
else if (adv_router == NULL) {
|
|
lp->prefixlen = IPV4_MAX_BITLEN;
|
|
lp->id = *id;
|
|
} else {
|
|
lp->prefixlen = 64;
|
|
lp->id = *id;
|
|
lp->adv_router = *adv_router;
|
|
}
|
|
}
|
|
|
|
static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt,
|
|
struct in_addr *id, struct in_addr *adv_router,
|
|
json_object *json)
|
|
{
|
|
struct prefix_ls lp;
|
|
struct route_node *rn, *start;
|
|
struct ospf_lsa *lsa;
|
|
json_object *json_lsa = NULL;
|
|
|
|
show_lsa_prefix_set(vty, &lp, id, adv_router);
|
|
start = route_node_get(rt, (struct prefix *)&lp);
|
|
if (start) {
|
|
route_lock_node(start);
|
|
for (rn = start; rn; rn = route_next_until(rn, start))
|
|
if ((lsa = rn->info)) {
|
|
if (show_function[lsa->data->type] != NULL) {
|
|
if (json) {
|
|
json_lsa =
|
|
json_object_new_object();
|
|
json_object_array_add(json,
|
|
json_lsa);
|
|
}
|
|
|
|
show_function[lsa->data->type](
|
|
vty, lsa, json_lsa);
|
|
}
|
|
}
|
|
route_unlock_node(start);
|
|
}
|
|
}
|
|
|
|
/* Show detail LSA information
|
|
-- if id is NULL then show all LSAs. */
|
|
static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type,
|
|
struct in_addr *id, struct in_addr *adv_router,
|
|
json_object *json)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_lsa_type = NULL;
|
|
json_object *json_areas = NULL;
|
|
json_object *json_lsa_array = NULL;
|
|
|
|
switch (type) {
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
if (!json)
|
|
vty_out(vty, " %s \n\n",
|
|
show_database_desc[type]);
|
|
else
|
|
json_lsa_array = json_object_new_array();
|
|
|
|
show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router,
|
|
json_lsa_array);
|
|
if (json)
|
|
json_object_object_add(json,
|
|
show_database_desc_json[type],
|
|
json_lsa_array);
|
|
|
|
break;
|
|
default:
|
|
if (json)
|
|
json_areas = json_object_new_object();
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
if (!json) {
|
|
vty_out(vty,
|
|
"\n %s (Area %s)\n\n",
|
|
show_database_desc[type],
|
|
ospf_area_desc_string(area));
|
|
} else {
|
|
json_lsa_array = json_object_new_array();
|
|
json_object_object_add(json_areas,
|
|
inet_ntop(AF_INET,
|
|
&area->area_id,
|
|
buf,
|
|
sizeof(buf)),
|
|
json_lsa_array);
|
|
}
|
|
|
|
show_lsa_detail_proc(vty, AREA_LSDB(area, type), id,
|
|
adv_router, json_lsa_array);
|
|
}
|
|
|
|
if (json) {
|
|
json_lsa_type = json_object_new_object();
|
|
json_object_object_add(json_lsa_type, "areas",
|
|
json_areas);
|
|
json_object_object_add(json,
|
|
show_database_desc_json[type],
|
|
json_lsa_type);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void show_lsa_detail_adv_router_proc(struct vty *vty,
|
|
struct route_table *rt,
|
|
struct in_addr *adv_router,
|
|
json_object *json)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_lsa *lsa;
|
|
json_object *json_lsa = NULL;
|
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn))
|
|
if ((lsa = rn->info)) {
|
|
if (IPV4_ADDR_SAME(adv_router,
|
|
&lsa->data->adv_router)) {
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
|
|
continue;
|
|
if (json) {
|
|
json_lsa = json_object_new_object();
|
|
json_object_array_add(json, json_lsa);
|
|
}
|
|
|
|
if (show_function[lsa->data->type] != NULL)
|
|
show_function[lsa->data->type](
|
|
vty, lsa, json_lsa);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Show detail LSA information. */
|
|
static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf,
|
|
int type, struct in_addr *adv_router,
|
|
json_object *json)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_lsa_type = NULL;
|
|
json_object *json_areas = NULL;
|
|
json_object *json_lsa_array = NULL;
|
|
|
|
if (json)
|
|
json_lsa_type = json_object_new_object();
|
|
|
|
switch (type) {
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
if (!json)
|
|
vty_out(vty, " %s \n\n",
|
|
show_database_desc[type]);
|
|
else
|
|
json_lsa_array = json_object_new_array();
|
|
|
|
show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type),
|
|
adv_router, json_lsa_array);
|
|
if (json)
|
|
json_object_object_add(json,
|
|
show_database_desc_json[type],
|
|
json_lsa_array);
|
|
break;
|
|
default:
|
|
if (json)
|
|
json_areas = json_object_new_object();
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
if (!json) {
|
|
vty_out(vty,
|
|
"\n %s (Area %s)\n\n",
|
|
show_database_desc[type],
|
|
ospf_area_desc_string(area));
|
|
} else {
|
|
json_lsa_array = json_object_new_array();
|
|
json_object_object_add(
|
|
json_areas,
|
|
inet_ntop(AF_INET, &area->area_id, buf,
|
|
sizeof(buf)),
|
|
json_lsa_array);
|
|
}
|
|
|
|
show_lsa_detail_adv_router_proc(
|
|
vty, AREA_LSDB(area, type), adv_router,
|
|
json_lsa_array);
|
|
}
|
|
|
|
if (json) {
|
|
json_object_object_add(json_lsa_type, "areas",
|
|
json_areas);
|
|
json_object_object_add(json,
|
|
show_database_desc_json[type],
|
|
json_lsa_type);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, int self,
|
|
json_object *json)
|
|
{
|
|
struct ospf_lsa *lsa;
|
|
struct route_node *rn;
|
|
struct ospf_area *area;
|
|
struct listnode *node;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_areas = NULL;
|
|
json_object *json_area = NULL;
|
|
json_object *json_lsa = NULL;
|
|
int type;
|
|
json_object *json_lsa_array = NULL;
|
|
uint32_t count;
|
|
|
|
if (json)
|
|
json_areas = json_object_new_object();
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
if (json)
|
|
json_area = json_object_new_object();
|
|
|
|
for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) {
|
|
count = 0;
|
|
switch (type) {
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
continue;
|
|
default:
|
|
break;
|
|
}
|
|
if (ospf_lsdb_count_self(area->lsdb, type) > 0
|
|
|| (!self
|
|
&& ospf_lsdb_count(area->lsdb, type) > 0)) {
|
|
|
|
if (!json) {
|
|
vty_out(vty,
|
|
" %s (Area %s)\n\n",
|
|
show_database_desc[type],
|
|
ospf_area_desc_string(area));
|
|
vty_out(vty, "%s\n",
|
|
show_database_header[type]);
|
|
} else {
|
|
json_lsa_array =
|
|
json_object_new_array();
|
|
json_object_object_add(
|
|
json_area,
|
|
show_database_desc_json[type],
|
|
json_lsa_array);
|
|
}
|
|
|
|
LSDB_LOOP (AREA_LSDB(area, type), rn, lsa) {
|
|
if (json) {
|
|
json_lsa =
|
|
json_object_new_object();
|
|
json_object_array_add(
|
|
json_lsa_array,
|
|
json_lsa);
|
|
}
|
|
|
|
count += show_lsa_summary(
|
|
vty, lsa, self, json_lsa);
|
|
}
|
|
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
else
|
|
json_object_int_add(
|
|
json_area,
|
|
|
|
show_database_desc_count_json
|
|
[type],
|
|
count);
|
|
}
|
|
}
|
|
if (json)
|
|
json_object_object_add(json_areas,
|
|
inet_ntop(AF_INET,
|
|
&area->area_id,
|
|
buf, sizeof(buf)),
|
|
json_area);
|
|
}
|
|
|
|
if (json)
|
|
json_object_object_add(json, "areas", json_areas);
|
|
|
|
for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) {
|
|
count = 0;
|
|
switch (type) {
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
if (ospf_lsdb_count_self(ospf->lsdb, type)
|
|
|| (!self && ospf_lsdb_count(ospf->lsdb, type))) {
|
|
if (!json) {
|
|
vty_out(vty, " %s\n\n",
|
|
show_database_desc[type]);
|
|
vty_out(vty, "%s\n",
|
|
show_database_header[type]);
|
|
} else {
|
|
json_lsa_array = json_object_new_array();
|
|
json_object_object_add(
|
|
json, show_database_desc_json[type],
|
|
json_lsa_array);
|
|
}
|
|
|
|
LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa) {
|
|
if (json) {
|
|
json_lsa = json_object_new_object();
|
|
json_object_array_add(json_lsa_array,
|
|
json_lsa);
|
|
}
|
|
|
|
count += show_lsa_summary(vty, lsa, self,
|
|
json_lsa);
|
|
}
|
|
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
else
|
|
json_object_int_add(
|
|
json,
|
|
show_database_desc_count_json[type],
|
|
count);
|
|
}
|
|
}
|
|
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf,
|
|
json_object *json)
|
|
{
|
|
struct route_node *rn;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_maxage = NULL;
|
|
|
|
if (!json)
|
|
vty_out(vty, "\n MaxAge Link States:\n\n");
|
|
else
|
|
json_maxage = json_object_new_object();
|
|
|
|
for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
|
|
struct ospf_lsa *lsa;
|
|
json_object *json_lsa = NULL;
|
|
|
|
if ((lsa = rn->info) != NULL) {
|
|
if (!json) {
|
|
vty_out(vty, "Link type: %d\n",
|
|
lsa->data->type);
|
|
vty_out(vty, "Link State ID: %pI4\n",
|
|
&lsa->data->id);
|
|
vty_out(vty, "Advertising Router: %pI4\n",
|
|
&lsa->data->adv_router);
|
|
vty_out(vty, "LSA lock count: %d\n", lsa->lock);
|
|
vty_out(vty, "\n");
|
|
} else {
|
|
json_lsa = json_object_new_object();
|
|
json_object_int_add(json_lsa, "linkType",
|
|
lsa->data->type);
|
|
json_object_string_addf(json_lsa, "linkStateId",
|
|
"%pI4", &lsa->data->id);
|
|
json_object_string_addf(
|
|
json_lsa, "advertisingRouter", "%pI4",
|
|
&lsa->data->adv_router);
|
|
json_object_int_add(json_lsa, "lsaLockCount",
|
|
lsa->lock);
|
|
json_object_object_add(
|
|
json_maxage,
|
|
inet_ntop(AF_INET,
|
|
&lsa->data->id,
|
|
buf, sizeof(buf)),
|
|
json_lsa);
|
|
}
|
|
}
|
|
}
|
|
if (json)
|
|
json_object_object_add(json, "maxAgeLinkStates", json_maxage);
|
|
}
|
|
|
|
#define OSPF_LSA_TYPE_NSSA_DESC "NSSA external link state\n"
|
|
#define OSPF_LSA_TYPE_NSSA_CMD_STR "|nssa-external"
|
|
|
|
#define OSPF_LSA_TYPE_OPAQUE_LINK_DESC "Link local Opaque-LSA\n"
|
|
#define OSPF_LSA_TYPE_OPAQUE_AREA_DESC "Link area Opaque-LSA\n"
|
|
#define OSPF_LSA_TYPE_OPAQUE_AS_DESC "Link AS Opaque-LSA\n"
|
|
#define OSPF_LSA_TYPE_OPAQUE_CMD_STR "|opaque-link|opaque-area|opaque-as"
|
|
|
|
#define OSPF_LSA_TYPES_DESC \
|
|
"ASBR summary link states\n" \
|
|
"External link states\n" \
|
|
"Network link states\n" \
|
|
"Router link states\n" \
|
|
"Network summary link states\n" OSPF_LSA_TYPE_NSSA_DESC \
|
|
OSPF_LSA_TYPE_OPAQUE_LINK_DESC OSPF_LSA_TYPE_OPAQUE_AREA_DESC \
|
|
OSPF_LSA_TYPE_OPAQUE_AS_DESC
|
|
|
|
static int
|
|
show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, bool maxage,
|
|
bool self, bool detail, const char *type_name,
|
|
struct in_addr *lsid, struct in_addr *adv_router,
|
|
bool use_vrf, json_object *json, bool uj)
|
|
{
|
|
int type;
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (uj) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (uj)
|
|
json_object_int_add(json_vrf, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
/* Show Router ID. */
|
|
if (uj) {
|
|
json_object_string_addf(json_vrf, "routerId", "%pI4",
|
|
&ospf->router_id);
|
|
} else {
|
|
vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n",
|
|
&ospf->router_id);
|
|
}
|
|
|
|
/* Show MaxAge LSAs */
|
|
if (maxage) {
|
|
show_ip_ospf_database_maxage(vty, ospf, json_vrf);
|
|
if (json) {
|
|
if (use_vrf) {
|
|
if (ospf->vrf_id == VRF_DEFAULT)
|
|
json_object_object_add(json, "default",
|
|
json_vrf);
|
|
else
|
|
json_object_object_add(json, ospf->name,
|
|
json_vrf);
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Show all LSAs. */
|
|
if (!type_name) {
|
|
if (detail) {
|
|
for (int i = OSPF_ROUTER_LSA; i <= OSPF_OPAQUE_AS_LSA;
|
|
i++) {
|
|
switch (i) {
|
|
case OSPF_GROUP_MEMBER_LSA:
|
|
case OSPF_EXTERNAL_ATTRIBUTES_LSA:
|
|
/* ignore deprecated LSA types */
|
|
continue;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (adv_router && !lsid)
|
|
show_lsa_detail_adv_router(vty, ospf, i,
|
|
adv_router,
|
|
json_vrf);
|
|
else
|
|
show_lsa_detail(vty, ospf, i, lsid,
|
|
adv_router, json_vrf);
|
|
}
|
|
} else
|
|
show_ip_ospf_database_summary(vty, ospf, self,
|
|
json_vrf);
|
|
|
|
if (json) {
|
|
if (use_vrf) {
|
|
if (ospf->vrf_id == VRF_DEFAULT)
|
|
json_object_object_add(json, "default",
|
|
json_vrf);
|
|
else
|
|
json_object_object_add(json, ospf->name,
|
|
json_vrf);
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Set database type to show. */
|
|
if (strncmp(type_name, "r", 1) == 0)
|
|
type = OSPF_ROUTER_LSA;
|
|
else if (strncmp(type_name, "ne", 2) == 0)
|
|
type = OSPF_NETWORK_LSA;
|
|
else if (strncmp(type_name, "ns", 2) == 0)
|
|
type = OSPF_AS_NSSA_LSA;
|
|
else if (strncmp(type_name, "su", 2) == 0)
|
|
type = OSPF_SUMMARY_LSA;
|
|
else if (strncmp(type_name, "a", 1) == 0)
|
|
type = OSPF_ASBR_SUMMARY_LSA;
|
|
else if (strncmp(type_name, "e", 1) == 0)
|
|
type = OSPF_AS_EXTERNAL_LSA;
|
|
else if (strncmp(type_name, "opaque-l", 8) == 0)
|
|
type = OSPF_OPAQUE_LINK_LSA;
|
|
else if (strncmp(type_name, "opaque-ar", 9) == 0)
|
|
type = OSPF_OPAQUE_AREA_LSA;
|
|
else if (strncmp(type_name, "opaque-as", 9) == 0)
|
|
type = OSPF_OPAQUE_AS_LSA;
|
|
else {
|
|
if (uj) {
|
|
if (use_vrf)
|
|
json_object_free(json_vrf);
|
|
}
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
if (adv_router && !lsid)
|
|
show_lsa_detail_adv_router(vty, ospf, type, adv_router,
|
|
json_vrf);
|
|
else
|
|
show_lsa_detail(vty, ospf, type, lsid, adv_router, json_vrf);
|
|
|
|
if (json) {
|
|
if (use_vrf) {
|
|
if (ospf->vrf_id == VRF_DEFAULT)
|
|
json_object_object_add(json, "default",
|
|
json_vrf);
|
|
else
|
|
json_object_object_add(json, ospf->name,
|
|
json_vrf);
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (show_ip_ospf_database,
|
|
show_ip_ospf_database_cmd,
|
|
"show ip ospf [(1-65535)$instance_id] [vrf <NAME|all>$vrf_name] database\
|
|
[<\
|
|
max-age$maxage\
|
|
|self-originate$selforig\
|
|
|<\
|
|
detail$detail\
|
|
|<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as>$type_name\
|
|
>\
|
|
[{\
|
|
A.B.C.D$lsid\
|
|
|<adv-router A.B.C.D$adv_router|self-originate$adv_router_self>\
|
|
}]\
|
|
>]\
|
|
[json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Database summary\n"
|
|
"LSAs in MaxAge list\n"
|
|
"Self-originated link states\n"
|
|
"Show detailed information\n"
|
|
OSPF_LSA_TYPES_DESC
|
|
"Link State ID (as an IP address)\n"
|
|
"Advertising Router link states\n"
|
|
"Advertising Router (as an IP address)\n"
|
|
"Self-originated link states\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf;
|
|
int ret = CMD_SUCCESS;
|
|
bool use_vrf = !!vrf_name;
|
|
bool uj = use_json(argc, argv);
|
|
struct in_addr *lsid_p = NULL;
|
|
struct in_addr *adv_router_p = NULL;
|
|
json_object *json = NULL;
|
|
|
|
if (instance_id != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
if (lsid_str)
|
|
lsid_p = &lsid;
|
|
if (adv_router_str)
|
|
adv_router_p = &adv_router;
|
|
|
|
if (vrf_name && strmatch(vrf_name, "all")) {
|
|
struct listnode *node;
|
|
bool ospf_output = false;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
if (ospf->instance != instance_id)
|
|
continue;
|
|
|
|
if (adv_router_self)
|
|
adv_router_p = &ospf->router_id;
|
|
|
|
ospf_output = true;
|
|
ret = show_ip_ospf_database_common(
|
|
vty, ospf, !!maxage, !!selforig, !!detail,
|
|
type_name, lsid_p, adv_router_p, use_vrf, json,
|
|
uj);
|
|
}
|
|
|
|
if (!ospf_output && !uj)
|
|
vty_out(vty, "%% OSPF is not enabled\n");
|
|
} else {
|
|
if (!vrf_name)
|
|
vrf_name = VRF_DEFAULT_NAME;
|
|
ospf = ospf_lookup_by_inst_name(instance_id, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty, "%% OSPF instance not found\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
if (adv_router_self)
|
|
adv_router_p = &ospf->router_id;
|
|
|
|
ret = (show_ip_ospf_database_common(
|
|
vty, ospf, !!maxage, !!selforig, !!detail, type_name,
|
|
lsid_p, adv_router_p, use_vrf, json, uj));
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (ip_ospf_authentication_args,
|
|
ip_ospf_authentication_args_addr_cmd,
|
|
"ip ospf authentication <null|message-digest|key-chain KEYCHAIN_NAME> [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Enable authentication on this interface\n"
|
|
"Use null authentication\n"
|
|
"Use message-digest authentication\n"
|
|
"Use a key-chain for cryptographic authentication keys\n"
|
|
"Key-chain name\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_encryption = 3;
|
|
int idx_ipv4 = argc-1;
|
|
struct in_addr addr;
|
|
int ret;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv[idx_ipv4]->type == IPV4_TKN) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
/* Handle null authentication */
|
|
if (argv[idx_encryption]->arg[0] == 'n') {
|
|
SET_IF_PARAM(params, auth_type);
|
|
params->auth_type = OSPF_AUTH_NULL;
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Handle message-digest authentication */
|
|
if (argv[idx_encryption]->arg[0] == 'm') {
|
|
SET_IF_PARAM(params, auth_type);
|
|
params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
|
|
UNSET_IF_PARAM(params, keychain_name);
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
if (argv[idx_encryption]->arg[0] == 'k') {
|
|
SET_IF_PARAM(params, auth_type);
|
|
params->auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
|
|
SET_IF_PARAM(params, keychain_name);
|
|
params->keychain_name = XSTRDUP(MTYPE_OSPF_IF_PARAMS, argv[idx_encryption+1]->arg);
|
|
UNSET_IF_PARAM(params, auth_crypt);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
vty_out(vty, "You shouldn't get here!\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
DEFUN (ip_ospf_authentication,
|
|
ip_ospf_authentication_addr_cmd,
|
|
"ip ospf authentication [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Enable authentication on this interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = 3;
|
|
struct in_addr addr;
|
|
int ret;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argc == 4) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
SET_IF_PARAM(params, auth_type);
|
|
params->auth_type = OSPF_AUTH_SIMPLE;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_authentication_args,
|
|
no_ip_ospf_authentication_args_addr_cmd,
|
|
"no ip ospf authentication <null|message-digest|key-chain [KEYCHAIN_NAME]> [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Enable authentication on this interface\n"
|
|
"Use null authentication\n"
|
|
"Use message-digest authentication\n"
|
|
"Use a key-chain for cryptographic authentication keys\n"
|
|
"Key-chain name\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_encryption = 4;
|
|
int idx_ipv4 = argc-1;
|
|
struct in_addr addr;
|
|
int ret;
|
|
struct ospf_if_params *params;
|
|
struct route_node *rn;
|
|
int auth_type;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv[idx_ipv4]->type == IPV4_TKN) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL) {
|
|
vty_out(vty, "Ip Address specified is unknown\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params->auth_type = OSPF_AUTH_NOTSET;
|
|
UNSET_IF_PARAM(params, auth_type);
|
|
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
|
|
UNSET_IF_PARAM(params, keychain_name);
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
} else {
|
|
if (argv[idx_encryption]->arg[0] == 'n') {
|
|
auth_type = OSPF_AUTH_NULL;
|
|
} else if (argv[idx_encryption]->arg[0] == 'm' ||
|
|
argv[idx_encryption]->arg[0] == 'k') {
|
|
auth_type = OSPF_AUTH_CRYPTOGRAPHIC;
|
|
} else {
|
|
vty_out(vty, "Unexpected input encountered\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
/*
|
|
* Here we have a case where the user has entered
|
|
* 'no ip ospf authentication (null | message_digest )'
|
|
* we need to find if we have any ip addresses underneath it
|
|
* that
|
|
* correspond to the associated type.
|
|
*/
|
|
if (params->auth_type == auth_type) {
|
|
params->auth_type = OSPF_AUTH_NOTSET;
|
|
UNSET_IF_PARAM(params, auth_type);
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
|
|
UNSET_IF_PARAM(params, keychain_name);
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn;
|
|
rn = route_next(rn)) {
|
|
if ((params = rn->info)) {
|
|
if (params->auth_type == auth_type) {
|
|
params->auth_type = OSPF_AUTH_NOTSET;
|
|
UNSET_IF_PARAM(params, auth_type);
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, params->keychain_name);
|
|
UNSET_IF_PARAM(params, keychain_name);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(
|
|
ifp, rn->p.u.prefix4);
|
|
ospf_if_update_params(
|
|
ifp, rn->p.u.prefix4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_authentication,
|
|
no_ip_ospf_authentication_addr_cmd,
|
|
"no ip ospf authentication [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Enable authentication on this interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = 4;
|
|
struct in_addr addr;
|
|
int ret;
|
|
struct ospf_if_params *params;
|
|
struct route_node *rn;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argc == 5) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL) {
|
|
vty_out(vty, "Ip Address specified is unknown\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params->auth_type = OSPF_AUTH_NOTSET;
|
|
UNSET_IF_PARAM(params, auth_type);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
} else {
|
|
/*
|
|
* When a user enters 'no ip ospf authentication'
|
|
* We should remove all authentication types from
|
|
* the interface.
|
|
*/
|
|
if ((params->auth_type == OSPF_AUTH_NULL)
|
|
|| (params->auth_type == OSPF_AUTH_CRYPTOGRAPHIC)
|
|
|| (params->auth_type == OSPF_AUTH_SIMPLE)) {
|
|
params->auth_type = OSPF_AUTH_NOTSET;
|
|
UNSET_IF_PARAM(params, auth_type);
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn;
|
|
rn = route_next(rn)) {
|
|
if ((params = rn->info)) {
|
|
|
|
if ((params->auth_type == OSPF_AUTH_NULL)
|
|
|| (params->auth_type
|
|
== OSPF_AUTH_CRYPTOGRAPHIC)
|
|
|| (params->auth_type
|
|
== OSPF_AUTH_SIMPLE)) {
|
|
params->auth_type = OSPF_AUTH_NOTSET;
|
|
UNSET_IF_PARAM(params, auth_type);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(
|
|
ifp, rn->p.u.prefix4);
|
|
ospf_if_update_params(
|
|
ifp, rn->p.u.prefix4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ip_ospf_authentication_key,
|
|
ip_ospf_authentication_key_addr_cmd,
|
|
"ip ospf authentication-key AUTH_KEY [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Authentication password (key)\n"
|
|
"The OSPF password (key)\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
strlcpy((char *)params->auth_simple, argv[3]->arg,
|
|
sizeof(params->auth_simple));
|
|
SET_IF_PARAM(params, auth_simple);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_authentication_key,
|
|
ospf_authentication_key_cmd,
|
|
"ospf authentication-key AUTH_KEY [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
VLINK_HELPSTR_AUTH_SIMPLE
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_authentication_key(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_authentication_key,
|
|
no_ip_ospf_authentication_key_authkey_addr_cmd,
|
|
"no ip ospf authentication-key [AUTH_KEY [A.B.C.D]]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
VLINK_HELPSTR_AUTH_SIMPLE
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
memset(params->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
|
|
UNSET_IF_PARAM(params, auth_simple);
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_authentication_key,
|
|
no_ospf_authentication_key_authkey_addr_cmd,
|
|
"no ospf authentication-key [AUTH_KEY [A.B.C.D]]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
VLINK_HELPSTR_AUTH_SIMPLE
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_authentication_key(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_message_digest_key,
|
|
ip_ospf_message_digest_key_cmd,
|
|
"ip ospf message-digest-key (1-255) md5 KEY [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Message digest authentication password (key)\n"
|
|
"Key ID\n"
|
|
"Use MD5 algorithm\n"
|
|
"The OSPF password (key)\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct crypt_key *ck;
|
|
uint8_t key_id;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
int idx = 0;
|
|
|
|
argv_find(argv, argc, "(1-255)", &idx);
|
|
char *keyid = argv[idx]->arg;
|
|
argv_find(argv, argc, "KEY", &idx);
|
|
char *cryptkey = argv[idx]->arg;
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
key_id = strtol(keyid, NULL, 10);
|
|
|
|
/* Remove existing key, if any */
|
|
ospf_crypt_key_delete(params->auth_crypt, key_id);
|
|
|
|
ck = ospf_crypt_key_new();
|
|
ck->key_id = (uint8_t)key_id;
|
|
strlcpy((char *)ck->auth_key, cryptkey, sizeof(ck->auth_key));
|
|
|
|
ospf_crypt_key_add(params->auth_crypt, ck);
|
|
SET_IF_PARAM(params, auth_crypt);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_message_digest_key,
|
|
ospf_message_digest_key_cmd,
|
|
"ospf message-digest-key (1-255) md5 KEY [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Message digest authentication password (key)\n"
|
|
"Key ID\n"
|
|
"Use MD5 algorithm\n"
|
|
"The OSPF password (key)\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_message_digest_key(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_message_digest_key,
|
|
no_ip_ospf_message_digest_key_cmd,
|
|
"no ip ospf message-digest-key (1-255) [md5 KEY] [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Message digest authentication password (key)\n"
|
|
"Key ID\n"
|
|
"Use MD5 algorithm\n"
|
|
"The OSPF password (key)\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct crypt_key *ck;
|
|
int key_id;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
argv_find(argv, argc, "(1-255)", &idx);
|
|
char *keyid = argv[idx]->arg;
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
key_id = strtol(keyid, NULL, 10);
|
|
ck = ospf_crypt_key_lookup(params->auth_crypt, key_id);
|
|
if (ck == NULL) {
|
|
vty_out(vty, "OSPF: Key %d does not exist\n", key_id);
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ospf_crypt_key_delete(params->auth_crypt, key_id);
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_message_digest_key,
|
|
no_ospf_message_digest_key_cmd,
|
|
"no ospf message-digest-key (1-255) [md5 KEY] [A.B.C.D]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Message digest authentication password (key)\n"
|
|
"Key ID\n"
|
|
"Use MD5 algorithm\n"
|
|
"The OSPF password (key)\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_message_digest_key(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_cost,
|
|
ip_ospf_cost_cmd,
|
|
"ip ospf cost (1-65535) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Interface cost\n"
|
|
"Cost\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
uint32_t cost = OSPF_OUTPUT_COST_DEFAULT;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
// get arguments
|
|
char *coststr = NULL, *ifaddr = NULL;
|
|
|
|
argv_find(argv, argc, "(1-65535)", &idx);
|
|
coststr = argv[idx]->arg;
|
|
cost = strtol(coststr, NULL, 10);
|
|
|
|
ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
|
|
if (ifaddr) {
|
|
if (!inet_aton(ifaddr, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
SET_IF_PARAM(params, output_cost_cmd);
|
|
params->output_cost_cmd = cost;
|
|
|
|
ospf_if_recalculate_output_cost(ifp);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_cost,
|
|
ospf_cost_cmd,
|
|
"ospf cost (1-65535) [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Interface cost\n"
|
|
"Cost\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_cost(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_cost,
|
|
no_ip_ospf_cost_cmd,
|
|
"no ip ospf cost [(1-65535)] [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Interface cost\n"
|
|
"Cost\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
// get arguments
|
|
char *ifaddr = NULL;
|
|
ifaddr = argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
|
|
|
|
/* According to the semantics we are mimicking "no ip ospf cost N" is
|
|
* always treated as "no ip ospf cost" regardless of the actual value
|
|
* of N already configured for the interface. Thus ignore cost. */
|
|
|
|
if (ifaddr) {
|
|
if (!inet_aton(ifaddr, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, output_cost_cmd);
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
ospf_if_recalculate_output_cost(ifp);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_cost,
|
|
no_ospf_cost_cmd,
|
|
"no ospf cost [(1-65535)] [A.B.C.D]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Interface cost\n"
|
|
"Cost\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_cost(self, vty, argc, argv);
|
|
}
|
|
|
|
static void ospf_nbr_timer_update(struct ospf_interface *oi)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_neighbor *nbr;
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
|
|
nbr = rn->info;
|
|
|
|
if (!nbr)
|
|
continue;
|
|
|
|
nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait);
|
|
nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval);
|
|
nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval);
|
|
nbr->v_ls_rxmt = OSPF_IF_PARAM(oi, retransmit_interval);
|
|
}
|
|
}
|
|
|
|
static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str,
|
|
const char *nbr_str,
|
|
const char *fast_hello_str)
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
uint32_t seconds;
|
|
uint8_t hellomult;
|
|
struct in_addr addr = { INADDR_ANY };
|
|
int ret;
|
|
struct ospf_if_params *params;
|
|
struct ospf_interface *oi;
|
|
struct route_node *rn;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (nbr_str) {
|
|
ret = inet_aton(nbr_str, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
if (interval_str) {
|
|
seconds = strtoul(interval_str, NULL, 10);
|
|
|
|
/* reset fast_hello too, just to be sure */
|
|
UNSET_IF_PARAM(params, fast_hello);
|
|
params->fast_hello = OSPF_FAST_HELLO_DEFAULT;
|
|
} else if (fast_hello_str) {
|
|
hellomult = strtoul(fast_hello_str, NULL, 10);
|
|
/* 1s dead-interval with sub-second hellos desired */
|
|
seconds = OSPF_ROUTER_DEAD_INTERVAL_MINIMAL;
|
|
SET_IF_PARAM(params, fast_hello);
|
|
params->fast_hello = hellomult;
|
|
} else {
|
|
vty_out(vty,
|
|
"Please specify dead-interval or hello-multiplier\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
SET_IF_PARAM(params, v_wait);
|
|
params->v_wait = seconds;
|
|
params->is_v_wait_set = true;
|
|
|
|
/* Update timer values in neighbor structure. */
|
|
if (nbr_str) {
|
|
struct ospf *ospf = NULL;
|
|
|
|
ospf = ifp->vrf->info;
|
|
if (ospf) {
|
|
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
|
|
if (oi)
|
|
ospf_nbr_timer_update(oi);
|
|
}
|
|
} else {
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
|
|
if ((oi = rn->info))
|
|
ospf_nbr_timer_update(oi);
|
|
}
|
|
|
|
if (params->fast_hello != OSPF_FAST_HELLO_DEFAULT)
|
|
ospf_reset_hello_timer(ifp, addr, false);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ip_ospf_dead_interval,
|
|
ip_ospf_dead_interval_cmd,
|
|
"ip ospf dead-interval (1-65535) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Interval time after which a neighbor is declared down\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
int idx = 0;
|
|
char *interval = argv_find(argv, argc, "(1-65535)", &idx)
|
|
? argv[idx]->arg
|
|
: NULL;
|
|
char *ifaddr =
|
|
argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
|
|
return ospf_vty_dead_interval_set(vty, interval, ifaddr, NULL);
|
|
}
|
|
|
|
|
|
DEFUN_HIDDEN (ospf_dead_interval,
|
|
ospf_dead_interval_cmd,
|
|
"ospf dead-interval (1-65535) [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Interval time after which a neighbor is declared down\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_dead_interval(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_dead_interval_minimal,
|
|
ip_ospf_dead_interval_minimal_addr_cmd,
|
|
"ip ospf dead-interval minimal hello-multiplier (2-20) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Interval time after which a neighbor is declared down\n"
|
|
"Minimal 1s dead-interval with fast sub-second hellos\n"
|
|
"Hello multiplier factor\n"
|
|
"Number of Hellos to send each second\n"
|
|
"Address of interface\n")
|
|
{
|
|
int idx_number = 5;
|
|
int idx_ipv4 = 6;
|
|
if (argc == 7)
|
|
return ospf_vty_dead_interval_set(
|
|
vty, NULL, argv[idx_ipv4]->arg, argv[idx_number]->arg);
|
|
else
|
|
return ospf_vty_dead_interval_set(vty, NULL, NULL,
|
|
argv[idx_number]->arg);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_dead_interval,
|
|
no_ip_ospf_dead_interval_cmd,
|
|
"no ip ospf dead-interval [<(1-65535)|minimal hello-multiplier [(2-20)]> [A.B.C.D]]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Interval time after which a neighbor is declared down\n"
|
|
"Seconds\n"
|
|
"Minimal 1s dead-interval with fast sub-second hellos\n"
|
|
"Hello multiplier factor\n"
|
|
"Number of Hellos to send each second\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = argc - 1;
|
|
struct in_addr addr = {.s_addr = 0L};
|
|
int ret;
|
|
struct ospf_if_params *params;
|
|
struct ospf_interface *oi;
|
|
struct route_node *rn;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv[idx_ipv4]->type == IPV4_TKN) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, v_wait);
|
|
params->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
|
|
params->is_v_wait_set = false;
|
|
|
|
UNSET_IF_PARAM(params, fast_hello);
|
|
params->fast_hello = OSPF_FAST_HELLO_DEFAULT;
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
/* Update timer values in neighbor structure. */
|
|
if (argc == 1) {
|
|
struct ospf *ospf = NULL;
|
|
|
|
ospf = ifp->vrf->info;
|
|
if (ospf) {
|
|
oi = ospf_if_lookup_by_local_addr(ospf, ifp, addr);
|
|
if (oi)
|
|
ospf_nbr_timer_update(oi);
|
|
}
|
|
} else {
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
|
|
if ((oi = rn->info))
|
|
ospf_nbr_timer_update(oi);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_dead_interval,
|
|
no_ospf_dead_interval_cmd,
|
|
"no ospf dead-interval [<(1-65535)|minimal hello-multiplier (2-20)> [A.B.C.D]]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Interval time after which a neighbor is declared down\n"
|
|
"Seconds\n"
|
|
"Minimal 1s dead-interval with fast sub-second hellos\n"
|
|
"Hello multiplier factor\n"
|
|
"Number of Hellos to send each second\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_dead_interval(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_hello_interval,
|
|
ip_ospf_hello_interval_cmd,
|
|
"ip ospf hello-interval (1-65535) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Time between HELLO packets\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr = {.s_addr = 0L};
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
uint32_t seconds = 0;
|
|
bool is_addr = false;
|
|
uint32_t old_interval = 0;
|
|
|
|
argv_find(argv, argc, "(1-65535)", &idx);
|
|
seconds = strtol(argv[idx]->arg, NULL, 10);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
is_addr = true;
|
|
}
|
|
|
|
old_interval = params->v_hello;
|
|
|
|
/* Return, if same interval is configured. */
|
|
if (old_interval == seconds)
|
|
return CMD_SUCCESS;
|
|
|
|
SET_IF_PARAM(params, v_hello);
|
|
params->v_hello = seconds;
|
|
|
|
if (!params->is_v_wait_set) {
|
|
SET_IF_PARAM(params, v_wait);
|
|
/* As per RFC 4062
|
|
* The router dead interval should
|
|
* be some multiple of the HelloInterval (perhaps 4 times the
|
|
* hello interval) and must be the same for all routers
|
|
* attached to a common network.
|
|
*/
|
|
params->v_wait = 4 * seconds;
|
|
}
|
|
|
|
ospf_reset_hello_timer(ifp, addr, is_addr);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_hello_interval,
|
|
ospf_hello_interval_cmd,
|
|
"ospf hello-interval (1-65535) [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Time between HELLO packets\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_hello_interval(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_hello_interval,
|
|
no_ip_ospf_hello_interval_cmd,
|
|
"no ip ospf hello-interval [(1-65535) [A.B.C.D]]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Time between HELLO packets\n" // ignored
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr = {.s_addr = 0L};
|
|
struct ospf_if_params *params;
|
|
struct route_node *rn;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, v_hello);
|
|
params->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
|
|
|
|
if (!params->is_v_wait_set) {
|
|
UNSET_IF_PARAM(params, v_wait);
|
|
params->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (!oi)
|
|
continue;
|
|
|
|
oi->type = IF_DEF_PARAMS(ifp)->type;
|
|
oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
|
|
|
|
if (oi->state > ISM_Down) {
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
|
|
}
|
|
}
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_hello_interval,
|
|
no_ospf_hello_interval_cmd,
|
|
"no ospf hello-interval [(1-65535) [A.B.C.D]]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Time between HELLO packets\n" // ignored
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_hello_interval(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN(ip_ospf_network, ip_ospf_network_cmd,
|
|
"ip ospf network <broadcast|"
|
|
"non-broadcast|"
|
|
"point-to-multipoint [delay-reflood|non-broadcast]|"
|
|
"point-to-point [dmvpn]>",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Network type\n"
|
|
"Specify OSPF broadcast multi-access network\n"
|
|
"Specify OSPF NBMA network\n"
|
|
"Specify OSPF point-to-multipoint network\n"
|
|
"Specify OSPF delayed reflooding of LSAs received on P2MP interface\n"
|
|
"Specify OSPF point-to-multipoint network doesn't support broadcast\n"
|
|
"Specify OSPF point-to-point network\n"
|
|
"Specify OSPF point-to-point DMVPN network\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
int old_type = IF_DEF_PARAMS(ifp)->type;
|
|
uint8_t old_ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
|
|
uint8_t old_p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
|
|
uint8_t old_p2mp_non_broadcast = IF_DEF_PARAMS(ifp)->p2mp_non_broadcast;
|
|
struct route_node *rn;
|
|
|
|
if (old_type == OSPF_IFTYPE_LOOPBACK) {
|
|
vty_out(vty,
|
|
"This is a loopback interface. Can't set network type.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
|
|
IF_DEF_PARAMS(ifp)->p2mp_delay_reflood =
|
|
OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
|
|
IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = OSPF_P2MP_NON_BROADCAST_DEFAULT;
|
|
|
|
if (argv_find(argv, argc, "broadcast", &idx))
|
|
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST;
|
|
else if (argv_find(argv, argc, "point-to-multipoint", &idx)) {
|
|
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT;
|
|
if (argv_find(argv, argc, "delay-reflood", &idx))
|
|
IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = true;
|
|
if (argv_find(argv, argc, "non-broadcast", &idx))
|
|
IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = true;
|
|
} else if (argv_find(argv, argc, "non-broadcast", &idx))
|
|
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA;
|
|
else if (argv_find(argv, argc, "point-to-point", &idx)) {
|
|
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT;
|
|
if (argv_find(argv, argc, "dmvpn", &idx))
|
|
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 1;
|
|
}
|
|
|
|
IF_DEF_PARAMS(ifp)->type_cfg = true;
|
|
|
|
if (IF_DEF_PARAMS(ifp)->type == old_type &&
|
|
IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn &&
|
|
IF_DEF_PARAMS(ifp)->p2mp_delay_reflood == old_p2mp_delay_reflood &&
|
|
IF_DEF_PARAMS(ifp)->p2mp_non_broadcast == old_p2mp_non_broadcast)
|
|
return CMD_SUCCESS;
|
|
|
|
SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (!oi)
|
|
continue;
|
|
|
|
oi->type = IF_DEF_PARAMS(ifp)->type;
|
|
oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
|
|
oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
|
|
oi->p2mp_non_broadcast = IF_DEF_PARAMS(ifp)->p2mp_non_broadcast;
|
|
|
|
/*
|
|
* The OSPF interface only needs to be flapped if the network
|
|
* type or DMVPN parameter changes.
|
|
*/
|
|
if (IF_DEF_PARAMS(ifp)->type != old_type ||
|
|
IF_DEF_PARAMS(ifp)->ptp_dmvpn != old_ptp_dmvpn ||
|
|
IF_DEF_PARAMS(ifp)->p2mp_non_broadcast !=
|
|
old_p2mp_non_broadcast) {
|
|
if (oi->state > ISM_Down) {
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
|
|
}
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_network,
|
|
ospf_network_cmd,
|
|
"ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
|
|
"OSPF interface commands\n"
|
|
"Network type\n"
|
|
"Specify OSPF broadcast multi-access network\n"
|
|
"Specify OSPF NBMA network\n"
|
|
"Specify OSPF point-to-multipoint network\n"
|
|
"Specify OSPF point-to-point network\n")
|
|
{
|
|
return ip_ospf_network(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_network,
|
|
no_ip_ospf_network_cmd,
|
|
"no ip ospf network [<broadcast|non-broadcast|point-to-multipoint|point-to-point>]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Network type\n"
|
|
"Specify OSPF broadcast multi-access network\n"
|
|
"Specify OSPF NBMA network\n"
|
|
"Specify OSPF point-to-multipoint network\n"
|
|
"Specify OSPF point-to-point network\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int old_type = IF_DEF_PARAMS(ifp)->type;
|
|
struct route_node *rn;
|
|
|
|
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
|
|
IF_DEF_PARAMS(ifp)->type_cfg = false;
|
|
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
|
|
IF_DEF_PARAMS(ifp)->p2mp_delay_reflood =
|
|
OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
|
|
IF_DEF_PARAMS(ifp)->p2mp_non_broadcast = OSPF_P2MP_NON_BROADCAST_DEFAULT;
|
|
|
|
if (IF_DEF_PARAMS(ifp)->type == old_type)
|
|
return CMD_SUCCESS;
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (!oi)
|
|
continue;
|
|
|
|
oi->type = IF_DEF_PARAMS(ifp)->type;
|
|
oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
|
|
oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
|
|
|
|
if (oi->state > ISM_Down) {
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_network,
|
|
no_ospf_network_cmd,
|
|
"no ospf network [<broadcast|non-broadcast|point-to-multipoint|point-to-point>]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Network type\n"
|
|
"Specify OSPF broadcast multi-access network\n"
|
|
"Specify OSPF NBMA network\n"
|
|
"Specify OSPF point-to-multipoint network\n"
|
|
"Specify OSPF point-to-point network\n")
|
|
{
|
|
return no_ip_ospf_network(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_priority,
|
|
ip_ospf_priority_cmd,
|
|
"ip ospf priority (0-255) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Router priority\n"
|
|
"Priority\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
long priority;
|
|
struct route_node *rn;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
argv_find(argv, argc, "(0-255)", &idx);
|
|
priority = strtol(argv[idx]->arg, NULL, 10);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
SET_IF_PARAM(params, priority);
|
|
params->priority = priority;
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (!oi)
|
|
continue;
|
|
|
|
if (PRIORITY(oi) != OSPF_IF_PARAM(oi, priority)) {
|
|
PRIORITY(oi) = OSPF_IF_PARAM(oi, priority);
|
|
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_priority,
|
|
ospf_priority_cmd,
|
|
"ospf priority (0-255) [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Router priority\n"
|
|
"Priority\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_priority(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_priority,
|
|
no_ip_ospf_priority_cmd,
|
|
"no ip ospf priority [(0-255) [A.B.C.D]]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Router priority\n" // ignored
|
|
"Priority\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct route_node *rn;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, priority);
|
|
params->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (!oi)
|
|
continue;
|
|
|
|
if (PRIORITY(oi) != OSPF_IF_PARAM(oi, priority)) {
|
|
PRIORITY(oi) = OSPF_IF_PARAM(oi, priority);
|
|
OSPF_ISM_EVENT_SCHEDULE(oi, ISM_NeighborChange);
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_priority,
|
|
no_ospf_priority_cmd,
|
|
"no ospf priority [(0-255) [A.B.C.D]]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Router priority\n"
|
|
"Priority\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_priority(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_retransmit_interval,
|
|
ip_ospf_retransmit_interval_addr_cmd,
|
|
"ip ospf retransmit-interval (1-65535) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Time between retransmitting lost link state advertisements\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
uint32_t seconds;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
argv_find(argv, argc, "(1-65535)", &idx);
|
|
seconds = strtol(argv[idx]->arg, NULL, 10);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
SET_IF_PARAM(params, retransmit_interval);
|
|
params->retransmit_interval = seconds;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_retransmit_interval,
|
|
ospf_retransmit_interval_cmd,
|
|
"ospf retransmit-interval (1-65535) [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Time between retransmitting lost link state advertisements\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_retransmit_interval(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_retransmit_interval,
|
|
no_ip_ospf_retransmit_interval_addr_cmd,
|
|
"no ip ospf retransmit-interval [(1-65535)] [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Time between retransmitting lost link state advertisements\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, retransmit_interval);
|
|
params->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (no_ospf_retransmit_interval,
|
|
no_ospf_retransmit_interval_cmd,
|
|
"no ospf retransmit-interval [(1-65535)] [A.B.C.D]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Time between retransmitting lost link state advertisements\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_retransmit_interval(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFPY(ip_ospf_retransmit_window, ip_ospf_retransmit_window_addr_cmd,
|
|
"[no] ip ospf retransmit-window ![(20-1000)]$retransmit-window [A.B.C.D]$ip_addr", NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Window for LSA retransmit - Retransmit LSAs expiring in this window\n"
|
|
"Milliseconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (ip_addr.s_addr != INADDR_ANY) {
|
|
params = ospf_get_if_params(ifp, ip_addr);
|
|
ospf_if_update_params(ifp, ip_addr);
|
|
}
|
|
|
|
if (no) {
|
|
UNSET_IF_PARAM(params, retransmit_window);
|
|
params->retransmit_window = OSPF_RETRANSMIT_WINDOW_DEFAULT;
|
|
} else {
|
|
SET_IF_PARAM(params, retransmit_window);
|
|
params->retransmit_window = retransmit_window;
|
|
}
|
|
|
|
/*
|
|
* There is nothing to do when the retransmit-window changes, any
|
|
* change will take effect the next time the interface LSA retransmision
|
|
* timer expires.
|
|
*/
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (ip_ospf_gr_hdelay,
|
|
ip_ospf_gr_hdelay_cmd,
|
|
"ip ospf graceful-restart hello-delay (1-1800)",
|
|
IP_STR
|
|
"OSPF interface commands\n"
|
|
"Graceful Restart parameters\n"
|
|
"Delay the sending of the first hello packets.\n"
|
|
"Delay in seconds\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
/* Note: new or updated value won't affect ongoing graceful restart. */
|
|
SET_IF_PARAM(params, v_gr_hello_delay);
|
|
params->v_gr_hello_delay = hello_delay;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (no_ip_ospf_gr_hdelay,
|
|
no_ip_ospf_gr_hdelay_cmd,
|
|
"no ip ospf graceful-restart hello-delay [(1-1800)]",
|
|
NO_STR
|
|
IP_STR
|
|
"OSPF interface commands\n"
|
|
"Graceful Restart parameters\n"
|
|
"Delay the sending of the first hello packets.\n"
|
|
"Delay in seconds\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct ospf_if_params *params;
|
|
struct route_node *rn;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
UNSET_IF_PARAM(params, v_gr_hello_delay);
|
|
params->v_gr_hello_delay = OSPF_HELLO_DELAY_DEFAULT;
|
|
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi;
|
|
|
|
oi = rn->info;
|
|
if (!oi)
|
|
continue;
|
|
|
|
oi->gr.hello_delay.elapsed_seconds = 0;
|
|
EVENT_OFF(oi->gr.hello_delay.t_grace_send);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ip_ospf_transmit_delay,
|
|
ip_ospf_transmit_delay_addr_cmd,
|
|
"ip ospf transmit-delay (1-65535) [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Link state transmit delay\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
uint32_t seconds;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
argv_find(argv, argc, "(1-65535)", &idx);
|
|
seconds = strtol(argv[idx]->arg, NULL, 10);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
SET_IF_PARAM(params, transmit_delay);
|
|
params->transmit_delay = seconds;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN_HIDDEN (ospf_transmit_delay,
|
|
ospf_transmit_delay_cmd,
|
|
"ospf transmit-delay (1-65535) [A.B.C.D]",
|
|
"OSPF interface commands\n"
|
|
"Link state transmit delay\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return ip_ospf_transmit_delay(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_transmit_delay,
|
|
no_ip_ospf_transmit_delay_addr_cmd,
|
|
"no ip ospf transmit-delay [(1-65535)] [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Link state transmit delay\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argv_find(argv, argc, "A.B.C.D", &idx)) {
|
|
if (!inet_aton(argv[idx]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, transmit_delay);
|
|
params->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
|
|
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN_HIDDEN (no_ospf_transmit_delay,
|
|
no_ospf_transmit_delay_cmd,
|
|
"no ospf transmit-delay [(1-65535) [A.B.C.D]]",
|
|
NO_STR
|
|
"OSPF interface commands\n"
|
|
"Link state transmit delay\n"
|
|
"Seconds\n"
|
|
"Address of interface\n")
|
|
{
|
|
return no_ip_ospf_transmit_delay(self, vty, argc, argv);
|
|
}
|
|
|
|
DEFUN (ip_ospf_area,
|
|
ip_ospf_area_cmd,
|
|
"ip ospf [(1-65535)] area <A.B.C.D|(0-4294967295)> [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Instance ID\n"
|
|
"Enable OSPF on this interface\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
int format, ret;
|
|
struct in_addr area_id;
|
|
struct in_addr addr;
|
|
struct ospf_if_params *params = NULL;
|
|
struct route_node *rn;
|
|
struct ospf *ospf = NULL;
|
|
unsigned short instance = 0;
|
|
char *areaid;
|
|
uint32_t count = 0;
|
|
|
|
if (argv_find(argv, argc, "(1-65535)", &idx))
|
|
instance = strtol(argv[idx]->arg, NULL, 10);
|
|
|
|
argv_find(argv, argc, "area", &idx);
|
|
areaid = argv[idx + 1]->arg;
|
|
|
|
if (!instance)
|
|
ospf = ifp->vrf->info;
|
|
else
|
|
ospf = ospf_lookup_instance(instance);
|
|
|
|
if (instance && instance != ospf_instance) {
|
|
/*
|
|
* At this point we know we have received
|
|
* an instance and there is no ospf instance
|
|
* associated with it. This means we are
|
|
* in a situation where we have an
|
|
* ospf command that is setup for a different
|
|
* process(instance). We need to safely
|
|
* remove the command from ourselves and
|
|
* allow the other instance(process) handle
|
|
* the configuration command.
|
|
*/
|
|
count = 0;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
|
|
UNSET_IF_PARAM(params, if_area);
|
|
count++;
|
|
}
|
|
|
|
for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
|
|
if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
|
|
UNSET_IF_PARAM(params, if_area);
|
|
count++;
|
|
}
|
|
|
|
if (count > 0) {
|
|
ospf = ifp->vrf->info;
|
|
if (ospf)
|
|
ospf_interface_area_unset(ospf, ifp);
|
|
}
|
|
|
|
return CMD_NOT_MY_INSTANCE;
|
|
}
|
|
|
|
ret = str2area_id(areaid, &area_id, &format);
|
|
if (ret < 0) {
|
|
vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
if (memcmp(ifp->name, "VLINK", 5) == 0) {
|
|
vty_out(vty, "Cannot enable OSPF on a virtual link.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (ospf) {
|
|
for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
|
|
if (rn->info != NULL) {
|
|
vty_out(vty,
|
|
"Please remove all network commands first.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
}
|
|
}
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)
|
|
&& !IPV4_ADDR_SAME(¶ms->if_area, &area_id)) {
|
|
vty_out(vty,
|
|
"Must remove previous area config before changing ospf area \n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
// Check if we have an address arg and proccess it
|
|
if (argc == idx + 3) {
|
|
if (!inet_aton(argv[idx + 2]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify Intf Address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
// update/create address-level params
|
|
params = ospf_get_if_params((ifp), (addr));
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
|
|
if (!IPV4_ADDR_SAME(¶ms->if_area, &area_id)) {
|
|
vty_out(vty,
|
|
"Must remove previous area/address config before changing ospf area\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
} else
|
|
return CMD_SUCCESS;
|
|
}
|
|
ospf_if_update_params((ifp), (addr));
|
|
}
|
|
|
|
/* enable ospf on this interface with area_id */
|
|
if (params) {
|
|
SET_IF_PARAM(params, if_area);
|
|
params->if_area = area_id;
|
|
params->if_area_id_fmt = format;
|
|
}
|
|
|
|
if (ospf)
|
|
ospf_interface_area_set(ospf, ifp);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_area,
|
|
no_ip_ospf_area_cmd,
|
|
"no ip ospf [(1-65535)] area [<A.B.C.D|(0-4294967295)> [A.B.C.D]]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Instance ID\n"
|
|
"Disable OSPF on this interface\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx = 0;
|
|
struct ospf *ospf;
|
|
struct ospf_if_params *params;
|
|
unsigned short instance = 0;
|
|
struct in_addr addr;
|
|
struct in_addr area_id;
|
|
|
|
if (argv_find(argv, argc, "(1-65535)", &idx))
|
|
instance = strtol(argv[idx]->arg, NULL, 10);
|
|
|
|
if (!instance)
|
|
ospf = ifp->vrf->info;
|
|
else
|
|
ospf = ospf_lookup_instance(instance);
|
|
|
|
if (instance && instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
argv_find(argv, argc, "area", &idx);
|
|
|
|
// Check if we have an address arg and proccess it
|
|
if (argc == idx + 3) {
|
|
if (!inet_aton(argv[idx + 2]->arg, &addr)) {
|
|
vty_out(vty,
|
|
"Please specify Intf Address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if ((params) == NULL)
|
|
return CMD_SUCCESS;
|
|
} else
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
area_id = params->if_area;
|
|
if (!OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
|
|
vty_out(vty,
|
|
"Can't find specified interface area configuration.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
UNSET_IF_PARAM(params, if_area);
|
|
if (params != IF_DEF_PARAMS((ifp))) {
|
|
ospf_free_if_params((ifp), (addr));
|
|
ospf_if_update_params((ifp), (addr));
|
|
}
|
|
|
|
if (ospf) {
|
|
ospf_interface_area_unset(ospf, ifp);
|
|
ospf_area_check_free(ospf, area_id);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ip_ospf_passive,
|
|
ip_ospf_passive_cmd,
|
|
"ip ospf passive [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Suppress routing updates on an interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = 3;
|
|
struct in_addr addr = {.s_addr = INADDR_ANY};
|
|
struct ospf_if_params *params;
|
|
int ret;
|
|
|
|
if (argc == 4) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
} else {
|
|
params = IF_DEF_PARAMS(ifp);
|
|
}
|
|
|
|
ospf_passive_interface_update(ifp, params, addr, OSPF_IF_PASSIVE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_passive,
|
|
no_ip_ospf_passive_cmd,
|
|
"no ip ospf passive [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Enable routing updates on an interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = 4;
|
|
struct in_addr addr = {.s_addr = INADDR_ANY};
|
|
struct ospf_if_params *params;
|
|
int ret;
|
|
|
|
if (argc == 5) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params = ospf_lookup_if_params(ifp, addr);
|
|
if (params == NULL)
|
|
return CMD_SUCCESS;
|
|
} else {
|
|
params = IF_DEF_PARAMS(ifp);
|
|
}
|
|
|
|
ospf_passive_interface_update(ifp, params, addr, OSPF_IF_ACTIVE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_redistribute_source,
|
|
ospf_redistribute_source_cmd,
|
|
"redistribute " FRR_REDIST_STR_OSPFD " [{metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]",
|
|
REDIST_STR
|
|
FRR_REDIST_HELP_STR_OSPFD
|
|
"Metric for redistributed routes\n"
|
|
"OSPF default metric\n"
|
|
"OSPF exterior metric type for redistributed routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Route map reference\n"
|
|
"Pointer to route-map entries\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_protocol = 1;
|
|
int source;
|
|
int type = -1;
|
|
int metric = -1;
|
|
struct ospf_redist *red;
|
|
int idx = 0;
|
|
bool update = false;
|
|
|
|
/* Get distribute source. */
|
|
source = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
|
|
if (source < 0)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
/* Get metric value. */
|
|
if (argv_find(argv, argc, "(0-16777214)", &idx)) {
|
|
if (!str2metric(argv[idx]->arg, &metric))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
idx = 1;
|
|
/* Get metric type. */
|
|
if (argv_find(argv, argc, "(1-2)", &idx)) {
|
|
if (!str2metric_type(argv[idx]->arg, &type))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
idx = 1;
|
|
|
|
red = ospf_redist_lookup(ospf, source, 0);
|
|
if (!red)
|
|
red = ospf_redist_add(ospf, source, 0);
|
|
else
|
|
update = true;
|
|
|
|
/* Get route-map */
|
|
if (argv_find(argv, argc, "route-map", &idx)) {
|
|
ospf_routemap_set(red, argv[idx + 1]->arg);
|
|
} else
|
|
ospf_routemap_unset(red);
|
|
|
|
if (update)
|
|
return ospf_redistribute_update(ospf, red, source, 0, type,
|
|
metric);
|
|
else
|
|
return ospf_redistribute_set(ospf, red, source, 0, type,
|
|
metric);
|
|
}
|
|
|
|
DEFUN (no_ospf_redistribute_source,
|
|
no_ospf_redistribute_source_cmd,
|
|
"no redistribute " FRR_REDIST_STR_OSPFD " [{metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]",
|
|
NO_STR
|
|
REDIST_STR
|
|
FRR_REDIST_HELP_STR_OSPFD
|
|
"Metric for redistributed routes\n"
|
|
"OSPF default metric\n"
|
|
"OSPF exterior metric type for redistributed routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Route map reference\n"
|
|
"Pointer to route-map entries\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_protocol = 2;
|
|
int source;
|
|
struct ospf_redist *red;
|
|
|
|
source = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
|
|
if (source < 0)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
red = ospf_redist_lookup(ospf, source, 0);
|
|
if (!red)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf_routemap_unset(red);
|
|
ospf_redist_del(ospf, source, 0);
|
|
|
|
return ospf_redistribute_unset(ospf, source, 0);
|
|
}
|
|
|
|
DEFUN (ospf_redistribute_instance_source,
|
|
ospf_redistribute_instance_source_cmd,
|
|
"redistribute <ospf|table> (1-65535) [{metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]",
|
|
REDIST_STR
|
|
"Open Shortest Path First\n"
|
|
"Non-main Kernel Routing Table\n"
|
|
"Instance ID/Table ID\n"
|
|
"Metric for redistributed routes\n"
|
|
"OSPF default metric\n"
|
|
"OSPF exterior metric type for redistributed routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Route map reference\n"
|
|
"Pointer to route-map entries\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ospf_table = 1;
|
|
int idx_number = 2;
|
|
int idx = 3;
|
|
int source;
|
|
int type = -1;
|
|
int metric = -1;
|
|
unsigned short instance;
|
|
struct ospf_redist *red;
|
|
bool update = false;
|
|
|
|
source = proto_redistnum(AFI_IP, argv[idx_ospf_table]->text);
|
|
|
|
if (source < 0) {
|
|
vty_out(vty, "Unknown instance redistribution\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) {
|
|
vty_out(vty,
|
|
"Instance redistribution in non-instanced OSPF not allowed\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) {
|
|
vty_out(vty, "Same instance OSPF redistribution not allowed\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* Get metric value. */
|
|
if (argv_find(argv, argc, "metric", &idx))
|
|
if (!str2metric(argv[idx + 1]->arg, &metric))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
idx = 3;
|
|
/* Get metric type. */
|
|
if (argv_find(argv, argc, "metric-type", &idx))
|
|
if (!str2metric_type(argv[idx + 1]->arg, &type))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
red = ospf_redist_lookup(ospf, source, instance);
|
|
if (!red)
|
|
red = ospf_redist_add(ospf, source, instance);
|
|
else
|
|
update = true;
|
|
|
|
idx = 3;
|
|
if (argv_find(argv, argc, "route-map", &idx))
|
|
ospf_routemap_set(red, argv[idx + 1]->arg);
|
|
else
|
|
ospf_routemap_unset(red);
|
|
|
|
if (update)
|
|
return ospf_redistribute_update(ospf, red, source, instance,
|
|
type, metric);
|
|
else
|
|
return ospf_redistribute_set(ospf, red, source, instance, type,
|
|
metric);
|
|
}
|
|
|
|
DEFUN (no_ospf_redistribute_instance_source,
|
|
no_ospf_redistribute_instance_source_cmd,
|
|
"no redistribute <ospf|table> (1-65535) [{metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]",
|
|
NO_STR
|
|
REDIST_STR
|
|
"Open Shortest Path First\n"
|
|
"Non-main Kernel Routing Table\n"
|
|
"Instance ID/Table Id\n"
|
|
"Metric for redistributed routes\n"
|
|
"OSPF default metric\n"
|
|
"OSPF exterior metric type for redistributed routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Route map reference\n"
|
|
"Pointer to route-map entries\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_ospf_table = 2;
|
|
int idx_number = 3;
|
|
unsigned int instance;
|
|
struct ospf_redist *red;
|
|
int source;
|
|
|
|
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
|
|
source = ZEBRA_ROUTE_OSPF;
|
|
else
|
|
source = ZEBRA_ROUTE_TABLE;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) {
|
|
vty_out(vty,
|
|
"Instance redistribution in non-instanced OSPF not allowed\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if ((source == ZEBRA_ROUTE_OSPF) && (ospf->instance == instance)) {
|
|
vty_out(vty, "Same instance OSPF redistribution not allowed\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
red = ospf_redist_lookup(ospf, source, instance);
|
|
if (!red)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf_routemap_unset(red);
|
|
ospf_redist_del(ospf, source, instance);
|
|
|
|
return ospf_redistribute_unset(ospf, source, instance);
|
|
}
|
|
|
|
DEFUN (ospf_distribute_list_out,
|
|
ospf_distribute_list_out_cmd,
|
|
"distribute-list ACCESSLIST4_NAME out " FRR_REDIST_STR_OSPFD,
|
|
"Filter networks in routing updates\n"
|
|
"Access-list name\n"
|
|
OUT_STR
|
|
FRR_REDIST_HELP_STR_OSPFD)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_word = 1;
|
|
int source;
|
|
|
|
char *proto = argv[argc - 1]->text;
|
|
|
|
/* Get distribute source. */
|
|
source = proto_redistnum(AFI_IP, proto);
|
|
if (source < 0)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
return ospf_distribute_list_out_set(ospf, source, argv[idx_word]->arg);
|
|
}
|
|
|
|
DEFUN (no_ospf_distribute_list_out,
|
|
no_ospf_distribute_list_out_cmd,
|
|
"no distribute-list ACCESSLIST4_NAME out " FRR_REDIST_STR_OSPFD,
|
|
NO_STR
|
|
"Filter networks in routing updates\n"
|
|
"Access-list name\n"
|
|
OUT_STR
|
|
FRR_REDIST_HELP_STR_OSPFD)
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_word = 2;
|
|
int source;
|
|
|
|
char *proto = argv[argc - 1]->text;
|
|
source = proto_redistnum(AFI_IP, proto);
|
|
if (source < 0)
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
return ospf_distribute_list_out_unset(ospf, source,
|
|
argv[idx_word]->arg);
|
|
}
|
|
|
|
/* Default information originate. */
|
|
DEFUN (ospf_default_information_originate,
|
|
ospf_default_information_originate_cmd,
|
|
"default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]",
|
|
"Control distribution of default information\n"
|
|
"Distribute a default route\n"
|
|
"Always advertise default route\n"
|
|
"OSPF default metric\n"
|
|
"OSPF metric\n"
|
|
"OSPF metric type for default routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Route map reference\n"
|
|
"Pointer to route-map entries\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int default_originate = DEFAULT_ORIGINATE_ZEBRA;
|
|
int type = -1;
|
|
int metric = -1;
|
|
struct ospf_redist *red;
|
|
int idx = 0;
|
|
int cur_originate = ospf->default_originate;
|
|
bool sameRtmap = false;
|
|
char *rtmap = NULL;
|
|
|
|
red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
|
|
|
|
/* Check whether "always" was specified */
|
|
if (argv_find(argv, argc, "always", &idx))
|
|
default_originate = DEFAULT_ORIGINATE_ALWAYS;
|
|
idx = 1;
|
|
/* Get metric value */
|
|
if (argv_find(argv, argc, "(0-16777214)", &idx)) {
|
|
if (!str2metric(argv[idx]->arg, &metric))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
idx = 1;
|
|
/* Get metric type. */
|
|
if (argv_find(argv, argc, "(1-2)", &idx)) {
|
|
if (!str2metric_type(argv[idx]->arg, &type))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
idx = 1;
|
|
/* Get route-map */
|
|
if (argv_find(argv, argc, "route-map", &idx))
|
|
rtmap = argv[idx + 1]->arg;
|
|
|
|
/* To check if user is providing same route map */
|
|
if ((!rtmap && !ROUTEMAP_NAME(red)) ||
|
|
(rtmap && ROUTEMAP_NAME(red) &&
|
|
(strcmp(rtmap, ROUTEMAP_NAME(red)) == 0)))
|
|
sameRtmap = true;
|
|
|
|
/* Don't allow if the same lsa is already originated. */
|
|
if ((sameRtmap)
|
|
&& (red->dmetric.type == type)
|
|
&& (red->dmetric.value == metric)
|
|
&& (cur_originate == default_originate))
|
|
return CMD_SUCCESS;
|
|
|
|
/* Updating Metric details */
|
|
red->dmetric.type = type;
|
|
red->dmetric.value = metric;
|
|
|
|
/* updating route map details */
|
|
if (rtmap)
|
|
ospf_routemap_set(red, rtmap);
|
|
else
|
|
ospf_routemap_unset(red);
|
|
|
|
return ospf_redistribute_default_set(ospf, default_originate, type,
|
|
metric);
|
|
}
|
|
|
|
DEFUN (no_ospf_default_information_originate,
|
|
no_ospf_default_information_originate_cmd,
|
|
"no default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map RMAP_NAME}]",
|
|
NO_STR
|
|
"Control distribution of default information\n"
|
|
"Distribute a default route\n"
|
|
"Always advertise default route\n"
|
|
"OSPF default metric\n"
|
|
"OSPF metric\n"
|
|
"OSPF metric type for default routes\n"
|
|
"Set OSPF External Type 1/2 metrics\n"
|
|
"Route map reference\n"
|
|
"Pointer to route-map entries\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct ospf_redist *red;
|
|
|
|
red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
|
|
if (!red)
|
|
return CMD_SUCCESS;
|
|
|
|
ospf_routemap_unset(red);
|
|
ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
|
|
|
|
return ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE,
|
|
0, 0);
|
|
}
|
|
|
|
DEFUN (ospf_default_metric,
|
|
ospf_default_metric_cmd,
|
|
"default-metric (0-16777214)",
|
|
"Set metric of redistributed routes\n"
|
|
"Default metric\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 1;
|
|
int metric = -1;
|
|
|
|
if (!str2metric(argv[idx_number]->arg, &metric))
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
ospf->default_metric = metric;
|
|
|
|
ospf_schedule_asbr_redist_update(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_default_metric,
|
|
no_ospf_default_metric_cmd,
|
|
"no default-metric [(0-16777214)]",
|
|
NO_STR
|
|
"Set metric of redistributed routes\n"
|
|
"Default metric\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->default_metric = -1;
|
|
|
|
ospf_schedule_asbr_redist_update(ospf);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_distance,
|
|
ospf_distance_cmd,
|
|
"distance (1-255)",
|
|
"Administrative distance\n"
|
|
"OSPF Administrative distance\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 1;
|
|
uint8_t distance;
|
|
|
|
distance = atoi(argv[idx_number]->arg);
|
|
if (ospf->distance_all != distance) {
|
|
ospf->distance_all = distance;
|
|
ospf_restart_spf(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_distance,
|
|
no_ospf_distance_cmd,
|
|
"no distance (1-255)",
|
|
NO_STR
|
|
"Administrative distance\n"
|
|
"OSPF Administrative distance\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (ospf->distance_all) {
|
|
ospf->distance_all = 0;
|
|
ospf_restart_spf(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_distance_ospf,
|
|
no_ospf_distance_ospf_cmd,
|
|
"no distance ospf [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
|
|
NO_STR
|
|
"Administrative distance\n"
|
|
"OSPF administrative distance\n"
|
|
"Intra-area routes\n"
|
|
"Distance for intra-area routes\n"
|
|
"Inter-area routes\n"
|
|
"Distance for inter-area routes\n"
|
|
"External routes\n"
|
|
"Distance for external routes\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx = 0;
|
|
|
|
if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
|
|
idx = ospf->distance_intra = 0;
|
|
if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
|
|
idx = ospf->distance_inter = 0;
|
|
if (argv_find(argv, argc, "external", &idx) || argc == 3)
|
|
ospf->distance_external = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_distance_ospf,
|
|
ospf_distance_ospf_cmd,
|
|
"distance ospf {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
|
|
"Administrative distance\n"
|
|
"OSPF administrative distance\n"
|
|
"Intra-area routes\n"
|
|
"Distance for intra-area routes\n"
|
|
"Inter-area routes\n"
|
|
"Distance for inter-area routes\n"
|
|
"External routes\n"
|
|
"Distance for external routes\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx = 0;
|
|
|
|
ospf->distance_intra = 0;
|
|
ospf->distance_inter = 0;
|
|
ospf->distance_external = 0;
|
|
|
|
if (argv_find(argv, argc, "intra-area", &idx))
|
|
ospf->distance_intra = atoi(argv[idx + 1]->arg);
|
|
idx = 0;
|
|
if (argv_find(argv, argc, "inter-area", &idx))
|
|
ospf->distance_inter = atoi(argv[idx + 1]->arg);
|
|
idx = 0;
|
|
if (argv_find(argv, argc, "external", &idx))
|
|
ospf->distance_external = atoi(argv[idx + 1]->arg);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ip_ospf_mtu_ignore,
|
|
ip_ospf_mtu_ignore_addr_cmd,
|
|
"ip ospf mtu-ignore [A.B.C.D]",
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Disable MTU mismatch detection on this interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = 3;
|
|
struct in_addr addr;
|
|
int ret;
|
|
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argc == 4) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
params->mtu_ignore = 1;
|
|
if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT)
|
|
SET_IF_PARAM(params, mtu_ignore);
|
|
else {
|
|
UNSET_IF_PARAM(params, mtu_ignore);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ip_ospf_mtu_ignore,
|
|
no_ip_ospf_mtu_ignore_addr_cmd,
|
|
"no ip ospf mtu-ignore [A.B.C.D]",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Disable MTU mismatch detection on this interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
int idx_ipv4 = 4;
|
|
struct in_addr addr;
|
|
int ret;
|
|
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (argc == 5) {
|
|
ret = inet_aton(argv[idx_ipv4]->arg, &addr);
|
|
if (!ret) {
|
|
vty_out(vty,
|
|
"Please specify interface address by A.B.C.D\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
params = ospf_get_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
params->mtu_ignore = 0;
|
|
if (params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT)
|
|
SET_IF_PARAM(params, mtu_ignore);
|
|
else {
|
|
UNSET_IF_PARAM(params, mtu_ignore);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, addr);
|
|
ospf_if_update_params(ifp, addr);
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ip_ospf_capability_opaque, ip_ospf_capability_opaque_addr_cmd,
|
|
"[no] ip ospf capability opaque [A.B.C.D]$ip_addr",
|
|
NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Disable OSPF capability on this interface\n"
|
|
"Disable OSPF opaque LSA capability on this interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct route_node *rn;
|
|
bool old_opaque_capable;
|
|
bool opaque_capable_change;
|
|
|
|
struct ospf_if_params *params;
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (ip_addr.s_addr != INADDR_ANY) {
|
|
params = ospf_get_if_params(ifp, ip_addr);
|
|
ospf_if_update_params(ifp, ip_addr);
|
|
}
|
|
|
|
old_opaque_capable = params->opaque_capable;
|
|
params->opaque_capable = (no) ? false : true;
|
|
opaque_capable_change = (old_opaque_capable != params->opaque_capable);
|
|
if (params->opaque_capable != OSPF_OPAQUE_CAPABLE_DEFAULT)
|
|
SET_IF_PARAM(params, opaque_capable);
|
|
else {
|
|
UNSET_IF_PARAM(params, opaque_capable);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, ip_addr);
|
|
ospf_if_update_params(ifp, ip_addr);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If there is a change to the opaque capability, flap the interface
|
|
* to reset all the neighbor adjacencies.
|
|
*/
|
|
if (opaque_capable_change) {
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (oi && (oi->state > ISM_Down) &&
|
|
(ip_addr.s_addr == INADDR_ANY ||
|
|
IPV4_ADDR_SAME(&oi->address->u.prefix4,
|
|
&ip_addr))) {
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
|
|
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
|
|
}
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFPY(ip_ospf_prefix_suppression, ip_ospf_prefix_suppression_addr_cmd,
|
|
"[no] ip ospf prefix-suppression [A.B.C.D]$ip_addr", NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Suppress OSPF prefix advertisement on this interface\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct route_node *rn;
|
|
bool prefix_suppression_change;
|
|
struct ospf_if_params *params;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (ip_addr.s_addr != INADDR_ANY) {
|
|
params = ospf_get_if_params(ifp, ip_addr);
|
|
ospf_if_update_params(ifp, ip_addr);
|
|
}
|
|
|
|
prefix_suppression_change = (params->prefix_suppression == (bool)no);
|
|
params->prefix_suppression = (no) ? false : true;
|
|
if (params->prefix_suppression != OSPF_PREFIX_SUPPRESSION_DEFAULT)
|
|
SET_IF_PARAM(params, prefix_suppression);
|
|
else {
|
|
UNSET_IF_PARAM(params, prefix_suppression);
|
|
if (params != IF_DEF_PARAMS(ifp)) {
|
|
ospf_free_if_params(ifp, ip_addr);
|
|
ospf_if_update_params(ifp, ip_addr);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If there is a change to the prefix suppression, update the Router-LSA.
|
|
*/
|
|
if (prefix_suppression_change) {
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (oi && (oi->state > ISM_Down) &&
|
|
(ip_addr.s_addr == INADDR_ANY ||
|
|
IPV4_ADDR_SAME(&oi->address->u.prefix4, &ip_addr))) {
|
|
(void)ospf_router_lsa_update_area(oi->area);
|
|
if (oi->state == ISM_DR)
|
|
ospf_network_lsa_update(oi);
|
|
}
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ip_ospf_neighbor_filter, ip_ospf_neighbor_filter_addr_cmd,
|
|
"[no] ip ospf neighbor-filter ![PREFIXLIST4_NAME]$prefix_list [A.B.C.D]$ip_addr", NO_STR
|
|
"IP Information\n"
|
|
"OSPF interface commands\n"
|
|
"Filter OSPF neighbor packets\n"
|
|
"Prefix-List used for filtering\n"
|
|
"Address of interface\n")
|
|
{
|
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
struct ospf_if_params *params;
|
|
struct prefix_list *nbr_filter = NULL;
|
|
struct route_node *rn;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
if (ip_addr.s_addr != INADDR_ANY) {
|
|
params = ospf_get_if_params(ifp, ip_addr);
|
|
ospf_if_update_params(ifp, ip_addr);
|
|
}
|
|
|
|
if (params->nbr_filter_name)
|
|
XFREE(MTYPE_OSPF_IF_PARAMS, params->nbr_filter_name);
|
|
|
|
if (no) {
|
|
UNSET_IF_PARAM(params, nbr_filter_name);
|
|
params->nbr_filter_name = NULL;
|
|
} else {
|
|
SET_IF_PARAM(params, nbr_filter_name);
|
|
params->nbr_filter_name = XSTRDUP(MTYPE_OSPF_IF_PARAMS,
|
|
prefix_list);
|
|
nbr_filter = prefix_list_lookup(AFI_IP, params->nbr_filter_name);
|
|
}
|
|
|
|
/*
|
|
* Determine if there is a change in neighbor filter prefix-list for the
|
|
* interface.
|
|
*/
|
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
|
struct ospf_interface *oi = rn->info;
|
|
|
|
if (oi &&
|
|
(ip_addr.s_addr == INADDR_ANY ||
|
|
IPV4_ADDR_SAME(&oi->address->u.prefix4, &ip_addr)) &&
|
|
oi->nbr_filter != nbr_filter) {
|
|
oi->nbr_filter = nbr_filter;
|
|
if (oi->nbr_filter)
|
|
ospf_intf_neighbor_filter_apply(oi);
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_max_metric_router_lsa_admin,
|
|
ospf_max_metric_router_lsa_admin_cmd,
|
|
"max-metric router-lsa administrative",
|
|
"OSPF maximum / infinite-distance metric\n"
|
|
"Advertise own Router-LSA with infinite distance (stub router)\n"
|
|
"Administratively applied, for an indefinite period\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct listnode *ln;
|
|
struct ospf_area *area;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
|
|
SET_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
|
|
|
|
if (!CHECK_FLAG(area->stub_router_state,
|
|
OSPF_AREA_IS_STUB_ROUTED))
|
|
ospf_router_lsa_update_area(area);
|
|
}
|
|
|
|
/* Allows for areas configured later to get the property */
|
|
ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_SET;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_max_metric_router_lsa_admin,
|
|
no_ospf_max_metric_router_lsa_admin_cmd,
|
|
"no max-metric router-lsa administrative",
|
|
NO_STR
|
|
"OSPF maximum / infinite-distance metric\n"
|
|
"Advertise own Router-LSA with infinite distance (stub router)\n"
|
|
"Administratively applied, for an indefinite period\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct listnode *ln;
|
|
struct ospf_area *area;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
|
|
UNSET_FLAG(area->stub_router_state,
|
|
OSPF_AREA_ADMIN_STUB_ROUTED);
|
|
|
|
/* Don't trample on the start-up stub timer */
|
|
if (CHECK_FLAG(area->stub_router_state,
|
|
OSPF_AREA_IS_STUB_ROUTED)
|
|
&& !area->t_stub_router) {
|
|
UNSET_FLAG(area->stub_router_state,
|
|
OSPF_AREA_IS_STUB_ROUTED);
|
|
ospf_router_lsa_update_area(area);
|
|
}
|
|
}
|
|
ospf->stub_router_admin_set = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_max_metric_router_lsa_startup,
|
|
ospf_max_metric_router_lsa_startup_cmd,
|
|
"max-metric router-lsa on-startup (5-86400)",
|
|
"OSPF maximum / infinite-distance metric\n"
|
|
"Advertise own Router-LSA with infinite distance (stub router)\n"
|
|
"Automatically advertise stub Router-LSA on startup of OSPF\n"
|
|
"Time (seconds) to advertise self as stub-router\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 3;
|
|
unsigned int seconds;
|
|
|
|
if (argc < 4) {
|
|
vty_out(vty, "%% Must supply stub-router period\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
seconds = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
ospf->stub_router_startup_time = seconds;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_max_metric_router_lsa_startup,
|
|
no_ospf_max_metric_router_lsa_startup_cmd,
|
|
"no max-metric router-lsa on-startup [(5-86400)]",
|
|
NO_STR
|
|
"OSPF maximum / infinite-distance metric\n"
|
|
"Advertise own Router-LSA with infinite distance (stub router)\n"
|
|
"Automatically advertise stub Router-LSA on startup of OSPF\n"
|
|
"Time (seconds) to advertise self as stub-router\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct listnode *ln;
|
|
struct ospf_area *area;
|
|
|
|
ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
|
|
SET_FLAG(area->stub_router_state,
|
|
OSPF_AREA_WAS_START_STUB_ROUTED);
|
|
EVENT_OFF(area->t_stub_router);
|
|
|
|
/* Don't trample on admin stub routed */
|
|
if (!CHECK_FLAG(area->stub_router_state,
|
|
OSPF_AREA_ADMIN_STUB_ROUTED)) {
|
|
UNSET_FLAG(area->stub_router_state,
|
|
OSPF_AREA_IS_STUB_ROUTED);
|
|
ospf_router_lsa_update_area(area);
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
|
|
DEFUN (ospf_max_metric_router_lsa_shutdown,
|
|
ospf_max_metric_router_lsa_shutdown_cmd,
|
|
"max-metric router-lsa on-shutdown (5-100)",
|
|
"OSPF maximum / infinite-distance metric\n"
|
|
"Advertise own Router-LSA with infinite distance (stub router)\n"
|
|
"Advertise stub-router prior to full shutdown of OSPF\n"
|
|
"Time (seconds) to wait till full shutdown\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
int idx_number = 3;
|
|
unsigned int seconds;
|
|
|
|
if (argc < 4) {
|
|
vty_out(vty, "%% Must supply stub-router shutdown period\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
seconds = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
|
|
ospf->stub_router_shutdown_time = seconds;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_max_metric_router_lsa_shutdown,
|
|
no_ospf_max_metric_router_lsa_shutdown_cmd,
|
|
"no max-metric router-lsa on-shutdown [(5-100)]",
|
|
NO_STR
|
|
"OSPF maximum / infinite-distance metric\n"
|
|
"Advertise own Router-LSA with infinite distance (stub router)\n"
|
|
"Advertise stub-router prior to full shutdown of OSPF\n"
|
|
"Time (seconds) to wait till full shutdown\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_proactive_arp,
|
|
ospf_proactive_arp_cmd,
|
|
"proactive-arp",
|
|
"Allow sending ARP requests proactively\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->proactive_arp = true;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_proactive_arp,
|
|
no_ospf_proactive_arp_cmd,
|
|
"no proactive-arp",
|
|
NO_STR
|
|
"Disallow sending ARP requests proactively\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf->proactive_arp = false;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Graceful Restart HELPER Commands */
|
|
DEFPY(ospf_gr_helper_enable, ospf_gr_helper_enable_cmd,
|
|
"graceful-restart helper enable [A.B.C.D$address]",
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Enable Helper support\n"
|
|
"Advertising Router-ID\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (address_str) {
|
|
ospf_gr_helper_support_set_per_routerid(ospf, &address,
|
|
OSPF_GR_TRUE);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(no_ospf_gr_helper_enable,
|
|
no_ospf_gr_helper_enable_cmd,
|
|
"no graceful-restart helper enable [A.B.C.D$address]",
|
|
NO_STR
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Enable Helper support\n"
|
|
"Advertising Router-ID\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
if (address_str) {
|
|
ospf_gr_helper_support_set_per_routerid(ospf, &address,
|
|
OSPF_GR_FALSE);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_gr_helper_support_set(ospf, OSPF_GR_FALSE);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ospf_gr_helper_enable_lsacheck,
|
|
ospf_gr_helper_enable_lsacheck_cmd,
|
|
"graceful-restart helper strict-lsa-checking",
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Enable strict LSA check\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_TRUE);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(no_ospf_gr_helper_enable_lsacheck,
|
|
no_ospf_gr_helper_enable_lsacheck_cmd,
|
|
"no graceful-restart helper strict-lsa-checking",
|
|
NO_STR
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Disable strict LSA check\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_FALSE);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ospf_gr_helper_supported_grace_time,
|
|
ospf_gr_helper_supported_grace_time_cmd,
|
|
"graceful-restart helper supported-grace-time (10-1800)$interval",
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Supported grace timer\n"
|
|
"Grace interval(in seconds)\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_gr_helper_supported_gracetime_set(ospf, interval);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(no_ospf_gr_helper_supported_grace_time,
|
|
no_ospf_gr_helper_supported_grace_time_cmd,
|
|
"no graceful-restart helper supported-grace-time (10-1800)$interval",
|
|
NO_STR
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Supported grace timer\n"
|
|
"Grace interval(in seconds)\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_gr_helper_supported_gracetime_set(ospf, OSPF_MAX_GRACE_INTERVAL);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ospf_gr_helper_planned_only,
|
|
ospf_gr_helper_planned_only_cmd,
|
|
"graceful-restart helper planned-only",
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Supported only planned restart\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_TRUE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* External Route Aggregation */
|
|
DEFUN (ospf_external_route_aggregation,
|
|
ospf_external_route_aggregation_cmd,
|
|
"summary-address A.B.C.D/M [tag (1-4294967295)]",
|
|
"External summary address\n"
|
|
"Summary address prefix\n"
|
|
"Router tag \n"
|
|
"Router tag value\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct prefix_ipv4 p;
|
|
int idx = 1;
|
|
route_tag_t tag = 0;
|
|
int ret = OSPF_SUCCESS;
|
|
|
|
str2prefix_ipv4(argv[idx]->arg, &p);
|
|
|
|
if (is_default_prefix4(&p)) {
|
|
vty_out(vty,
|
|
"Default address shouldn't be configured as summary address.\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Apply mask for given prefix. */
|
|
apply_mask(&p);
|
|
|
|
if (!is_valid_summary_addr(&p)) {
|
|
vty_out(vty, "Not a valid summary address.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argc > 2)
|
|
tag = strtoul(argv[idx + 2]->arg, NULL, 10);
|
|
|
|
ret = ospf_asbr_external_aggregator_set(ospf, &p, tag);
|
|
if (ret == OSPF_INVALID)
|
|
vty_out(vty, "Invalid configuration!!\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_external_route_aggregation,
|
|
no_ospf_external_route_aggregation_cmd,
|
|
"no summary-address A.B.C.D/M [tag (1-4294967295)]",
|
|
NO_STR
|
|
"External summary address\n"
|
|
"Summary address prefix\n"
|
|
"Router tag\n"
|
|
"Router tag value\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct prefix_ipv4 p;
|
|
int idx = 2;
|
|
route_tag_t tag = 0;
|
|
int ret = OSPF_SUCCESS;
|
|
|
|
str2prefix_ipv4(argv[idx]->arg, &p);
|
|
|
|
if (is_default_prefix4(&p)) {
|
|
vty_out(vty,
|
|
"Default address shouldn't be configured as summary address.\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Apply mask for given prefix. */
|
|
apply_mask(&p);
|
|
|
|
if (!is_valid_summary_addr(&p)) {
|
|
vty_out(vty, "Not a valid summary address.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
if (argc > 3)
|
|
tag = strtoul(argv[idx + 2]->arg, NULL, 10);
|
|
|
|
ret = ospf_asbr_external_aggregator_unset(ospf, &p, tag);
|
|
if (ret == OSPF_INVALID)
|
|
vty_out(vty, "Invalid configuration!!\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(no_ospf_gr_helper_planned_only,
|
|
no_ospf_gr_helper_planned_only_cmd,
|
|
"no graceful-restart helper planned-only",
|
|
NO_STR
|
|
"OSPF Graceful Restart\n"
|
|
"OSPF GR Helper\n"
|
|
"Supported only for planned restart\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_FALSE);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static int ospf_print_vty_helper_dis_rtr_walkcb(struct hash_bucket *bucket,
|
|
void *arg)
|
|
{
|
|
struct advRtr *rtr = bucket->data;
|
|
struct vty *vty = (struct vty *)arg;
|
|
static unsigned int count;
|
|
|
|
vty_out(vty, "%-6pI4,", &rtr->advRtrAddr);
|
|
count++;
|
|
|
|
if (count % 5 == 0)
|
|
vty_out(vty, "\n");
|
|
|
|
return HASHWALK_CONTINUE;
|
|
}
|
|
|
|
static int ospf_print_json_helper_enabled_rtr_walkcb(struct hash_bucket *bucket,
|
|
void *arg)
|
|
{
|
|
struct advRtr *rtr = bucket->data;
|
|
struct json_object *json_rid_array = arg;
|
|
struct json_object *json_rid;
|
|
|
|
json_rid = json_object_new_object();
|
|
|
|
json_object_string_addf(json_rid, "routerId", "%pI4", &rtr->advRtrAddr);
|
|
json_object_array_add(json_rid_array, json_rid);
|
|
|
|
return HASHWALK_CONTINUE;
|
|
}
|
|
|
|
static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
|
|
uint8_t use_vrf, json_object *json,
|
|
bool uj, bool detail)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_interface *oi;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (uj) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (uj)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
if (uj) {
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
/* Show Router ID. */
|
|
if (uj) {
|
|
json_object_string_add(json_vrf, "routerId",
|
|
inet_ntop(AF_INET, &ospf->router_id,
|
|
buf, sizeof(buf)));
|
|
} else {
|
|
vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n",
|
|
&ospf->router_id);
|
|
}
|
|
|
|
if (!uj) {
|
|
|
|
if (ospf->is_helper_supported)
|
|
vty_out(vty,
|
|
" Graceful restart helper support enabled.\n");
|
|
else
|
|
vty_out(vty,
|
|
" Graceful restart helper support disabled.\n");
|
|
|
|
if (ospf->strict_lsa_check)
|
|
vty_out(vty, " Strict LSA check is enabled.\n");
|
|
else
|
|
vty_out(vty, " Strict LSA check is disabled.\n");
|
|
|
|
if (ospf->only_planned_restart)
|
|
vty_out(vty,
|
|
" Helper supported for planned restarts only.\n");
|
|
else
|
|
vty_out(vty,
|
|
" Helper supported for Planned and Unplanned Restarts.\n");
|
|
|
|
vty_out(vty,
|
|
" Supported Graceful restart interval: %d(in seconds).\n",
|
|
ospf->supported_grace_time);
|
|
|
|
if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
|
|
vty_out(vty, " Enable Router list:\n");
|
|
vty_out(vty, " ");
|
|
hash_walk(ospf->enable_rtr_list,
|
|
ospf_print_vty_helper_dis_rtr_walkcb, vty);
|
|
vty_out(vty, "\n\n");
|
|
}
|
|
|
|
if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) {
|
|
vty_out(vty, " Last Helper exit Reason :%s\n",
|
|
ospf_exit_reason2str(ospf->last_exit_reason));
|
|
}
|
|
|
|
if (ospf->active_restarter_cnt)
|
|
vty_out(vty,
|
|
" Number of Active neighbours in graceful restart: %d\n",
|
|
ospf->active_restarter_cnt);
|
|
else
|
|
vty_out(vty, "\n");
|
|
|
|
} else {
|
|
json_object_string_add(
|
|
json_vrf, "helperSupport",
|
|
(ospf->is_helper_supported) ? "Enabled" : "Disabled");
|
|
json_object_string_add(json_vrf, "strictLsaCheck",
|
|
(ospf->strict_lsa_check) ? "Enabled"
|
|
: "Disabled");
|
|
json_object_string_add(
|
|
json_vrf, "restartSupport",
|
|
(ospf->only_planned_restart)
|
|
? "Planned Restart only"
|
|
: "Planned and Unplanned Restarts");
|
|
|
|
json_object_int_add(json_vrf, "supportedGracePeriod",
|
|
ospf->supported_grace_time);
|
|
|
|
if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE)
|
|
json_object_string_add(
|
|
json_vrf, "lastExitReason",
|
|
ospf_exit_reason2str(ospf->last_exit_reason));
|
|
|
|
if (ospf->active_restarter_cnt)
|
|
json_object_int_add(json_vrf, "activeRestarterCnt",
|
|
ospf->active_restarter_cnt);
|
|
|
|
if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
|
|
struct json_object *json_rid_array =
|
|
json_object_new_array();
|
|
|
|
json_object_object_add(json_vrf, "enabledRouterIds",
|
|
json_rid_array);
|
|
|
|
hash_walk(ospf->enable_rtr_list,
|
|
ospf_print_json_helper_enabled_rtr_walkcb,
|
|
json_rid_array);
|
|
}
|
|
}
|
|
|
|
|
|
if (detail) {
|
|
int cnt = 1;
|
|
json_object *json_neighbors = NULL;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
|
struct route_node *rn;
|
|
struct ospf_neighbor *nbr;
|
|
json_object *json_neigh;
|
|
|
|
if (ospf_interface_neighbor_count(oi) == 0)
|
|
continue;
|
|
|
|
if (uj) {
|
|
json_object_object_get_ex(json_vrf, "neighbors",
|
|
&json_neighbors);
|
|
if (!json_neighbors) {
|
|
json_neighbors =
|
|
json_object_new_object();
|
|
json_object_object_add(json_vrf,
|
|
"neighbors",
|
|
json_neighbors);
|
|
}
|
|
}
|
|
|
|
for (rn = route_top(oi->nbrs); rn;
|
|
rn = route_next(rn)) {
|
|
|
|
if (!rn->info)
|
|
continue;
|
|
|
|
nbr = rn->info;
|
|
|
|
if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
|
continue;
|
|
|
|
if (!uj) {
|
|
vty_out(vty, " Neighbour %d :\n", cnt);
|
|
vty_out(vty, " Address : %pI4\n",
|
|
&nbr->address.u.prefix4);
|
|
vty_out(vty, " Routerid : %pI4\n",
|
|
&nbr->router_id);
|
|
vty_out(vty,
|
|
" Received Grace period : %d(in seconds).\n",
|
|
nbr->gr_helper_info
|
|
.recvd_grace_period);
|
|
vty_out(vty,
|
|
" Actual Grace period : %d(in seconds)\n",
|
|
nbr->gr_helper_info
|
|
.actual_grace_period);
|
|
vty_out(vty,
|
|
" Remaining GraceTime:%ld(in seconds).\n",
|
|
event_timer_remain_second(
|
|
nbr->gr_helper_info
|
|
.t_grace_timer));
|
|
vty_out(vty,
|
|
" Graceful Restart reason: %s.\n\n",
|
|
ospf_restart_reason2str(
|
|
nbr->gr_helper_info
|
|
.gr_restart_reason));
|
|
cnt++;
|
|
} else {
|
|
json_neigh = json_object_new_object();
|
|
json_object_string_add(
|
|
json_neigh, "srcAddr",
|
|
inet_ntop(AF_INET, &nbr->src,
|
|
buf, sizeof(buf)));
|
|
|
|
json_object_string_add(
|
|
json_neigh, "routerid",
|
|
inet_ntop(AF_INET,
|
|
&nbr->router_id,
|
|
buf, sizeof(buf)));
|
|
json_object_int_add(
|
|
json_neigh,
|
|
"recvdGraceInterval",
|
|
nbr->gr_helper_info
|
|
.recvd_grace_period);
|
|
json_object_int_add(
|
|
json_neigh,
|
|
"actualGraceInterval",
|
|
nbr->gr_helper_info
|
|
.actual_grace_period);
|
|
json_object_int_add(
|
|
json_neigh, "remainGracetime",
|
|
event_timer_remain_second(
|
|
nbr->gr_helper_info
|
|
.t_grace_timer));
|
|
json_object_string_add(
|
|
json_neigh, "restartReason",
|
|
ospf_restart_reason2str(
|
|
nbr->gr_helper_info
|
|
.gr_restart_reason));
|
|
json_object_object_add(
|
|
json_neighbors,
|
|
inet_ntop(AF_INET, &nbr->src,
|
|
buf, sizeof(buf)),
|
|
json_neigh);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_external_route_aggregation_no_adrvertise,
|
|
ospf_external_route_aggregation_no_adrvertise_cmd,
|
|
"summary-address A.B.C.D/M no-advertise",
|
|
"External summary address\n"
|
|
"Summary address prefix\n"
|
|
"Don't advertise summary route \n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct prefix_ipv4 p;
|
|
int idx = 1;
|
|
int ret = OSPF_SUCCESS;
|
|
|
|
str2prefix_ipv4(argv[idx]->arg, &p);
|
|
|
|
if (is_default_prefix4(&p)) {
|
|
vty_out(vty,
|
|
"Default address shouldn't be configured as summary address.\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Apply mask for given prefix. */
|
|
apply_mask(&p);
|
|
|
|
if (!is_valid_summary_addr(&p)) {
|
|
vty_out(vty, "Not a valid summary address.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ret = ospf_asbr_external_rt_no_advertise(ospf, &p);
|
|
if (ret == OSPF_INVALID)
|
|
vty_out(vty, "Invalid configuration!!\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (no_ospf_external_route_aggregation_no_adrvertise,
|
|
no_ospf_external_route_aggregation_no_adrvertise_cmd,
|
|
"no summary-address A.B.C.D/M no-advertise",
|
|
NO_STR
|
|
"External summary address\n"
|
|
"Summary address prefix\n"
|
|
"Advertise summary route to the AS \n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct prefix_ipv4 p;
|
|
int idx = 2;
|
|
int ret = OSPF_SUCCESS;
|
|
|
|
str2prefix_ipv4(argv[idx]->arg, &p);
|
|
|
|
if (is_default_prefix4(&p)) {
|
|
vty_out(vty,
|
|
"Default address shouldn't be configured as summary address.\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Apply mask for given prefix. */
|
|
apply_mask(&p);
|
|
|
|
if (!is_valid_summary_addr(&p)) {
|
|
vty_out(vty, "Not a valid summary address.\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
ret = ospf_asbr_external_rt_advertise(ospf, &p);
|
|
if (ret == OSPF_INVALID)
|
|
vty_out(vty, "Invalid configuration!!\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (ospf_route_aggregation_timer,
|
|
ospf_route_aggregation_timer_cmd,
|
|
"aggregation timer (5-1800)",
|
|
"External route aggregation\n"
|
|
"Delay timer (in seconds)\n"
|
|
"Timer interval(in seconds)\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
uint16_t interval = 0;
|
|
|
|
interval = strtoul(argv[2]->arg, NULL, 10);
|
|
|
|
ospf_external_aggregator_timer_set(ospf, interval);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (show_ip_ospf_gr_helper,
|
|
show_ip_ospf_gr_helper_cmd,
|
|
"show ip ospf [{(1-65535)$instance|vrf <NAME|all>}] graceful-restart helper [detail] [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"OSPF Graceful Restart\n"
|
|
"Helper details in the router\n"
|
|
"Detailed information\n"
|
|
JSON_STR)
|
|
{
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int idx_vrf = 0;
|
|
int idx = 0;
|
|
uint8_t use_vrf = 0;
|
|
bool uj = use_json(argc, argv);
|
|
struct ospf *ospf = NULL;
|
|
json_object *json = NULL;
|
|
struct listnode *node = NULL;
|
|
int inst = 0;
|
|
bool detail = false;
|
|
|
|
if (instance && instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (instance && vrf_name) {
|
|
vty_out(vty, "%% VRF is not supported in instance mode\n");
|
|
return CMD_WARNING;
|
|
}
|
|
|
|
if (argv_find(argv, argc, "detail", &idx))
|
|
detail = true;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided */
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
|
|
ret = ospf_show_gr_helper_details(
|
|
vty, ospf, use_vrf, json, uj, detail);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
} else {
|
|
/* Default Vrf */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
}
|
|
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n", vrf_name ? vrf_name : "default");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_show_gr_helper_details(vty, ospf, use_vrf, json, uj, detail);
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
/* Graceful Restart HELPER commands end */
|
|
DEFUN (no_ospf_route_aggregation_timer,
|
|
no_ospf_route_aggregation_timer_cmd,
|
|
"no aggregation timer",
|
|
NO_STR
|
|
"External route aggregation\n"
|
|
"Delay timer\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
|
|
ospf_external_aggregator_timer_set(ospf, OSPF_EXTL_AGGR_DEFAULT_DELAY);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* External Route Aggregation End */
|
|
|
|
static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED)
|
|
vty_out(vty, " max-metric router-lsa on-startup %u\n",
|
|
ospf->stub_router_startup_time);
|
|
if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
|
|
vty_out(vty, " max-metric router-lsa on-shutdown %u\n",
|
|
ospf->stub_router_shutdown_time);
|
|
if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
|
|
vty_out(vty, " max-metric router-lsa administrative\n");
|
|
|
|
return;
|
|
}
|
|
|
|
static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
|
|
struct route_table *rt,
|
|
json_object *json, bool detail)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_route * or ;
|
|
struct listnode *pnode, *pnnode;
|
|
struct ospf_path *path;
|
|
json_object *json_route = NULL, *json_nexthop_array = NULL,
|
|
*json_nexthop = NULL;
|
|
|
|
if (!json)
|
|
vty_out(vty,
|
|
"============ OSPF network routing table ============\n");
|
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
|
char buf1[PREFIX2STR_BUFFER];
|
|
|
|
if ((or = rn->info) == NULL)
|
|
continue;
|
|
|
|
prefix2str(&rn->p, buf1, sizeof(buf1));
|
|
|
|
if (json) {
|
|
json_route = json_object_new_object();
|
|
json_object_object_add(json, buf1, json_route);
|
|
}
|
|
|
|
switch (or->path_type) {
|
|
case OSPF_PATH_INTER_AREA:
|
|
if (or->type == OSPF_DESTINATION_NETWORK) {
|
|
if (json) {
|
|
json_object_string_add(json_route,
|
|
"routeType",
|
|
"N IA");
|
|
json_object_int_add(json_route, "cost",
|
|
or->cost);
|
|
json_object_string_addf(
|
|
json_route, "area", "%pI4",
|
|
&or->u.std.area_id);
|
|
} else {
|
|
vty_out(vty,
|
|
"N IA %-18s [%d] area: %pI4\n",
|
|
buf1, or->cost,
|
|
&or->u.std.area_id);
|
|
}
|
|
} else if (or->type == OSPF_DESTINATION_DISCARD) {
|
|
if (json) {
|
|
json_object_string_add(json_route,
|
|
"routeType",
|
|
"D IA");
|
|
} else {
|
|
vty_out(vty,
|
|
"D IA %-18s Discard entry\n",
|
|
buf1);
|
|
}
|
|
}
|
|
break;
|
|
case OSPF_PATH_INTRA_AREA:
|
|
if (json) {
|
|
json_object_string_add(json_route, "routeType",
|
|
"N");
|
|
json_object_boolean_add(json_route, "transit",
|
|
or->u.std.transit);
|
|
json_object_int_add(json_route, "cost",
|
|
or->cost);
|
|
json_object_string_addf(json_route, "area",
|
|
"%pI4",
|
|
&or->u.std.area_id);
|
|
} else {
|
|
vty_out(vty, "N %s %-18s [%d] area: %pI4\n",
|
|
or->u.std.transit && detail ? "T" : " ",
|
|
buf1, or->cost, &or->u.std.area_id);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (or->type == OSPF_DESTINATION_NETWORK) {
|
|
if (json) {
|
|
json_nexthop_array = json_object_new_array();
|
|
json_object_object_add(json_route, "nexthops",
|
|
json_nexthop_array);
|
|
}
|
|
|
|
for (ALL_LIST_ELEMENTS(or->paths, pnode, pnnode,
|
|
path)) {
|
|
if (json) {
|
|
json_nexthop = json_object_new_object();
|
|
json_object_array_add(
|
|
json_nexthop_array,
|
|
json_nexthop);
|
|
}
|
|
if (if_lookup_by_index(path->ifindex,
|
|
ospf->vrf_id)) {
|
|
|
|
if (path->nexthop.s_addr
|
|
== INADDR_ANY) {
|
|
if (json) {
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"ip", " ");
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"directlyAttachedTo",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
} else {
|
|
vty_out(vty,
|
|
"%24s directly attached to %s\n",
|
|
"",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
}
|
|
} else {
|
|
if (json) {
|
|
json_object_string_addf(
|
|
json_nexthop,
|
|
"ip", "%pI4",
|
|
&path->nexthop);
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"via",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
json_object_string_addf(
|
|
json_nexthop,
|
|
"advertisedRouter",
|
|
"%pI4",
|
|
&path->adv_router);
|
|
} else {
|
|
vty_out(vty,
|
|
"%24s via %pI4, %s\n",
|
|
"",
|
|
&path->nexthop,
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
}
|
|
if (detail && !json)
|
|
vty_out(vty,
|
|
"%24s adv %pI4\n",
|
|
"",
|
|
&path->adv_router);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
|
|
struct route_table *rtrs,
|
|
json_object *json)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_route * or ;
|
|
struct listnode *pnode;
|
|
struct listnode *node;
|
|
struct ospf_path *path;
|
|
char buf[PREFIX_STRLEN];
|
|
json_object *json_route = NULL, *json_nexthop_array = NULL,
|
|
*json_nexthop = NULL;
|
|
|
|
if (!json)
|
|
vty_out(vty, "============ OSPF %s table =============\n",
|
|
ospf->all_rtrs == rtrs ? "reachable routers"
|
|
: "router routing");
|
|
|
|
for (rn = route_top(rtrs); rn; rn = route_next(rn)) {
|
|
if (rn->info == NULL)
|
|
continue;
|
|
int flag = 0;
|
|
|
|
if (json) {
|
|
json_route = json_object_new_object();
|
|
json_object_object_add(
|
|
json, inet_ntop(AF_INET, &rn->p.u.prefix4,
|
|
buf, sizeof(buf)),
|
|
json_route);
|
|
json_object_string_add(json_route, "routeType", "R ");
|
|
} else {
|
|
vty_out(vty, "R %-15pI4 ",
|
|
&rn->p.u.prefix4);
|
|
}
|
|
|
|
for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) {
|
|
if (flag++) {
|
|
if (!json)
|
|
vty_out(vty, "%24s", "");
|
|
}
|
|
|
|
/* Show path. */
|
|
if (json) {
|
|
json_object_int_add(json_route, "cost",
|
|
or->cost);
|
|
json_object_string_addf(json_route, "area",
|
|
"%pI4",
|
|
&or->u.std.area_id);
|
|
if (or->path_type == OSPF_PATH_INTER_AREA) {
|
|
json_object_boolean_true_add(json_route,
|
|
"IA");
|
|
json_object_boolean_true_add(json_route,
|
|
"ia");
|
|
}
|
|
if (or->u.std.flags & ROUTER_LSA_BORDER)
|
|
json_object_string_add(json_route,
|
|
"routerType",
|
|
"abr");
|
|
else if (or->u.std.flags & ROUTER_LSA_EXTERNAL)
|
|
json_object_string_add(json_route,
|
|
"routerType",
|
|
"asbr");
|
|
} else {
|
|
vty_out(vty, "%s [%d] area: %pI4",
|
|
(or->path_type == OSPF_PATH_INTER_AREA
|
|
? "IA"
|
|
: " "),
|
|
or->cost, &or->u.std.area_id);
|
|
/* Show flags. */
|
|
vty_out(vty, "%s%s\n",
|
|
(or->u.std.flags & ROUTER_LSA_BORDER
|
|
? ", ABR"
|
|
: ""),
|
|
(or->u.std.flags & ROUTER_LSA_EXTERNAL
|
|
? ", ASBR"
|
|
: ""));
|
|
}
|
|
|
|
if (json) {
|
|
json_nexthop_array = json_object_new_array();
|
|
json_object_object_add(json_route, "nexthops",
|
|
json_nexthop_array);
|
|
}
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) {
|
|
if (json) {
|
|
json_nexthop = json_object_new_object();
|
|
json_object_array_add(
|
|
json_nexthop_array,
|
|
json_nexthop);
|
|
}
|
|
if (if_lookup_by_index(path->ifindex,
|
|
ospf->vrf_id)) {
|
|
if (path->nexthop.s_addr
|
|
== INADDR_ANY) {
|
|
if (json) {
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"ip", " ");
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"directlyAttachedTo",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
} else {
|
|
vty_out(vty,
|
|
"%24s directly attached to %s\n",
|
|
"",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
}
|
|
} else {
|
|
if (json) {
|
|
json_object_string_addf(
|
|
json_nexthop,
|
|
"ip", "%pI4",
|
|
&path->nexthop);
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"via",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
} else {
|
|
vty_out(vty,
|
|
"%24s via %pI4, %s\n",
|
|
"",
|
|
&path->nexthop,
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
|
|
struct route_table *rt,
|
|
json_object *json, bool detail)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_route *er;
|
|
struct listnode *pnode, *pnnode;
|
|
struct ospf_path *path;
|
|
json_object *json_route = NULL, *json_nexthop_array = NULL,
|
|
*json_nexthop = NULL;
|
|
|
|
if (!json)
|
|
vty_out(vty,
|
|
"============ OSPF external routing table ===========\n");
|
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
|
if ((er = rn->info) == NULL)
|
|
continue;
|
|
|
|
char buf1[19];
|
|
|
|
snprintfrr(buf1, sizeof(buf1), "%pFX", &rn->p);
|
|
if (json) {
|
|
json_route = json_object_new_object();
|
|
json_object_object_add(json, buf1, json_route);
|
|
}
|
|
|
|
switch (er->path_type) {
|
|
case OSPF_PATH_TYPE1_EXTERNAL:
|
|
if (json) {
|
|
json_object_string_add(json_route, "routeType",
|
|
"N E1");
|
|
json_object_int_add(json_route, "cost",
|
|
er->cost);
|
|
json_object_int_add(json_route, "tag",
|
|
er->u.ext.tag);
|
|
} else {
|
|
vty_out(vty,
|
|
"N E1 %-18s [%d] tag: %" ROUTE_TAG_PRI
|
|
"\n",
|
|
buf1, er->cost, er->u.ext.tag);
|
|
}
|
|
break;
|
|
case OSPF_PATH_TYPE2_EXTERNAL:
|
|
if (json) {
|
|
json_object_string_add(json_route, "routeType",
|
|
"N E2");
|
|
json_object_int_add(json_route, "cost",
|
|
er->cost);
|
|
json_object_int_add(json_route, "type2cost",
|
|
er->u.ext.type2_cost);
|
|
json_object_int_add(json_route, "tag",
|
|
er->u.ext.tag);
|
|
} else {
|
|
vty_out(vty,
|
|
"N E2 %-18s [%d/%d] tag: %" ROUTE_TAG_PRI
|
|
"\n",
|
|
buf1, er->cost, er->u.ext.type2_cost,
|
|
er->u.ext.tag);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (json) {
|
|
json_nexthop_array = json_object_new_array();
|
|
json_object_object_add(json_route, "nexthops",
|
|
json_nexthop_array);
|
|
}
|
|
|
|
for (ALL_LIST_ELEMENTS(er->paths, pnode, pnnode, path)) {
|
|
if (json) {
|
|
json_nexthop = json_object_new_object();
|
|
json_object_array_add(json_nexthop_array,
|
|
json_nexthop);
|
|
}
|
|
|
|
if (if_lookup_by_index(path->ifindex, ospf->vrf_id)) {
|
|
if (path->nexthop.s_addr == INADDR_ANY) {
|
|
if (json) {
|
|
json_object_string_add(
|
|
json_nexthop, "ip",
|
|
" ");
|
|
json_object_string_add(
|
|
json_nexthop,
|
|
"directlyAttachedTo",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
} else {
|
|
vty_out(vty,
|
|
"%24s directly attached to %s\n",
|
|
"",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
}
|
|
} else {
|
|
if (json) {
|
|
json_object_string_addf(
|
|
json_nexthop, "ip",
|
|
"%pI4", &path->nexthop);
|
|
json_object_string_add(
|
|
json_nexthop, "via",
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
json_object_string_addf(
|
|
json_nexthop,
|
|
"advertisedRouter",
|
|
"%pI4",
|
|
&path->adv_router);
|
|
} else {
|
|
vty_out(vty,
|
|
"%24s via %pI4, %s\n",
|
|
"",
|
|
&path->nexthop,
|
|
ifindex2ifname(
|
|
path->ifindex,
|
|
ospf->vrf_id));
|
|
}
|
|
if (detail && !json)
|
|
vty_out(vty,
|
|
"%24s adv %pI4\n", "",
|
|
&path->adv_router);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!json)
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
static int show_ip_ospf_reachable_routers_common(struct vty *vty,
|
|
struct ospf *ospf,
|
|
uint8_t use_vrf)
|
|
{
|
|
if (ospf->instance)
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
|
|
ospf_show_vrf_name(ospf, vty, NULL, use_vrf);
|
|
|
|
if (ospf->all_rtrs == NULL) {
|
|
vty_out(vty, "No OSPF reachable router information exist\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Show Router routes. */
|
|
show_ip_ospf_route_router(vty, ospf, ospf->all_rtrs, NULL);
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_reachable_routers,
|
|
show_ip_ospf_reachable_routers_cmd,
|
|
"show ip ospf [vrf <NAME|all>] reachable-routers",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Show all the reachable OSPF routers\n")
|
|
{
|
|
struct ospf *ospf = NULL;
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0;
|
|
uint8_t use_vrf = 0;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (vrf_name) {
|
|
bool ospf_output = false;
|
|
|
|
use_vrf = 1;
|
|
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
|
|
ospf_output = true;
|
|
ret = show_ip_ospf_reachable_routers_common(
|
|
vty, ospf, use_vrf);
|
|
}
|
|
|
|
if (!ospf_output)
|
|
vty_out(vty, "%% OSPF instance not found\n");
|
|
} else {
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
vty_out(vty, "%% OSPF instance not found\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ret = show_ip_ospf_reachable_routers_common(vty, ospf,
|
|
use_vrf);
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
vty_out(vty, "%% OSPF instance not found\n");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ret = show_ip_ospf_reachable_routers_common(vty, ospf, use_vrf);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_reachable_routers,
|
|
show_ip_ospf_instance_reachable_routers_cmd,
|
|
"show ip ospf (1-65535) reachable-routers",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Show all the reachable OSPF routers\n")
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
return show_ip_ospf_reachable_routers_common(vty, ospf, 0);
|
|
}
|
|
|
|
static int show_ip_ospf_border_routers_common(struct vty *vty,
|
|
struct ospf *ospf,
|
|
uint8_t use_vrf,
|
|
json_object *json)
|
|
{
|
|
json_object *json_vrf = NULL;
|
|
json_object *json_router = NULL;
|
|
|
|
if (json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
json_router = json_object_new_object();
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (!json)
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
else
|
|
json_object_int_add(json_vrf, "ospfInstance",
|
|
ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
if (ospf->new_table == NULL) {
|
|
if (!json)
|
|
vty_out(vty, "No OSPF routing information exist\n");
|
|
else {
|
|
json_object_free(json_router);
|
|
if (use_vrf)
|
|
json_object_free(json_vrf);
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/* Show Network routes.
|
|
show_ip_ospf_route_network (vty, ospf->new_table); */
|
|
|
|
/* Show Router routes. */
|
|
show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, json_router);
|
|
|
|
if (json) {
|
|
json_object_object_add(json_vrf, "routers", json_router);
|
|
if (use_vrf) {
|
|
if (ospf->vrf_id == VRF_DEFAULT)
|
|
json_object_object_add(json, "default",
|
|
json_vrf);
|
|
else
|
|
json_object_object_add(json, ospf->name,
|
|
json_vrf);
|
|
}
|
|
} else {
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (show_ip_ospf_border_routers,
|
|
show_ip_ospf_border_routers_cmd,
|
|
"show ip ospf [vrf <NAME|all>] border-routers [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Show all the ABR's and ASBR's\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf = NULL;
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx_vrf = 0;
|
|
uint8_t use_vrf = 0;
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (vrf_name) {
|
|
bool ospf_output = false;
|
|
|
|
use_vrf = 1;
|
|
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
|
|
ospf_output = true;
|
|
ret = show_ip_ospf_border_routers_common(
|
|
vty, ospf, use_vrf, json);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else if (!ospf_output)
|
|
vty_out(vty, "%% OSPF is not enabled\n");
|
|
|
|
return ret;
|
|
} else {
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf default\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf) {
|
|
ret = show_ip_ospf_border_routers_common(vty, ospf, use_vrf,
|
|
json);
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_border_routers,
|
|
show_ip_ospf_instance_border_routers_cmd,
|
|
"show ip ospf (1-65535) border-routers",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Show all the ABR's and ASBR's\n")
|
|
{
|
|
int idx_number = 3;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
return show_ip_ospf_border_routers_common(vty, ospf, 0, NULL);
|
|
}
|
|
|
|
static int show_ip_ospf_route_common(struct vty *vty, struct ospf *ospf,
|
|
json_object *json, uint8_t use_vrf,
|
|
bool detail)
|
|
{
|
|
json_object *json_vrf = NULL;
|
|
|
|
if (ospf->instance)
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
|
|
|
|
if (json) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
if (ospf->new_table == NULL) {
|
|
if (json) {
|
|
if (use_vrf)
|
|
json_object_free(json_vrf);
|
|
} else {
|
|
vty_out(vty, "No OSPF routing information exist\n");
|
|
}
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
if (detail && json == NULL) {
|
|
vty_out(vty, "Codes: N - network T - transitive\n");
|
|
vty_out(vty, " IA - inter-area E - external route\n");
|
|
vty_out(vty, " D - destination R - router\n\n");
|
|
}
|
|
|
|
/* Show Network routes. */
|
|
show_ip_ospf_route_network(vty, ospf, ospf->new_table, json_vrf,
|
|
detail);
|
|
|
|
/* Show Router routes. */
|
|
show_ip_ospf_route_router(vty, ospf, ospf->new_rtrs, json_vrf);
|
|
|
|
/* Show Router routes. */
|
|
if (ospf->all_rtrs)
|
|
show_ip_ospf_route_router(vty, ospf, ospf->all_rtrs, json_vrf);
|
|
|
|
/* Show AS External routes. */
|
|
show_ip_ospf_route_external(vty, ospf, ospf->old_external_route,
|
|
json_vrf, detail);
|
|
|
|
if (json) {
|
|
if (use_vrf) {
|
|
// json_object_object_add(json_vrf, "areas",
|
|
// json_areas);
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
}
|
|
} else {
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_route,
|
|
show_ip_ospf_route_cmd,
|
|
"show ip ospf [vrf <NAME|all>] route [detail] [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"OSPF routing table\n"
|
|
"Detailed information\n"
|
|
JSON_STR)
|
|
{
|
|
struct ospf *ospf = NULL;
|
|
struct listnode *node = NULL;
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int inst = 0;
|
|
int idx = 0;
|
|
int idx_vrf = 0;
|
|
uint8_t use_vrf = 0;
|
|
bool uj = use_json(argc, argv);
|
|
bool detail = false;
|
|
json_object *json = NULL;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
if (argv_find(argv, argc, "detail", &idx))
|
|
detail = true;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
/* vrf input is provided could be all or specific vrf*/
|
|
if (vrf_name) {
|
|
bool ospf_output = false;
|
|
|
|
use_vrf = 1;
|
|
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ospf_output = true;
|
|
ret = show_ip_ospf_route_common(
|
|
vty, ospf, json, use_vrf, detail);
|
|
}
|
|
|
|
if (uj) {
|
|
/* Keep Non-pretty format */
|
|
vty_json(vty, json);
|
|
} else if (!ospf_output)
|
|
vty_out(vty, "%% OSPF is not enabled\n");
|
|
|
|
return ret;
|
|
}
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
} else {
|
|
/* Display default ospf (instance 0) info */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf default\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (ospf) {
|
|
ret = show_ip_ospf_route_common(vty, ospf, json, use_vrf,
|
|
detail);
|
|
/* Keep Non-pretty format */
|
|
if (uj)
|
|
vty_out(vty, "%s\n",
|
|
json_object_to_json_string_ext(
|
|
json, JSON_C_TO_STRING_NOSLASHESCAPE));
|
|
}
|
|
|
|
if (uj)
|
|
json_object_free(json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_instance_route,
|
|
show_ip_ospf_instance_route_cmd,
|
|
"show ip ospf (1-65535) route [detail]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"OSPF routing table\n"
|
|
"Detailed information\n")
|
|
{
|
|
int idx_number = 3;
|
|
int idx = 0;
|
|
struct ospf *ospf;
|
|
unsigned short instance = 0;
|
|
bool detail = false;
|
|
|
|
if (argv_find(argv, argc, "detail", &idx))
|
|
detail = true;
|
|
|
|
instance = strtoul(argv[idx_number]->arg, NULL, 10);
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
|
|
ospf = ospf_lookup_instance(instance);
|
|
if (!ospf || !ospf->oi_running)
|
|
return CMD_SUCCESS;
|
|
|
|
return show_ip_ospf_route_common(vty, ospf, NULL, 0, detail);
|
|
}
|
|
|
|
|
|
DEFUN (show_ip_ospf_vrfs,
|
|
show_ip_ospf_vrfs_cmd,
|
|
"show ip ospf vrfs [json]",
|
|
SHOW_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Show OSPF VRFs \n"
|
|
JSON_STR)
|
|
{
|
|
bool uj = use_json(argc, argv);
|
|
json_object *json = NULL;
|
|
json_object *json_vrfs = NULL;
|
|
struct ospf *ospf = NULL;
|
|
struct listnode *node = NULL;
|
|
int count = 0;
|
|
static const char header[] = "Name Id RouterId ";
|
|
|
|
if (uj) {
|
|
json = json_object_new_object();
|
|
json_vrfs = json_object_new_object();
|
|
}
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
json_object *json_vrf = NULL;
|
|
const char *name = NULL;
|
|
int64_t vrf_id_ui = 0;
|
|
|
|
count++;
|
|
|
|
if (!uj && count == 1)
|
|
vty_out(vty, "%s\n", header);
|
|
if (uj)
|
|
json_vrf = json_object_new_object();
|
|
|
|
name = ospf_get_name(ospf);
|
|
|
|
vrf_id_ui = (ospf->vrf_id == VRF_UNKNOWN)
|
|
? -1
|
|
: (int64_t)ospf->vrf_id;
|
|
|
|
if (uj) {
|
|
json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
|
|
json_object_string_addf(json_vrf, "routerId", "%pI4",
|
|
&ospf->router_id);
|
|
|
|
json_object_object_add(json_vrfs, name, json_vrf);
|
|
|
|
} else {
|
|
vty_out(vty, "%-25s %-5d %-16pI4 \n", name,
|
|
ospf->vrf_id, &ospf->router_id);
|
|
}
|
|
}
|
|
|
|
if (uj) {
|
|
json_object_object_add(json, "vrfs", json_vrfs);
|
|
json_object_int_add(json, "totalVrfs", count);
|
|
|
|
vty_json(vty, json);
|
|
} else {
|
|
if (count)
|
|
vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
|
|
count);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
DEFPY (clear_ip_ospf_neighbor,
|
|
clear_ip_ospf_neighbor_cmd,
|
|
"clear ip ospf [(1-65535)]$instance neighbor [A.B.C.D$nbr_id]",
|
|
CLEAR_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Reset OSPF Neighbor\n"
|
|
"Neighbor ID\n")
|
|
{
|
|
struct listnode *node;
|
|
struct ospf *ospf = NULL;
|
|
|
|
/* If user does not specify the arguments,
|
|
* instance = 0 and nbr_id = 0.0.0.0
|
|
*/
|
|
if (instance != 0) {
|
|
/* This means clear only the particular ospf process */
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
}
|
|
|
|
/* Clear all the ospf processes */
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
|
|
if (nbr_id_str && IPV4_ADDR_SAME(&ospf->router_id, &nbr_id)) {
|
|
vty_out(vty, "Self router-id is not allowed.\r\n ");
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_neighbor_reset(ospf, nbr_id, nbr_id_str);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (clear_ip_ospf_process,
|
|
clear_ip_ospf_process_cmd,
|
|
"clear ip ospf [(1-65535)]$instance process",
|
|
CLEAR_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
"Instance ID\n"
|
|
"Reset OSPF Process\n")
|
|
{
|
|
struct listnode *node;
|
|
struct ospf *ospf = NULL;
|
|
|
|
/* Check if instance is not passed as an argument */
|
|
if (instance != 0) {
|
|
/* This means clear only the particular ospf process */
|
|
if (instance != ospf_instance)
|
|
return CMD_NOT_MY_INSTANCE;
|
|
}
|
|
|
|
/* Clear all the ospf processes */
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
|
|
ospf_process_reset(ospf);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static const char *const ospf_abr_type_str[] = {
|
|
"unknown", "standard", "ibm", "cisco", "shortcut"
|
|
};
|
|
|
|
static const char *const ospf_shortcut_mode_str[] = {
|
|
"default", "enable", "disable"
|
|
};
|
|
static int ospf_vty_external_rt_walkcb(struct hash_bucket *bucket,
|
|
void *arg)
|
|
{
|
|
struct external_info *ei = bucket->data;
|
|
struct vty *vty = (struct vty *)arg;
|
|
static unsigned int count;
|
|
|
|
vty_out(vty, "%-4pI4/%d, ", &ei->p.prefix, ei->p.prefixlen);
|
|
count++;
|
|
|
|
if (count % 5 == 0)
|
|
vty_out(vty, "\n");
|
|
|
|
if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count)
|
|
count = 0;
|
|
|
|
return HASHWALK_CONTINUE;
|
|
}
|
|
|
|
static int ospf_json_external_rt_walkcb(struct hash_bucket *bucket,
|
|
void *arg)
|
|
{
|
|
struct external_info *ei = bucket->data;
|
|
struct json_object *json = (struct json_object *)arg;
|
|
char buf[PREFIX2STR_BUFFER];
|
|
char exnalbuf[20];
|
|
static unsigned int count;
|
|
|
|
prefix2str(&ei->p, buf, sizeof(buf));
|
|
|
|
snprintf(exnalbuf, 20, "Exnl Addr-%d", count);
|
|
|
|
json_object_string_add(json, exnalbuf, buf);
|
|
|
|
count++;
|
|
|
|
if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count)
|
|
count = 0;
|
|
|
|
return HASHWALK_CONTINUE;
|
|
}
|
|
|
|
static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf,
|
|
uint8_t use_vrf, json_object *json,
|
|
bool uj, bool detail)
|
|
{
|
|
struct route_node *rn;
|
|
json_object *json_vrf = NULL;
|
|
int mtype = 0;
|
|
int mval = 0;
|
|
static char header[] =
|
|
"Summary-address Metric-type Metric Tag External_Rt_count\n";
|
|
|
|
mtype = metric_type(ospf, 0, ospf->instance);
|
|
mval = metric_value(ospf, 0, ospf->instance);
|
|
|
|
if (!uj)
|
|
vty_out(vty, "%s\n", header);
|
|
|
|
if (uj) {
|
|
if (use_vrf)
|
|
json_vrf = json_object_new_object();
|
|
else
|
|
json_vrf = json;
|
|
}
|
|
|
|
if (ospf->instance) {
|
|
if (uj)
|
|
json_object_int_add(json, "ospfInstance",
|
|
ospf->instance);
|
|
else
|
|
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
|
|
}
|
|
|
|
ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
|
|
|
|
if (!uj) {
|
|
vty_out(vty, "aggregation delay interval: %u(in seconds)\n\n",
|
|
ospf->aggr_delay_interval);
|
|
} else {
|
|
json_object_int_add(json_vrf, "aggregationDelayInterval",
|
|
ospf->aggr_delay_interval);
|
|
}
|
|
|
|
for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn))
|
|
if (rn->info) {
|
|
struct ospf_external_aggr_rt *aggr = rn->info;
|
|
json_object *json_aggr = NULL;
|
|
char buf[PREFIX2STR_BUFFER];
|
|
|
|
prefix2str(&aggr->p, buf, sizeof(buf));
|
|
|
|
if (uj) {
|
|
|
|
json_aggr = json_object_new_object();
|
|
|
|
json_object_object_add(json_vrf, buf,
|
|
json_aggr);
|
|
json_object_string_add(json_aggr,
|
|
"summaryAddress", buf);
|
|
json_object_string_add(
|
|
json_aggr, "metricType",
|
|
(mtype == EXTERNAL_METRIC_TYPE_1)
|
|
? "E1"
|
|
: "E2");
|
|
|
|
json_object_int_add(json_aggr, "metric", mval);
|
|
json_object_int_add(json_aggr, "tag",
|
|
aggr->tag);
|
|
json_object_int_add(
|
|
json_aggr, "externalRouteCount",
|
|
OSPF_EXTERNAL_RT_COUNT(aggr));
|
|
|
|
if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) {
|
|
hash_walk(
|
|
aggr->match_extnl_hash,
|
|
ospf_json_external_rt_walkcb,
|
|
json_aggr);
|
|
}
|
|
|
|
} else {
|
|
vty_out(vty, "%-20s", buf);
|
|
|
|
(mtype == EXTERNAL_METRIC_TYPE_1)
|
|
? vty_out(vty, "%-16s", "E1")
|
|
: vty_out(vty, "%-16s", "E2");
|
|
vty_out(vty, "%-11d", mval);
|
|
|
|
vty_out(vty, "%-12u", aggr->tag);
|
|
|
|
vty_out(vty, "%-5ld\n",
|
|
OSPF_EXTERNAL_RT_COUNT(aggr));
|
|
|
|
if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) {
|
|
vty_out(vty,
|
|
"Matched External routes:\n");
|
|
hash_walk(
|
|
aggr->match_extnl_hash,
|
|
ospf_vty_external_rt_walkcb,
|
|
vty);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
}
|
|
|
|
if (uj) {
|
|
if (use_vrf)
|
|
json_object_object_add(json, ospf_get_name(ospf),
|
|
json_vrf);
|
|
} else
|
|
vty_out(vty, "\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFUN (show_ip_ospf_external_aggregator,
|
|
show_ip_ospf_external_aggregator_cmd,
|
|
"show ip ospf [vrf <NAME|all>] summary-address [detail] [json]",
|
|
SHOW_STR IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"All VRFs\n"
|
|
"Show external summary addresses\n"
|
|
"Detailed information\n"
|
|
JSON_STR)
|
|
{
|
|
char *vrf_name = NULL;
|
|
bool all_vrf = false;
|
|
int ret = CMD_SUCCESS;
|
|
int idx_vrf = 0;
|
|
int idx = 0;
|
|
uint8_t use_vrf = 0;
|
|
bool uj = use_json(argc, argv);
|
|
struct ospf *ospf = NULL;
|
|
json_object *json = NULL;
|
|
struct listnode *node = NULL;
|
|
int inst = 0;
|
|
bool detail = false;
|
|
|
|
OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (argv_find(argv, argc, "detail", &idx))
|
|
detail = true;
|
|
|
|
if (uj)
|
|
json = json_object_new_object();
|
|
|
|
/* vrf input is provided */
|
|
if (vrf_name) {
|
|
use_vrf = 1;
|
|
if (all_vrf) {
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (!ospf->oi_running)
|
|
continue;
|
|
ret = ospf_show_summary_address(
|
|
vty, ospf, use_vrf, json, uj, detail);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
|
|
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf %s\n",
|
|
vrf_name);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail);
|
|
|
|
} else {
|
|
/* Default Vrf */
|
|
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
if (ospf == NULL || !ospf->oi_running) {
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
else
|
|
vty_out(vty,
|
|
"%% OSPF is not enabled in vrf default\n");
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail);
|
|
}
|
|
|
|
if (uj)
|
|
vty_json(vty, json);
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
static const char *const ospf_int_type_str[] = {
|
|
"unknown", /* should never be used. */
|
|
"point-to-point",
|
|
"broadcast",
|
|
"non-broadcast",
|
|
"point-to-multipoint",
|
|
"virtual-link", /* should never be used. */
|
|
"loopback"
|
|
};
|
|
|
|
static int interface_config_auth_str(struct ospf_if_params *params, char *buf)
|
|
{
|
|
if (!OSPF_IF_PARAM_CONFIGURED(params, auth_type)
|
|
|| params->auth_type == OSPF_AUTH_NOTSET)
|
|
return 0;
|
|
|
|
/* Translation tables are not that much help
|
|
* here due to syntax
|
|
* of the simple option */
|
|
switch (params->auth_type) {
|
|
|
|
case OSPF_AUTH_NULL:
|
|
snprintf(buf, BUFSIZ, " null");
|
|
break;
|
|
|
|
case OSPF_AUTH_SIMPLE:
|
|
snprintf(buf, BUFSIZ, " ");
|
|
break;
|
|
|
|
case OSPF_AUTH_CRYPTOGRAPHIC:
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, keychain_name))
|
|
snprintf(buf, BUFSIZ, " key-chain %s", params->keychain_name);
|
|
else
|
|
snprintf(buf, BUFSIZ, " message-digest");
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
|
|
{
|
|
struct listnode *node;
|
|
struct interface *ifp;
|
|
struct crypt_key *ck;
|
|
struct route_node *rn = NULL;
|
|
struct ospf_if_params *params;
|
|
char buf[BUFSIZ];
|
|
int ret = 0;
|
|
int write = 0;
|
|
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
|
|
|
if (memcmp(ifp->name, "VLINK", 5) == 0)
|
|
continue;
|
|
|
|
if_vty_config_start(vty, ifp);
|
|
|
|
if (ifp->desc)
|
|
vty_out(vty, " description %s\n", ifp->desc);
|
|
|
|
write++;
|
|
|
|
params = IF_DEF_PARAMS(ifp);
|
|
|
|
do {
|
|
/* Interface Network print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, type) &&
|
|
params->type != OSPF_IFTYPE_LOOPBACK &&
|
|
params->type_cfg) {
|
|
vty_out(vty, " ip ospf network %s",
|
|
ospf_int_type_str[params->type]);
|
|
if (params->type == OSPF_IFTYPE_POINTOPOINT &&
|
|
params->ptp_dmvpn)
|
|
vty_out(vty, " dmvpn");
|
|
if (params->type ==
|
|
OSPF_IFTYPE_POINTOMULTIPOINT &&
|
|
params->p2mp_delay_reflood)
|
|
vty_out(vty, " delay-reflood");
|
|
if (params->type ==
|
|
OSPF_IFTYPE_POINTOMULTIPOINT &&
|
|
params->p2mp_non_broadcast)
|
|
vty_out(vty, " non-broadcast");
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4", &rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* OSPF interface authentication print */
|
|
ret = interface_config_auth_str(params, buf);
|
|
if (ret) {
|
|
vty_out(vty, " ip ospf authentication%s",
|
|
buf);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Simple Authentication Password print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, auth_simple)
|
|
&& params->auth_simple[0] != '\0') {
|
|
vty_out(vty, " ip ospf authentication-key %s",
|
|
params->auth_simple);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Cryptographic Authentication Key print. */
|
|
if (params && params->auth_crypt) {
|
|
for (ALL_LIST_ELEMENTS_RO(params->auth_crypt,
|
|
node, ck)) {
|
|
vty_out(vty,
|
|
" ip ospf message-digest-key %d md5 %s",
|
|
ck->key_id, ck->auth_key);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
}
|
|
|
|
/* Interface Output Cost print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, output_cost_cmd)) {
|
|
vty_out(vty, " ip ospf cost %u",
|
|
params->output_cost_cmd);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Hello Interval print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, v_hello)
|
|
&& params->v_hello != OSPF_HELLO_INTERVAL_DEFAULT) {
|
|
vty_out(vty, " ip ospf hello-interval %u",
|
|
params->v_hello);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
|
|
/* Router Dead Interval print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, v_wait)
|
|
&& params->is_v_wait_set) {
|
|
vty_out(vty, " ip ospf dead-interval ");
|
|
|
|
/* fast hello ? */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params,
|
|
fast_hello))
|
|
vty_out(vty,
|
|
"minimal hello-multiplier %d",
|
|
params->fast_hello);
|
|
else
|
|
vty_out(vty, "%u", params->v_wait);
|
|
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Hello Graceful-Restart Delay print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params,
|
|
v_gr_hello_delay) &&
|
|
params->v_gr_hello_delay !=
|
|
OSPF_HELLO_DELAY_DEFAULT)
|
|
vty_out(vty,
|
|
" ip ospf graceful-restart hello-delay %u\n",
|
|
params->v_gr_hello_delay);
|
|
|
|
/* Router Priority print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, priority)
|
|
&& params->priority
|
|
!= OSPF_ROUTER_PRIORITY_DEFAULT) {
|
|
vty_out(vty, " ip ospf priority %u",
|
|
params->priority);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Retransmit Interval print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params,
|
|
retransmit_interval)
|
|
&& params->retransmit_interval
|
|
!= OSPF_RETRANSMIT_INTERVAL_DEFAULT) {
|
|
vty_out(vty, " ip ospf retransmit-interval %u",
|
|
params->retransmit_interval);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Retransmit Window print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, retransmit_window) &&
|
|
params->retransmit_window !=
|
|
OSPF_RETRANSMIT_WINDOW_DEFAULT) {
|
|
vty_out(vty, " ip ospf retransmit-window %u",
|
|
params->retransmit_window);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4", &rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Transmit Delay print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay)
|
|
&& params->transmit_delay
|
|
!= OSPF_TRANSMIT_DELAY_DEFAULT) {
|
|
vty_out(vty, " ip ospf transmit-delay %u",
|
|
params->transmit_delay);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* Area print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
|
|
if (ospf_instance)
|
|
vty_out(vty, " ip ospf %d",
|
|
ospf_instance);
|
|
else
|
|
vty_out(vty, " ip ospf");
|
|
|
|
char buf[INET_ADDRSTRLEN];
|
|
|
|
area_id2str(buf, sizeof(buf), ¶ms->if_area,
|
|
params->if_area_id_fmt);
|
|
vty_out(vty, " area %s", buf);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* bfd print. */
|
|
if (params && params->bfd_config)
|
|
ospf_bfd_write_config(vty, params);
|
|
|
|
/* MTU ignore print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, mtu_ignore)
|
|
&& params->mtu_ignore != OSPF_MTU_IGNORE_DEFAULT) {
|
|
if (params->mtu_ignore == 0)
|
|
vty_out(vty, " no ip ospf mtu-ignore");
|
|
else
|
|
vty_out(vty, " ip ospf mtu-ignore");
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4",
|
|
&rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
if (OSPF_IF_PARAM_CONFIGURED(params,
|
|
passive_interface)) {
|
|
vty_out(vty, " %sip ospf passive",
|
|
params->passive_interface
|
|
== OSPF_IF_ACTIVE
|
|
? "no "
|
|
: "");
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4", &rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* LDP-Sync print */
|
|
if (params && params->ldp_sync_info)
|
|
ospf_ldp_sync_if_write_config(vty, params);
|
|
|
|
/* Capability opaque print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, opaque_capable) &&
|
|
params->opaque_capable !=
|
|
OSPF_OPAQUE_CAPABLE_DEFAULT) {
|
|
if (params->opaque_capable == false)
|
|
vty_out(vty,
|
|
" no ip ospf capability opaque");
|
|
else
|
|
vty_out(vty,
|
|
" ip ospf capability opaque");
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4", &rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* prefix-suppression print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params,
|
|
prefix_suppression) &&
|
|
params->prefix_suppression !=
|
|
OSPF_PREFIX_SUPPRESSION_DEFAULT) {
|
|
if (params->prefix_suppression == false)
|
|
vty_out(vty,
|
|
" no ip ospf prefix-suppression");
|
|
else
|
|
vty_out(vty,
|
|
" ip ospf prefix-suppression");
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4", &rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
/* neighbor-filter print. */
|
|
if (OSPF_IF_PARAM_CONFIGURED(params, nbr_filter_name)) {
|
|
vty_out(vty, " ip ospf neighbor-filter %s",
|
|
params->nbr_filter_name);
|
|
if (params != IF_DEF_PARAMS(ifp) && rn)
|
|
vty_out(vty, " %pI4", &rn->p.u.prefix4);
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
while (1) {
|
|
if (rn == NULL)
|
|
rn = route_top(IF_OIFS_PARAMS(ifp));
|
|
else
|
|
rn = route_next(rn);
|
|
|
|
if (rn == NULL)
|
|
break;
|
|
params = rn->info;
|
|
if (params != NULL)
|
|
break;
|
|
}
|
|
} while (rn);
|
|
|
|
ospf_opaque_config_write_if(vty, ifp);
|
|
|
|
if_vty_config_end(vty);
|
|
}
|
|
|
|
return write;
|
|
}
|
|
|
|
/* Configuration write function for ospfd. */
|
|
static int config_write_interface(struct vty *vty)
|
|
{
|
|
int write = 0;
|
|
struct vrf *vrf = NULL;
|
|
|
|
/* Display all VRF aware OSPF interface configuration */
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
|
write += config_write_interface_one(vty, vrf);
|
|
}
|
|
|
|
return write;
|
|
}
|
|
|
|
static int config_write_network_area(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
struct route_node *rn;
|
|
char buf[INET_ADDRSTRLEN];
|
|
|
|
/* `network area' print. */
|
|
for (rn = route_top(ospf->networks); rn; rn = route_next(rn))
|
|
if (rn->info) {
|
|
struct ospf_network *n = rn->info;
|
|
|
|
/* Create Area ID string by specified Area ID format. */
|
|
if (n->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
|
|
inet_ntop(AF_INET, &n->area_id, buf,
|
|
sizeof(buf));
|
|
else
|
|
snprintf(buf, sizeof(buf), "%lu",
|
|
(unsigned long int)ntohl(
|
|
n->area_id.s_addr));
|
|
|
|
/* Network print. */
|
|
vty_out(vty, " network %pFX area %s\n", &rn->p, buf);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
char buf[INET_ADDRSTRLEN];
|
|
|
|
/* Area configuration print. */
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
struct route_node *rn1;
|
|
|
|
area_id2str(buf, sizeof(buf), &area->area_id,
|
|
area->area_id_fmt);
|
|
|
|
if (area->auth_type != OSPF_AUTH_NULL) {
|
|
if (area->auth_type == OSPF_AUTH_SIMPLE)
|
|
vty_out(vty, " area %s authentication\n", buf);
|
|
else
|
|
vty_out(vty,
|
|
" area %s authentication message-digest\n",
|
|
buf);
|
|
}
|
|
|
|
if (area->shortcut_configured != OSPF_SHORTCUT_DEFAULT)
|
|
vty_out(vty, " area %s shortcut %s\n", buf,
|
|
ospf_shortcut_mode_str
|
|
[area->shortcut_configured]);
|
|
|
|
if ((area->external_routing == OSPF_AREA_STUB)
|
|
|| (area->external_routing == OSPF_AREA_NSSA)) {
|
|
if (area->external_routing == OSPF_AREA_STUB) {
|
|
vty_out(vty, " area %s stub", buf);
|
|
if (area->no_summary)
|
|
vty_out(vty, " no-summary\n");
|
|
vty_out(vty, "\n");
|
|
} else if (area->external_routing == OSPF_AREA_NSSA) {
|
|
vty_out(vty, " area %s nssa", buf);
|
|
|
|
switch (area->NSSATranslatorRole) {
|
|
case OSPF_NSSA_ROLE_NEVER:
|
|
vty_out(vty, " translate-never");
|
|
break;
|
|
case OSPF_NSSA_ROLE_ALWAYS:
|
|
vty_out(vty, " translate-always");
|
|
break;
|
|
case OSPF_NSSA_ROLE_CANDIDATE:
|
|
break;
|
|
}
|
|
|
|
if (area->nssa_default_originate.enabled) {
|
|
vty_out(vty,
|
|
" default-information-originate");
|
|
if (area->nssa_default_originate
|
|
.metric_value != -1)
|
|
vty_out(vty, " metric %d",
|
|
area->nssa_default_originate
|
|
.metric_value);
|
|
if (area->nssa_default_originate
|
|
.metric_type !=
|
|
DEFAULT_METRIC_TYPE)
|
|
vty_out(vty, " metric-type 1");
|
|
}
|
|
|
|
if (area->no_summary)
|
|
vty_out(vty, " no-summary");
|
|
if (area->suppress_fa)
|
|
vty_out(vty, " suppress-fa");
|
|
vty_out(vty, "\n");
|
|
|
|
for (rn1 = route_top(area->nssa_ranges); rn1;
|
|
rn1 = route_next(rn1)) {
|
|
struct ospf_area_range *range;
|
|
|
|
range = rn1->info;
|
|
if (!range)
|
|
continue;
|
|
|
|
vty_out(vty, " area %s nssa range %pFX",
|
|
buf, &rn1->p);
|
|
|
|
if (range->cost_config !=
|
|
OSPF_AREA_RANGE_COST_UNSPEC)
|
|
vty_out(vty, " cost %u",
|
|
range->cost_config);
|
|
|
|
if (!CHECK_FLAG(
|
|
range->flags,
|
|
OSPF_AREA_RANGE_ADVERTISE))
|
|
vty_out(vty, " not-advertise");
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
}
|
|
|
|
if (area->default_cost != 1)
|
|
vty_out(vty, " area %s default-cost %d\n", buf,
|
|
area->default_cost);
|
|
}
|
|
|
|
for (rn1 = route_top(area->ranges); rn1; rn1 = route_next(rn1))
|
|
if (rn1->info) {
|
|
struct ospf_area_range *range = rn1->info;
|
|
|
|
vty_out(vty, " area %s range %pFX", buf,
|
|
&rn1->p);
|
|
|
|
if (range->cost_config
|
|
!= OSPF_AREA_RANGE_COST_UNSPEC)
|
|
vty_out(vty, " cost %d",
|
|
range->cost_config);
|
|
|
|
if (!CHECK_FLAG(range->flags,
|
|
OSPF_AREA_RANGE_ADVERTISE))
|
|
vty_out(vty, " not-advertise");
|
|
|
|
if (CHECK_FLAG(range->flags,
|
|
OSPF_AREA_RANGE_SUBSTITUTE))
|
|
vty_out(vty, " substitute %pI4/%d",
|
|
&range->subst_addr,
|
|
range->subst_masklen);
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
if (EXPORT_NAME(area))
|
|
vty_out(vty, " area %s export-list %s\n", buf,
|
|
EXPORT_NAME(area));
|
|
|
|
if (IMPORT_NAME(area))
|
|
vty_out(vty, " area %s import-list %s\n", buf,
|
|
IMPORT_NAME(area));
|
|
|
|
if (PREFIX_NAME_IN(area))
|
|
vty_out(vty, " area %s filter-list prefix %s in\n", buf,
|
|
PREFIX_NAME_IN(area));
|
|
|
|
if (PREFIX_NAME_OUT(area))
|
|
vty_out(vty, " area %s filter-list prefix %s out\n",
|
|
buf, PREFIX_NAME_OUT(area));
|
|
|
|
if (area->fr_info.configured)
|
|
vty_out(vty, " area %s flood-reduction\n", buf);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_ospf_nbr_nbma(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
struct ospf_nbr_nbma *nbr_nbma;
|
|
struct route_node *rn;
|
|
|
|
/* Static Neighbor configuration print. */
|
|
for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
|
|
if ((nbr_nbma = rn->info)) {
|
|
vty_out(vty, " neighbor %pI4", &nbr_nbma->addr);
|
|
|
|
if (nbr_nbma->priority
|
|
!= OSPF_NEIGHBOR_PRIORITY_DEFAULT)
|
|
vty_out(vty, " priority %d",
|
|
nbr_nbma->priority);
|
|
|
|
if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
|
|
vty_out(vty, " poll-interval %d",
|
|
nbr_nbma->v_poll);
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_virtual_link(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
struct listnode *node;
|
|
struct ospf_vl_data *vl_data;
|
|
char buf[INET_ADDRSTRLEN];
|
|
char buf2[BUFSIZ];
|
|
int ret = 0;
|
|
|
|
/* Virtual-Link print */
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
|
|
struct listnode *n2;
|
|
struct crypt_key *ck;
|
|
struct ospf_interface *oi;
|
|
|
|
if (vl_data != NULL) {
|
|
area_id2str(buf, sizeof(buf), &vl_data->vl_area_id,
|
|
vl_data->vl_area_id_fmt);
|
|
oi = vl_data->vl_oi;
|
|
|
|
/* timers */
|
|
if (OSPF_IF_PARAM(oi, v_hello) !=
|
|
OSPF_HELLO_INTERVAL_DEFAULT ||
|
|
OSPF_IF_PARAM(oi, v_wait) !=
|
|
OSPF_ROUTER_DEAD_INTERVAL_DEFAULT ||
|
|
OSPF_IF_PARAM(oi, retransmit_interval) !=
|
|
OSPF_RETRANSMIT_INTERVAL_DEFAULT ||
|
|
OSPF_IF_PARAM(oi, retransmit_window) !=
|
|
OSPF_RETRANSMIT_WINDOW_DEFAULT ||
|
|
OSPF_IF_PARAM(oi, transmit_delay) !=
|
|
OSPF_TRANSMIT_DELAY_DEFAULT)
|
|
vty_out(vty,
|
|
" area %s virtual-link %pI4 hello-interval %d retransmit-interval %d retransmit-window %d transmit-delay %d dead-interval %d\n",
|
|
buf, &vl_data->vl_peer,
|
|
OSPF_IF_PARAM(oi, v_hello),
|
|
OSPF_IF_PARAM(oi, retransmit_interval),
|
|
OSPF_IF_PARAM(oi, retransmit_window),
|
|
OSPF_IF_PARAM(oi, transmit_delay),
|
|
OSPF_IF_PARAM(oi, v_wait));
|
|
else
|
|
vty_out(vty, " area %s virtual-link %pI4\n", buf,
|
|
&vl_data->vl_peer);
|
|
/* Auth type */
|
|
ret = interface_config_auth_str(
|
|
IF_DEF_PARAMS(oi->ifp), buf2);
|
|
if (ret)
|
|
vty_out(vty,
|
|
" area %s virtual-link %pI4 authentication%s\n",
|
|
buf, &vl_data->vl_peer, buf2);
|
|
/* Auth key */
|
|
if (IF_DEF_PARAMS(vl_data->vl_oi->ifp)->auth_simple[0]
|
|
!= '\0')
|
|
vty_out(vty,
|
|
" area %s virtual-link %pI4 authentication-key %s\n",
|
|
buf, &vl_data->vl_peer,
|
|
IF_DEF_PARAMS(vl_data->vl_oi->ifp)
|
|
->auth_simple);
|
|
/* md5 keys */
|
|
for (ALL_LIST_ELEMENTS_RO(
|
|
IF_DEF_PARAMS(vl_data->vl_oi->ifp)
|
|
->auth_crypt,
|
|
n2, ck))
|
|
vty_out(vty,
|
|
" area %s virtual-link %pI4 message-digest-key %d md5 %s\n",
|
|
buf, &vl_data->vl_peer,
|
|
ck->key_id, ck->auth_key);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int config_write_ospf_redistribute(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
int type;
|
|
|
|
/* redistribute print. */
|
|
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
|
|
struct list *red_list;
|
|
struct listnode *node;
|
|
struct ospf_redist *red;
|
|
|
|
red_list = ospf->redist[type];
|
|
if (!red_list)
|
|
continue;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
|
|
vty_out(vty, " redistribute %s",
|
|
zebra_route_string(type));
|
|
if (red->instance)
|
|
vty_out(vty, " %d", red->instance);
|
|
|
|
if (red->dmetric.value >= 0)
|
|
vty_out(vty, " metric %d", red->dmetric.value);
|
|
|
|
if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1)
|
|
vty_out(vty, " metric-type 1");
|
|
|
|
if (ROUTEMAP_NAME(red))
|
|
vty_out(vty, " route-map %s",
|
|
ROUTEMAP_NAME(red));
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ospf_cfg_write_helper_dis_rtr_walkcb(struct hash_bucket *bucket,
|
|
void *arg)
|
|
{
|
|
struct advRtr *rtr = bucket->data;
|
|
struct vty *vty = (struct vty *)arg;
|
|
|
|
vty_out(vty, " graceful-restart helper enable %pI4\n",
|
|
&rtr->advRtrAddr);
|
|
return HASHWALK_CONTINUE;
|
|
}
|
|
|
|
static void config_write_ospf_gr(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
if (!ospf->gr_info.restart_support)
|
|
return;
|
|
|
|
if (ospf->gr_info.grace_period == OSPF_DFLT_GRACE_INTERVAL)
|
|
vty_out(vty, " graceful-restart\n");
|
|
else
|
|
vty_out(vty, " graceful-restart grace-period %u\n",
|
|
ospf->gr_info.grace_period);
|
|
}
|
|
|
|
static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
if (ospf->is_helper_supported)
|
|
vty_out(vty, " graceful-restart helper enable\n");
|
|
|
|
if (!ospf->strict_lsa_check)
|
|
vty_out(vty,
|
|
" no graceful-restart helper strict-lsa-checking\n");
|
|
|
|
if (ospf->only_planned_restart)
|
|
vty_out(vty, " graceful-restart helper planned-only\n");
|
|
|
|
if (ospf->supported_grace_time != OSPF_MAX_GRACE_INTERVAL)
|
|
vty_out(vty,
|
|
" graceful-restart helper supported-grace-time %d\n",
|
|
ospf->supported_grace_time);
|
|
|
|
if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
|
|
hash_walk(ospf->enable_rtr_list,
|
|
ospf_cfg_write_helper_dis_rtr_walkcb, vty);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_ospf_external_aggregator(struct vty *vty,
|
|
struct ospf *ospf)
|
|
{
|
|
struct route_node *rn;
|
|
|
|
if (ospf->aggr_delay_interval != OSPF_EXTL_AGGR_DEFAULT_DELAY)
|
|
vty_out(vty, " aggregation timer %u\n",
|
|
ospf->aggr_delay_interval);
|
|
|
|
/* print 'summary-address A.B.C.D/M' */
|
|
for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn))
|
|
if (rn->info) {
|
|
struct ospf_external_aggr_rt *aggr = rn->info;
|
|
|
|
vty_out(vty, " summary-address %pI4/%d",
|
|
&aggr->p.prefix, aggr->p.prefixlen);
|
|
if (aggr->tag)
|
|
vty_out(vty, " tag %u", aggr->tag);
|
|
|
|
if (CHECK_FLAG(aggr->flags,
|
|
OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
|
|
vty_out(vty, " no-advertise");
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_ospf_default_metric(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
if (ospf->default_metric != -1)
|
|
vty_out(vty, " default-metric %d\n", ospf->default_metric);
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_ospf_distribute(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
int type;
|
|
struct ospf_redist *red;
|
|
|
|
if (ospf) {
|
|
/* distribute-list print. */
|
|
for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
|
|
if (DISTRIBUTE_NAME(ospf, type))
|
|
vty_out(vty, " distribute-list %s out %s\n",
|
|
DISTRIBUTE_NAME(ospf, type),
|
|
zebra_route_string(type));
|
|
|
|
/* default-information print. */
|
|
if (ospf->default_originate != DEFAULT_ORIGINATE_NONE) {
|
|
vty_out(vty, " default-information originate");
|
|
if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
|
|
vty_out(vty, " always");
|
|
|
|
red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0);
|
|
if (red) {
|
|
if (red->dmetric.value >= 0)
|
|
vty_out(vty, " metric %d",
|
|
red->dmetric.value);
|
|
|
|
if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1)
|
|
vty_out(vty, " metric-type 1");
|
|
|
|
if (ROUTEMAP_NAME(red))
|
|
vty_out(vty, " route-map %s",
|
|
ROUTEMAP_NAME(red));
|
|
}
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
struct route_node *rn;
|
|
struct ospf_distance *odistance;
|
|
|
|
if (ospf->distance_all)
|
|
vty_out(vty, " distance %d\n", ospf->distance_all);
|
|
|
|
if (ospf->distance_intra || ospf->distance_inter
|
|
|| ospf->distance_external) {
|
|
vty_out(vty, " distance ospf");
|
|
|
|
if (ospf->distance_intra)
|
|
vty_out(vty, " intra-area %d", ospf->distance_intra);
|
|
if (ospf->distance_inter)
|
|
vty_out(vty, " inter-area %d", ospf->distance_inter);
|
|
if (ospf->distance_external)
|
|
vty_out(vty, " external %d", ospf->distance_external);
|
|
|
|
vty_out(vty, "\n");
|
|
}
|
|
|
|
for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
|
|
if ((odistance = rn->info) != NULL) {
|
|
vty_out(vty, " distance %d %pFX %s\n",
|
|
odistance->distance, &rn->p,
|
|
odistance->access_list ? odistance->access_list
|
|
: "");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
|
|
{
|
|
int write = 0;
|
|
|
|
/* `router ospf' print. */
|
|
if (ospf->instance && strcmp(ospf->name, VRF_DEFAULT_NAME)) {
|
|
vty_out(vty, "router ospf %d vrf %s\n", ospf->instance,
|
|
ospf->name);
|
|
} else if (ospf->instance) {
|
|
vty_out(vty, "router ospf %d\n", ospf->instance);
|
|
} else if (strcmp(ospf->name, VRF_DEFAULT_NAME)) {
|
|
vty_out(vty, "router ospf vrf %s\n", ospf->name);
|
|
} else
|
|
vty_out(vty, "router ospf\n");
|
|
|
|
if (!ospf->networks) {
|
|
write++;
|
|
return write;
|
|
}
|
|
|
|
/* Router ID print. */
|
|
if (ospf->router_id_static.s_addr != INADDR_ANY)
|
|
vty_out(vty, " ospf router-id %pI4\n",
|
|
&ospf->router_id_static);
|
|
|
|
/* zebra opaque attributes configuration. */
|
|
if (CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA))
|
|
vty_out(vty, " ospf send-extra-data zebra\n");
|
|
|
|
/* ABR type print. */
|
|
if (ospf->abr_type != OSPF_ABR_DEFAULT)
|
|
vty_out(vty, " ospf abr-type %s\n",
|
|
ospf_abr_type_str[ospf->abr_type]);
|
|
|
|
/* log-adjacency-changes flag print. */
|
|
if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES)) {
|
|
if (CHECK_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
|
|
vty_out(vty, " log-adjacency-changes detail\n");
|
|
else if (!SAVE_OSPF_LOG_ADJACENCY_CHANGES)
|
|
vty_out(vty, " log-adjacency-changes\n");
|
|
} else if (SAVE_OSPF_LOG_ADJACENCY_CHANGES) {
|
|
vty_out(vty, " no log-adjacency-changes\n");
|
|
}
|
|
|
|
/* RFC1583 compatibility flag print -- Compatible with CISCO
|
|
* 12.1. */
|
|
if (CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE))
|
|
vty_out(vty, " compatible rfc1583\n");
|
|
|
|
/* auto-cost reference-bandwidth configuration. */
|
|
if (ospf->ref_bandwidth != OSPF_DEFAULT_REF_BANDWIDTH) {
|
|
vty_out(vty,
|
|
"! Important: ensure reference bandwidth is consistent across all routers\n");
|
|
vty_out(vty, " auto-cost reference-bandwidth %d\n",
|
|
ospf->ref_bandwidth);
|
|
}
|
|
|
|
/* SPF timers print. */
|
|
if (ospf->spf_delay != OSPF_SPF_DELAY_DEFAULT
|
|
|| ospf->spf_holdtime != OSPF_SPF_HOLDTIME_DEFAULT
|
|
|| ospf->spf_max_holdtime != OSPF_SPF_MAX_HOLDTIME_DEFAULT)
|
|
vty_out(vty, " timers throttle spf %d %d %d\n", ospf->spf_delay,
|
|
ospf->spf_holdtime, ospf->spf_max_holdtime);
|
|
|
|
/* LSA timers print. */
|
|
if (ospf->min_ls_interval != OSPF_MIN_LS_INTERVAL)
|
|
vty_out(vty, " timers throttle lsa all %d\n",
|
|
ospf->min_ls_interval);
|
|
if (ospf->min_ls_arrival != OSPF_MIN_LS_ARRIVAL)
|
|
vty_out(vty, " timers lsa min-arrival %d\n",
|
|
ospf->min_ls_arrival);
|
|
|
|
/* Write multiplier print. */
|
|
if (ospf->write_oi_count != OSPF_WRITE_INTERFACE_COUNT_DEFAULT)
|
|
vty_out(vty, " ospf write-multiplier %d\n",
|
|
ospf->write_oi_count);
|
|
|
|
if (ospf->max_multipath != MULTIPATH_NUM)
|
|
vty_out(vty, " maximum-paths %d\n", ospf->max_multipath);
|
|
|
|
/* Max-metric router-lsa print */
|
|
config_write_stub_router(vty, ospf);
|
|
|
|
/* SPF refresh parameters print. */
|
|
if (ospf->lsa_refresh_interval != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
|
|
vty_out(vty, " refresh timer %d\n", ospf->lsa_refresh_interval);
|
|
|
|
if (ospf->fr_configured)
|
|
vty_out(vty, " flood-reduction\n");
|
|
|
|
if (!ospf->intf_socket_enabled)
|
|
vty_out(vty, " no socket-per-interface\n");
|
|
|
|
/* Redistribute information print. */
|
|
config_write_ospf_redistribute(vty, ospf);
|
|
|
|
/* Graceful Restart print */
|
|
config_write_ospf_gr(vty, ospf);
|
|
config_write_ospf_gr_helper(vty, ospf);
|
|
|
|
/* Print external route aggregation. */
|
|
config_write_ospf_external_aggregator(vty, ospf);
|
|
|
|
/* passive-interface print. */
|
|
if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
|
|
vty_out(vty, " passive-interface default\n");
|
|
|
|
/* proactive-arp print. */
|
|
if (ospf->proactive_arp != OSPF_PROACTIVE_ARP_DEFAULT) {
|
|
if (ospf->proactive_arp)
|
|
vty_out(vty, " proactive-arp\n");
|
|
else
|
|
vty_out(vty, " no proactive-arp\n");
|
|
}
|
|
|
|
/* TI-LFA print. */
|
|
if (ospf->ti_lfa_enabled) {
|
|
if (ospf->ti_lfa_protection_type == OSPF_TI_LFA_NODE_PROTECTION)
|
|
vty_out(vty, " fast-reroute ti-lfa node-protection\n");
|
|
else
|
|
vty_out(vty, " fast-reroute ti-lfa\n");
|
|
}
|
|
|
|
/* Network area print. */
|
|
config_write_network_area(vty, ospf);
|
|
|
|
/* Area config print. */
|
|
config_write_ospf_area(vty, ospf);
|
|
|
|
/* static neighbor print. */
|
|
config_write_ospf_nbr_nbma(vty, ospf);
|
|
|
|
/* Virtual-Link print. */
|
|
config_write_virtual_link(vty, ospf);
|
|
|
|
/* Default metric configuration. */
|
|
config_write_ospf_default_metric(vty, ospf);
|
|
|
|
/* Distribute-list and default-information print. */
|
|
config_write_ospf_distribute(vty, ospf);
|
|
|
|
/* Distance configuration. */
|
|
config_write_ospf_distance(vty, ospf);
|
|
|
|
ospf_opaque_config_write_router(vty, ospf);
|
|
|
|
/* LDP-Sync print */
|
|
ospf_ldp_sync_write_config(vty, ospf);
|
|
|
|
/* Socket buffer sizes */
|
|
if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE) {
|
|
if (ospf->send_sock_bufsize == ospf->recv_sock_bufsize)
|
|
vty_out(vty, " socket buffer all %u\n",
|
|
ospf->recv_sock_bufsize);
|
|
else
|
|
vty_out(vty, " socket buffer recv %u\n",
|
|
ospf->recv_sock_bufsize);
|
|
}
|
|
|
|
if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE &&
|
|
ospf->send_sock_bufsize != ospf->recv_sock_bufsize)
|
|
vty_out(vty, " socket buffer send %u\n",
|
|
ospf->send_sock_bufsize);
|
|
|
|
|
|
vty_out(vty, "exit\n");
|
|
|
|
write++;
|
|
return write;
|
|
}
|
|
|
|
/* OSPF configuration write function. */
|
|
static int ospf_config_write(struct vty *vty)
|
|
{
|
|
struct ospf *ospf;
|
|
struct listnode *ospf_node = NULL;
|
|
int write = 0;
|
|
|
|
if (listcount(om->ospf) == 0)
|
|
return write;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, ospf_node, ospf)) {
|
|
/* VRF Default check if it is running.
|
|
* Upon daemon start, there could be default instance
|
|
* in absence of 'router ospf'/oi_running is disabled. */
|
|
if (ospf->vrf_id == VRF_DEFAULT && ospf->oi_running)
|
|
write += ospf_config_write_one(vty, ospf);
|
|
/* For Non-Default VRF simply display the configuration,
|
|
* even if it is not oi_running. */
|
|
else if (ospf->vrf_id != VRF_DEFAULT)
|
|
write += ospf_config_write_one(vty, ospf);
|
|
}
|
|
return write;
|
|
}
|
|
|
|
void ospf_vty_show_init(void)
|
|
{
|
|
/* "show ip ospf" commands. */
|
|
install_element(VIEW_NODE, &show_ip_ospf_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_cmd);
|
|
|
|
/* "show ip ospf database" commands. */
|
|
install_element(VIEW_NODE, &show_ip_ospf_database_cmd);
|
|
|
|
/* "show ip ospf interface" commands. */
|
|
install_element(VIEW_NODE, &show_ip_ospf_interface_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_interface_cmd);
|
|
/* "show ip ospf interface traffic */
|
|
install_element(VIEW_NODE, &show_ip_ospf_interface_traffic_cmd);
|
|
|
|
/* "show ip ospf neighbor" commands. */
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_id_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_detail_all_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_detail_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_neighbor_all_cmd);
|
|
|
|
install_element(VIEW_NODE,
|
|
&show_ip_ospf_instance_neighbor_int_detail_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_int_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_id_cmd);
|
|
install_element(VIEW_NODE,
|
|
&show_ip_ospf_instance_neighbor_detail_all_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_neighbor_all_cmd);
|
|
|
|
/* "show ip ospf route" commands. */
|
|
install_element(VIEW_NODE, &show_ip_ospf_route_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_border_routers_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_reachable_routers_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_route_cmd);
|
|
install_element(VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd);
|
|
install_element(VIEW_NODE,
|
|
&show_ip_ospf_instance_reachable_routers_cmd);
|
|
|
|
/* "show ip ospf vrfs" commands. */
|
|
install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
|
|
|
|
/* "show ip ospf gr-helper details" command */
|
|
install_element(VIEW_NODE, &show_ip_ospf_gr_helper_cmd);
|
|
|
|
/* "show ip ospf summary-address" command */
|
|
install_element(VIEW_NODE, &show_ip_ospf_external_aggregator_cmd);
|
|
}
|
|
|
|
/* Initialization of OSPF interface. */
|
|
static void ospf_vty_if_init(void)
|
|
{
|
|
/* Install interface node. */
|
|
if_cmd_init(config_write_interface);
|
|
|
|
/* "ip ospf authentication" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_authentication_args_addr_cmd);
|
|
install_element(INTERFACE_NODE, &ip_ospf_authentication_addr_cmd);
|
|
install_element(INTERFACE_NODE,
|
|
&no_ip_ospf_authentication_args_addr_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_authentication_addr_cmd);
|
|
install_element(INTERFACE_NODE, &ip_ospf_authentication_key_addr_cmd);
|
|
install_element(INTERFACE_NODE,
|
|
&no_ip_ospf_authentication_key_authkey_addr_cmd);
|
|
install_element(INTERFACE_NODE,
|
|
&no_ospf_authentication_key_authkey_addr_cmd);
|
|
|
|
/* "ip ospf message-digest-key" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_message_digest_key_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_message_digest_key_cmd);
|
|
|
|
/* "ip ospf cost" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_cost_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_cost_cmd);
|
|
|
|
/* "ip ospf mtu-ignore" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_mtu_ignore_addr_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_mtu_ignore_addr_cmd);
|
|
|
|
/* "ip ospf dead-interval" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_dead_interval_cmd);
|
|
install_element(INTERFACE_NODE,
|
|
&ip_ospf_dead_interval_minimal_addr_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_dead_interval_cmd);
|
|
|
|
/* "ip ospf hello-interval" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_hello_interval_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_hello_interval_cmd);
|
|
|
|
/* "ip ospf graceful-restart" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_gr_hdelay_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_gr_hdelay_cmd);
|
|
|
|
/* "ip ospf network" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_network_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_network_cmd);
|
|
|
|
/* "ip ospf priority" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_priority_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_priority_cmd);
|
|
|
|
/* "ip ospf retransmit-interval" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_retransmit_interval_addr_cmd);
|
|
install_element(INTERFACE_NODE,
|
|
&no_ip_ospf_retransmit_interval_addr_cmd);
|
|
|
|
/* "ip ospf retransmit-window" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_retransmit_window_addr_cmd);
|
|
|
|
/* "ip ospf transmit-delay" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_transmit_delay_addr_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd);
|
|
|
|
/* "ip ospf area" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_area_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_area_cmd);
|
|
|
|
/* "ip ospf passive" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_passive_cmd);
|
|
install_element(INTERFACE_NODE, &no_ip_ospf_passive_cmd);
|
|
|
|
/* "ip ospf capability opaque" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_capability_opaque_addr_cmd);
|
|
|
|
/* "ip ospf prefix-suppression" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_prefix_suppression_addr_cmd);
|
|
|
|
/* "ip ospf neighbor-filter" commands. */
|
|
install_element(INTERFACE_NODE, &ip_ospf_neighbor_filter_addr_cmd);
|
|
|
|
/* These commands are compatibitliy for previous version. */
|
|
install_element(INTERFACE_NODE, &ospf_authentication_key_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_message_digest_key_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_message_digest_key_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_dead_interval_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_dead_interval_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_hello_interval_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_hello_interval_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_cost_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_cost_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_network_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_network_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_priority_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_priority_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_retransmit_interval_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_retransmit_interval_cmd);
|
|
install_element(INTERFACE_NODE, &ospf_transmit_delay_cmd);
|
|
install_element(INTERFACE_NODE, &no_ospf_transmit_delay_cmd);
|
|
}
|
|
|
|
static void ospf_vty_zebra_init(void)
|
|
{
|
|
install_element(OSPF_NODE, &ospf_redistribute_source_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_redistribute_source_cmd);
|
|
install_element(OSPF_NODE, &ospf_redistribute_instance_source_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_redistribute_instance_source_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_distribute_list_out_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_distribute_list_out_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_default_information_originate_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_default_information_originate_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_default_metric_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_default_metric_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_distance_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_distance_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd);
|
|
install_element(OSPF_NODE, &ospf_distance_ospf_cmd);
|
|
|
|
/*Ospf garcefull restart helper configurations */
|
|
install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd);
|
|
install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd);
|
|
install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_gr_helper_supported_grace_time_cmd);
|
|
install_element(OSPF_NODE, &ospf_gr_helper_planned_only_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_gr_helper_planned_only_cmd);
|
|
|
|
/* External LSA summarisation config commands.*/
|
|
install_element(OSPF_NODE, &ospf_external_route_aggregation_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_external_route_aggregation_cmd);
|
|
install_element(OSPF_NODE,
|
|
&ospf_external_route_aggregation_no_adrvertise_cmd);
|
|
install_element(OSPF_NODE,
|
|
&no_ospf_external_route_aggregation_no_adrvertise_cmd);
|
|
install_element(OSPF_NODE, &ospf_route_aggregation_timer_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_route_aggregation_timer_cmd);
|
|
}
|
|
|
|
static int ospf_config_write(struct vty *vty);
|
|
static struct cmd_node ospf_node = {
|
|
.name = "ospf",
|
|
.node = OSPF_NODE,
|
|
.parent_node = CONFIG_NODE,
|
|
.prompt = "%s(config-router)# ",
|
|
.config_write = ospf_config_write,
|
|
};
|
|
|
|
static void ospf_interface_clear(struct interface *ifp)
|
|
{
|
|
if (!if_is_operative(ifp))
|
|
return;
|
|
|
|
if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
|
|
zlog_debug("ISM[%s]: clear by reset", ifp->name);
|
|
|
|
ospf_if_reset(ifp);
|
|
}
|
|
|
|
DEFUN (clear_ip_ospf_interface,
|
|
clear_ip_ospf_interface_cmd,
|
|
"clear ip ospf [vrf NAME] interface [IFNAME]",
|
|
CLEAR_STR
|
|
IP_STR
|
|
"OSPF information\n"
|
|
VRF_CMD_HELP_STR
|
|
"Interface information\n"
|
|
"Interface name\n")
|
|
{
|
|
int idx_ifname = 0;
|
|
int idx_vrf = 0;
|
|
struct interface *ifp;
|
|
struct listnode *node;
|
|
struct ospf *ospf = NULL;
|
|
char *vrf_name = NULL;
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
struct vrf *vrf = NULL;
|
|
|
|
if (argv_find(argv, argc, "vrf", &idx_vrf))
|
|
vrf_name = argv[idx_vrf + 1]->arg;
|
|
if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
|
|
vrf_name = NULL;
|
|
if (vrf_name) {
|
|
vrf = vrf_lookup_by_name(vrf_name);
|
|
if (vrf)
|
|
vrf_id = vrf->vrf_id;
|
|
}
|
|
if (!argv_find(argv, argc, "IFNAME", &idx_ifname)) {
|
|
/* Clear all the ospfv2 interfaces. */
|
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
|
if (vrf_id != ospf->vrf_id)
|
|
continue;
|
|
if (!vrf)
|
|
vrf = vrf_lookup_by_id(ospf->vrf_id);
|
|
FOR_ALL_INTERFACES (vrf, ifp)
|
|
ospf_interface_clear(ifp);
|
|
}
|
|
} else {
|
|
/* Interface name is specified. */
|
|
ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
|
|
if (ifp == NULL)
|
|
vty_out(vty, "No such interface name\n");
|
|
else
|
|
ospf_interface_clear(ifp);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY_HIDDEN(ospf_lsa_refresh_timer, ospf_lsa_refresh_timer_cmd,
|
|
"[no$no] ospf lsa-refresh [(120-1800)]$value",
|
|
NO_STR OSPF_STR
|
|
"OSPF lsa refresh timer\n"
|
|
"timer value in seconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
|
|
|
|
if (no)
|
|
ospf->lsa_refresh_timer = OSPF_LS_REFRESH_TIME;
|
|
else
|
|
ospf->lsa_refresh_timer = value;
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY_HIDDEN(ospf_maxage_delay_timer, ospf_maxage_delay_timer_cmd,
|
|
"[no$no] ospf maxage-delay [(0-60)]$value",
|
|
NO_STR OSPF_STR
|
|
"OSPF lsa maxage delay timer\n"
|
|
"timer value in seconds\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
|
|
|
|
if (no)
|
|
ospf->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
|
|
else
|
|
ospf->maxage_delay = value;
|
|
|
|
EVENT_OFF(ospf->t_maxage);
|
|
OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover,
|
|
ospf->maxage_delay);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------*
|
|
* Following is (vty) configuration functions for flood-reduction handling.
|
|
* ------------------------------------------------------------------------
|
|
*/
|
|
|
|
DEFPY(flood_reduction, flood_reduction_cmd, "flood-reduction",
|
|
"flood reduction feature\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
|
|
struct ospf_area *area;
|
|
struct listnode *node;
|
|
|
|
/* Turn on the Flood Reduction feature for the router. */
|
|
if (!ospf->fr_configured) {
|
|
ospf->fr_configured = true;
|
|
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
|
"Flood Reduction: OFF -> ON");
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
if (area) {
|
|
ospf_area_update_fr_state(area);
|
|
ospf_refresh_area_self_lsas(area);
|
|
}
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(flood_reduction_area, flood_reduction_area_cmd,
|
|
"area <A.B.C.D|(0-4294967295)> flood-reduction",
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Enable flood reduction for area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
|
|
struct ospf_area *oa;
|
|
int idx = 1;
|
|
int format;
|
|
int ret;
|
|
const char *areaid;
|
|
struct in_addr area_id;
|
|
|
|
areaid = argv[idx]->arg;
|
|
|
|
ret = str2area_id(areaid, &area_id, &format);
|
|
if (ret < 0) {
|
|
vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
oa = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (!oa) {
|
|
vty_out(vty, "OSPF area ID not present\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* Turn on the Flood Reduction feature for the area. */
|
|
if (!oa->fr_info.configured) {
|
|
oa->fr_info.configured = true;
|
|
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
|
"Flood Reduction area %pI4 : OFF -> ON",
|
|
&oa->area_id);
|
|
ospf_area_update_fr_state(oa);
|
|
ospf_refresh_area_self_lsas(oa);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(no_flood_reduction, no_flood_reduction_cmd, "no flood-reduction",
|
|
NO_STR "flood reduction feature\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
|
|
struct listnode *node;
|
|
struct ospf_area *area;
|
|
|
|
/* Turn off the Flood Reduction feature for the router. */
|
|
if (ospf->fr_configured) {
|
|
ospf->fr_configured = false;
|
|
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
|
"Flood Reduction: ON -> OFF");
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
if (area) {
|
|
ospf_area_update_fr_state(area);
|
|
ospf_refresh_area_self_lsas(area);
|
|
}
|
|
}
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(no_flood_reduction_area, no_flood_reduction_area_cmd,
|
|
"no area <A.B.C.D|(0-4294967295)> flood-reduction",
|
|
NO_STR
|
|
"OSPF area parameters\n"
|
|
"OSPF area ID in IP address format\n"
|
|
"OSPF area ID as a decimal value\n"
|
|
"Disable flood reduction for area\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
|
|
struct ospf_area *oa;
|
|
int idx = 2;
|
|
int format;
|
|
int ret;
|
|
const char *areaid;
|
|
struct in_addr area_id;
|
|
|
|
areaid = argv[idx]->arg;
|
|
|
|
ret = str2area_id(areaid, &area_id, &format);
|
|
if (ret < 0) {
|
|
vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
oa = ospf_area_lookup_by_area_id(ospf, area_id);
|
|
if (!oa) {
|
|
vty_out(vty, "OSPF area ID not present\n");
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
}
|
|
|
|
/* Turn off the Flood Reduction feature for the area. */
|
|
if (oa->fr_info.configured) {
|
|
oa->fr_info.configured = false;
|
|
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
|
"Flood Reduction area %pI4 : ON -> OFF",
|
|
&oa->area_id);
|
|
ospf_area_update_fr_state(oa);
|
|
ospf_refresh_area_self_lsas(oa);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY(ospf_socket_bufsizes,
|
|
ospf_socket_bufsizes_cmd,
|
|
"[no] socket buffer <send$send_val | recv$recv_val | all$all_val> \
|
|
![(1-4000000000)$bufsize]",
|
|
NO_STR
|
|
"Socket parameters\n"
|
|
"Buffer size configuration\n"
|
|
"Send buffer size\n"
|
|
"Receive buffer size\n"
|
|
"Both send and receive buffer sizes\n"
|
|
"Buffer size, in bytes\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
uint32_t recvsz, sendsz;
|
|
|
|
if (no)
|
|
bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
|
|
|
|
if (all_val) {
|
|
recvsz = bufsize;
|
|
sendsz = bufsize;
|
|
} else if (send_val) {
|
|
sendsz = bufsize;
|
|
recvsz = ospf->recv_sock_bufsize;
|
|
} else if (recv_val) {
|
|
recvsz = bufsize;
|
|
sendsz = ospf->send_sock_bufsize;
|
|
} else
|
|
return CMD_SUCCESS;
|
|
|
|
/* React to a change by modifying existing sockets */
|
|
ospf_update_bufsize(ospf, recvsz, sendsz);
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
DEFPY (per_intf_socket,
|
|
per_intf_socket_cmd,
|
|
"[no] socket-per-interface",
|
|
NO_STR
|
|
"Use write socket per interface\n")
|
|
{
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
|
struct listnode *node;
|
|
struct ospf_interface *oi;
|
|
|
|
if (no) {
|
|
if (ospf->intf_socket_enabled) {
|
|
ospf->intf_socket_enabled = false;
|
|
|
|
/* Iterate and close any sockets */
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
|
|
ospf_ifp_sock_close(oi->ifp);
|
|
}
|
|
} else if (!ospf->intf_socket_enabled) {
|
|
ospf->intf_socket_enabled = true;
|
|
|
|
/* Iterate and open sockets */
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
|
|
ospf_ifp_sock_init(oi->ifp);
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
}
|
|
|
|
void ospf_vty_clear_init(void)
|
|
{
|
|
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
|
|
install_element(ENABLE_NODE, &clear_ip_ospf_process_cmd);
|
|
install_element(ENABLE_NODE, &clear_ip_ospf_neighbor_cmd);
|
|
}
|
|
|
|
|
|
/* Install OSPF related vty commands. */
|
|
void ospf_vty_init(void)
|
|
{
|
|
/* Install ospf top node. */
|
|
install_node(&ospf_node);
|
|
|
|
/* "router ospf" commands. */
|
|
install_element(CONFIG_NODE, &router_ospf_cmd);
|
|
install_element(CONFIG_NODE, &no_router_ospf_cmd);
|
|
|
|
|
|
install_default(OSPF_NODE);
|
|
|
|
/* "ospf router-id" commands. */
|
|
install_element(OSPF_NODE, &ospf_router_id_cmd);
|
|
install_element(OSPF_NODE, &ospf_router_id_old_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_router_id_cmd);
|
|
install_element(OSPF_NODE, &no_router_id_cmd);
|
|
|
|
/* "passive-interface" commands. */
|
|
install_element(OSPF_NODE, &ospf_passive_interface_default_cmd);
|
|
install_element(OSPF_NODE, &ospf_passive_interface_addr_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_passive_interface_default_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_passive_interface_addr_cmd);
|
|
|
|
/* "ospf abr-type" commands. */
|
|
install_element(OSPF_NODE, &ospf_abr_type_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_abr_type_cmd);
|
|
|
|
/* "ospf log-adjacency-changes" commands. */
|
|
install_element(OSPF_NODE, &ospf_log_adjacency_changes_cmd);
|
|
install_element(OSPF_NODE, &ospf_log_adjacency_changes_detail_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_log_adjacency_changes_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_log_adjacency_changes_detail_cmd);
|
|
|
|
/* "ospf rfc1583-compatible" commands. */
|
|
install_element(OSPF_NODE, &ospf_compatible_rfc1583_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_compatible_rfc1583_cmd);
|
|
install_element(OSPF_NODE, &ospf_rfc1583_flag_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_rfc1583_flag_cmd);
|
|
|
|
/* "ospf send-extra-data zebra" commands. */
|
|
install_element(OSPF_NODE, &ospf_send_extra_data_cmd);
|
|
|
|
/* "network area" commands. */
|
|
install_element(OSPF_NODE, &ospf_network_area_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_network_area_cmd);
|
|
|
|
/* "area authentication" commands. */
|
|
install_element(OSPF_NODE,
|
|
&ospf_area_authentication_message_digest_cmd);
|
|
install_element(OSPF_NODE, &ospf_area_authentication_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_authentication_cmd);
|
|
|
|
/* "area range" commands. */
|
|
install_element(OSPF_NODE, &ospf_area_range_cmd);
|
|
install_element(OSPF_NODE, &ospf_area_range_cost_cmd);
|
|
install_element(OSPF_NODE, &ospf_area_range_not_advertise_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_range_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_range_substitute_cmd);
|
|
|
|
/* "area virtual-link" commands. */
|
|
install_element(OSPF_NODE, &ospf_area_vlink_cmd);
|
|
install_element(OSPF_NODE, &ospf_area_vlink_intervals_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_vlink_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_vlink_intervals_cmd);
|
|
|
|
|
|
/* "area stub" commands. */
|
|
install_element(OSPF_NODE, &ospf_area_stub_no_summary_cmd);
|
|
install_element(OSPF_NODE, &ospf_area_stub_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_stub_no_summary_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_stub_cmd);
|
|
|
|
/* "area nssa" commands. */
|
|
install_element(OSPF_NODE, &ospf_area_nssa_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_nssa_cmd);
|
|
install_element(OSPF_NODE, &ospf_area_nssa_range_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_nssa_range_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_area_default_cost_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_default_cost_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_area_shortcut_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_shortcut_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_area_export_list_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_export_list_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_area_filter_list_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_filter_list_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_area_import_list_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_area_import_list_cmd);
|
|
|
|
/* SPF timer commands */
|
|
install_element(OSPF_NODE, &ospf_timers_throttle_spf_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_timers_throttle_spf_cmd);
|
|
|
|
/* LSA timers commands */
|
|
install_element(OSPF_NODE, &ospf_timers_min_ls_interval_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd);
|
|
install_element(OSPF_NODE, &ospf_timers_lsa_min_arrival_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_timers_lsa_min_arrival_cmd);
|
|
|
|
/* refresh timer commands */
|
|
install_element(OSPF_NODE, &ospf_refresh_timer_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_refresh_timer_val_cmd);
|
|
|
|
/* max-metric commands */
|
|
install_element(OSPF_NODE, &ospf_max_metric_router_lsa_admin_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_admin_cmd);
|
|
install_element(OSPF_NODE, &ospf_max_metric_router_lsa_startup_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_startup_cmd);
|
|
install_element(OSPF_NODE, &ospf_max_metric_router_lsa_shutdown_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_max_metric_router_lsa_shutdown_cmd);
|
|
|
|
/* reference bandwidth commands */
|
|
install_element(OSPF_NODE, &ospf_auto_cost_reference_bandwidth_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_auto_cost_reference_bandwidth_cmd);
|
|
|
|
/* "neighbor" command. */
|
|
install_element(OSPF_NODE, &ospf_neighbor_cmd);
|
|
|
|
/* write multiplier commands */
|
|
install_element(OSPF_NODE, &ospf_write_multiplier_cmd);
|
|
install_element(OSPF_NODE, &write_multiplier_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_write_multiplier_cmd);
|
|
install_element(OSPF_NODE, &no_write_multiplier_cmd);
|
|
|
|
/* "proactive-arp" commands. */
|
|
install_element(OSPF_NODE, &ospf_proactive_arp_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_proactive_arp_cmd);
|
|
|
|
/* TI-LFA commands */
|
|
install_element(OSPF_NODE, &ospf_ti_lfa_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_ti_lfa_cmd);
|
|
|
|
/* Max path configurations */
|
|
install_element(OSPF_NODE, &ospf_max_multipath_cmd);
|
|
install_element(OSPF_NODE, &no_ospf_max_multipath_cmd);
|
|
|
|
vrf_cmd_init(NULL);
|
|
|
|
install_element(OSPF_NODE, &ospf_lsa_refresh_timer_cmd);
|
|
install_element(OSPF_NODE, &ospf_maxage_delay_timer_cmd);
|
|
|
|
/* Flood Reduction commands */
|
|
install_element(OSPF_NODE, &flood_reduction_cmd);
|
|
install_element(OSPF_NODE, &no_flood_reduction_cmd);
|
|
install_element(OSPF_NODE, &flood_reduction_area_cmd);
|
|
install_element(OSPF_NODE, &no_flood_reduction_area_cmd);
|
|
|
|
install_element(OSPF_NODE, &ospf_socket_bufsizes_cmd);
|
|
install_element(OSPF_NODE, &per_intf_socket_cmd);
|
|
|
|
/* Init interface related vty commands. */
|
|
ospf_vty_if_init();
|
|
|
|
/* Init zebra related vty commands. */
|
|
ospf_vty_zebra_init();
|
|
}
|