2002-12-13 21:15:29 +01:00
|
|
|
/*
|
2004-05-18 20:57:06 +02:00
|
|
|
* Copyright (C) 2003 Yasuhiro Ohara
|
2002-12-13 21:15:29 +01:00
|
|
|
*
|
|
|
|
* This file is part of GNU Zebra.
|
|
|
|
*
|
|
|
|
* GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
* later version.
|
|
|
|
*
|
|
|
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "log.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "vty.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "command.h"
|
2017-03-09 19:00:19 +01:00
|
|
|
#include "defaults.h"
|
2020-10-13 14:44:52 +02:00
|
|
|
#include "lib/json.h"
|
2020-09-05 09:07:25 +02:00
|
|
|
#include "lib_errors.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "ospf6_proto.h"
|
2004-05-18 20:57:06 +02:00
|
|
|
#include "ospf6_message.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "ospf6_lsa.h"
|
|
|
|
#include "ospf6_lsdb.h"
|
|
|
|
#include "ospf6_route.h"
|
|
|
|
#include "ospf6_zebra.h"
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
#include "ospf6_top.h"
|
|
|
|
#include "ospf6_area.h"
|
|
|
|
#include "ospf6_interface.h"
|
|
|
|
#include "ospf6_neighbor.h"
|
2020-09-05 09:07:25 +02:00
|
|
|
#include "ospf6_network.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-08-15 07:52:07 +02:00
|
|
|
#include "ospf6_flood.h"
|
2004-05-18 20:57:06 +02:00
|
|
|
#include "ospf6_asbr.h"
|
2004-08-04 22:02:13 +02:00
|
|
|
#include "ospf6_abr.h"
|
2004-08-15 07:52:07 +02:00
|
|
|
#include "ospf6_intra.h"
|
2013-08-24 09:54:09 +02:00
|
|
|
#include "ospf6_spf.h"
|
2004-08-04 22:02:13 +02:00
|
|
|
#include "ospf6d.h"
|
2020-10-28 11:51:39 +01:00
|
|
|
#include "lib/json.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-03-22 19:31:56 +01:00
|
|
|
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_TOP, "OSPF6 top");
|
|
|
|
|
2016-12-07 13:25:38 +01:00
|
|
|
DEFINE_QOBJ_TYPE(ospf6);
|
|
|
|
|
2019-08-01 18:49:50 +02:00
|
|
|
FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
|
2020-04-02 21:16:04 +02:00
|
|
|
{ .val_bool = true, .match_profile = "datacenter", },
|
|
|
|
{ .val_bool = false },
|
2019-08-01 18:49:50 +02:00
|
|
|
);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* global ospf6d variable */
|
2018-02-27 20:24:16 +01:00
|
|
|
static struct ospf6_master ospf6_master;
|
|
|
|
struct ospf6_master *om6;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2010-11-10 22:01:41 +01:00
|
|
|
static void ospf6_disable(struct ospf6 *o);
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
static void ospf6_add(struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
listnode_add(om6->ospf6, ospf6);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf6_del(struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
listnode_delete(om6->ospf6, ospf6);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
|
|
|
|
|
|
|
|
return vrf ? vrf->name : "NIL";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Link OSPF instance to VRF. */
|
|
|
|
void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf)
|
|
|
|
{
|
|
|
|
ospf6->vrf_id = vrf->vrf_id;
|
|
|
|
if (vrf->info != (void *)ospf6)
|
|
|
|
vrf->info = (void *)ospf6;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlink OSPF instance from VRF. */
|
|
|
|
void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf)
|
|
|
|
{
|
|
|
|
if (vrf->info == (void *)ospf6)
|
|
|
|
vrf->info = NULL;
|
|
|
|
ospf6->vrf_id = VRF_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
struct vrf *vrf = NULL;
|
|
|
|
|
|
|
|
vrf = vrf_lookup_by_id(vrf_id);
|
|
|
|
if (!vrf)
|
|
|
|
return NULL;
|
|
|
|
return (vrf->info) ? (struct ospf6 *)vrf->info : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
|
|
|
|
{
|
|
|
|
struct ospf6 *o = NULL;
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) {
|
|
|
|
if (((o->name == NULL && name == NULL)
|
|
|
|
|| (o->name && name && strcmp(o->name, name) == 0)))
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-05-05 22:17:01 +02:00
|
|
|
/* This is hook function for vrf create called as part of vrf_init */
|
|
|
|
static int ospf6_vrf_new(struct vrf *vrf)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is hook function for vrf delete call as part of vrf_init */
|
|
|
|
static int ospf6_vrf_delete(struct vrf *vrf)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf6_set_redist_vrf_bitmaps(struct ospf6 *ospf6, bool set)
|
|
|
|
{
|
|
|
|
int type;
|
|
|
|
struct list *red_list;
|
|
|
|
|
|
|
|
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
|
|
|
|
red_list = ospf6->redist[type];
|
|
|
|
if (!red_list)
|
|
|
|
continue;
|
|
|
|
if (IS_OSPF6_DEBUG_ZEBRA(RECV))
|
|
|
|
zlog_debug(
|
|
|
|
"%s: setting redist vrf %d bitmap for type %d",
|
|
|
|
__func__, ospf6->vrf_id, type);
|
|
|
|
if (set)
|
|
|
|
vrf_bitmap_set(zclient->redist[AFI_IP6][type],
|
|
|
|
ospf6->vrf_id);
|
|
|
|
else
|
|
|
|
vrf_bitmap_unset(zclient->redist[AFI_IP6][type],
|
|
|
|
ospf6->vrf_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Disable OSPF6 VRF instance */
|
|
|
|
static int ospf6_vrf_disable(struct vrf *vrf)
|
|
|
|
{
|
|
|
|
struct ospf6 *ospf6 = NULL;
|
|
|
|
|
|
|
|
if (vrf->vrf_id == VRF_DEFAULT)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
|
|
|
|
if (ospf6) {
|
|
|
|
ospf6_zebra_vrf_deregister(ospf6);
|
|
|
|
|
|
|
|
ospf6_set_redist_vrf_bitmaps(ospf6, false);
|
|
|
|
|
|
|
|
/* We have instance configured, unlink
|
|
|
|
* from VRF and make it "down".
|
|
|
|
*/
|
|
|
|
ospf6_vrf_unlink(ospf6, vrf);
|
|
|
|
thread_cancel(&ospf6->t_ospf6_receive);
|
|
|
|
close(ospf6->fd);
|
|
|
|
ospf6->fd = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Note: This is a callback, the VRF will be deleted by the caller. */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Enable OSPF6 VRF instance */
|
|
|
|
static int ospf6_vrf_enable(struct vrf *vrf)
|
|
|
|
{
|
|
|
|
struct ospf6 *ospf6 = NULL;
|
|
|
|
vrf_id_t old_vrf_id;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
ospf6 = ospf6_lookup_by_vrf_name(vrf->name);
|
|
|
|
if (ospf6) {
|
|
|
|
old_vrf_id = ospf6->vrf_id;
|
|
|
|
/* We have instance configured, link to VRF and make it "up". */
|
|
|
|
ospf6_vrf_link(ospf6, vrf);
|
|
|
|
|
|
|
|
if (old_vrf_id != ospf6->vrf_id) {
|
|
|
|
ospf6_set_redist_vrf_bitmaps(ospf6, true);
|
|
|
|
|
|
|
|
/* start zebra redist to us for new vrf */
|
|
|
|
ospf6_zebra_vrf_register(ospf6);
|
|
|
|
|
|
|
|
ret = ospf6_serv_sock(ospf6);
|
|
|
|
if (ret < 0 || ospf6->fd <= 0)
|
|
|
|
return 0;
|
|
|
|
thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
|
|
|
|
&ospf6->t_ospf6_receive);
|
|
|
|
|
|
|
|
ospf6_router_id_update(ospf6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ospf6_vrf_init(void)
|
|
|
|
{
|
|
|
|
vrf_init(ospf6_vrf_new, ospf6_vrf_enable, ospf6_vrf_disable,
|
|
|
|
ospf6_vrf_delete, ospf6_vrf_enable);
|
|
|
|
}
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-05-18 20:57:06 +02:00
|
|
|
switch (ntohs(lsa->header->type)) {
|
|
|
|
case OSPF6_LSTYPE_AS_EXTERNAL:
|
2020-11-20 04:01:55 +01:00
|
|
|
ospf6_asbr_lsa_add(lsa);
|
2004-05-18 20:57:06 +02:00
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
default:
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-05-18 20:57:06 +02:00
|
|
|
switch (ntohs(lsa->header->type)) {
|
|
|
|
case OSPF6_LSTYPE_AS_EXTERNAL:
|
2018-02-15 04:02:11 +01:00
|
|
|
ospf6_asbr_lsa_remove(lsa, NULL);
|
2004-05-18 20:57:06 +02:00
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
default:
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-20 02:13:52 +01:00
|
|
|
static void ospf6_top_route_hook_add(struct ospf6_route *route)
|
2004-08-04 22:02:13 +02:00
|
|
|
{
|
2020-11-20 02:13:52 +01:00
|
|
|
struct ospf6 *ospf6 = route->table->scope;
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_abr_originate_summary(route, ospf6);
|
|
|
|
ospf6_zebra_route_update_add(route, ospf6);
|
2004-08-04 22:02:13 +02:00
|
|
|
}
|
|
|
|
|
2020-11-20 02:13:52 +01:00
|
|
|
static void ospf6_top_route_hook_remove(struct ospf6_route *route)
|
2004-08-04 22:02:13 +02:00
|
|
|
{
|
2020-11-20 02:13:52 +01:00
|
|
|
struct ospf6 *ospf6 = route->table->scope;
|
|
|
|
|
2015-05-20 03:03:39 +02:00
|
|
|
route->flag |= OSPF6_ROUTE_REMOVE;
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_abr_originate_summary(route, ospf6);
|
|
|
|
ospf6_zebra_route_update_remove(route, ospf6);
|
2004-08-04 22:02:13 +02:00
|
|
|
}
|
|
|
|
|
2020-11-20 02:13:52 +01:00
|
|
|
static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
|
2004-08-15 07:52:07 +02:00
|
|
|
{
|
2020-11-20 02:13:52 +01:00
|
|
|
struct ospf6 *ospf6 = route->table->scope;
|
|
|
|
|
2018-05-04 04:39:07 +02:00
|
|
|
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
|
|
|
|
IS_OSPF6_DEBUG_BROUTER) {
|
2018-02-15 04:02:11 +01:00
|
|
|
uint32_t brouter_id;
|
|
|
|
char brouter_name[16];
|
|
|
|
|
|
|
|
brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
|
|
|
|
inet_ntop(AF_INET, &brouter_id, brouter_name,
|
|
|
|
sizeof(brouter_name));
|
|
|
|
zlog_debug("%s: brouter %s add with adv router %x nh count %u",
|
2020-03-05 19:17:54 +01:00
|
|
|
__func__, brouter_name,
|
2018-02-15 04:02:11 +01:00
|
|
|
route->path.origin.adv_router,
|
|
|
|
listcount(route->nh_list));
|
2017-12-07 03:20:48 +01:00
|
|
|
}
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
|
|
|
|
ospf6);
|
|
|
|
ospf6_asbr_lsentry_add(route, ospf6);
|
|
|
|
ospf6_abr_originate_summary(route, ospf6);
|
2004-08-15 07:52:07 +02:00
|
|
|
}
|
|
|
|
|
2020-11-20 02:13:52 +01:00
|
|
|
static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
|
2004-08-15 07:52:07 +02:00
|
|
|
{
|
2020-11-20 02:13:52 +01:00
|
|
|
struct ospf6 *ospf6 = route->table->scope;
|
|
|
|
|
2018-05-04 04:39:07 +02:00
|
|
|
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
|
|
|
|
IS_OSPF6_DEBUG_BROUTER) {
|
2018-02-15 04:02:11 +01:00
|
|
|
uint32_t brouter_id;
|
|
|
|
char brouter_name[16];
|
2017-12-07 03:20:48 +01:00
|
|
|
|
2018-02-15 04:02:11 +01:00
|
|
|
brouter_id = ADV_ROUTER_IN_PREFIX(&route->prefix);
|
|
|
|
inet_ntop(AF_INET, &brouter_id, brouter_name,
|
|
|
|
sizeof(brouter_name));
|
2018-05-04 04:39:07 +02:00
|
|
|
zlog_debug("%s: brouter %p %s del with adv router %x nh %u",
|
2020-03-05 19:17:54 +01:00
|
|
|
__func__, (void *)route, brouter_name,
|
2018-05-04 04:39:07 +02:00
|
|
|
route->path.origin.adv_router,
|
2018-02-15 04:02:11 +01:00
|
|
|
listcount(route->nh_list));
|
2017-12-07 03:20:48 +01:00
|
|
|
}
|
2015-05-20 03:03:39 +02:00
|
|
|
route->flag |= OSPF6_ROUTE_REMOVE;
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
|
|
|
|
ospf6);
|
|
|
|
ospf6_asbr_lsentry_remove(route, ospf6);
|
|
|
|
ospf6_abr_originate_summary(route, ospf6);
|
2004-08-15 07:52:07 +02:00
|
|
|
}
|
|
|
|
|
2020-09-05 09:07:25 +02:00
|
|
|
static struct ospf6 *ospf6_create(const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6 *o;
|
2020-09-05 09:07:25 +02:00
|
|
|
struct vrf *vrf = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-09-05 09:07:25 +02:00
|
|
|
vrf = vrf_lookup_by_name(name);
|
|
|
|
if (vrf) {
|
|
|
|
o->vrf_id = vrf->vrf_id;
|
2020-10-08 07:38:43 +02:00
|
|
|
} else
|
|
|
|
o->vrf_id = VRF_UNKNOWN;
|
|
|
|
|
|
|
|
/* Freed in ospf6_delete */
|
|
|
|
o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
|
|
|
|
if (vrf)
|
|
|
|
ospf6_vrf_link(o, vrf);
|
|
|
|
|
|
|
|
ospf6_zebra_vrf_register(o);
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* initialize */
|
2017-01-18 01:30:43 +01:00
|
|
|
monotime(&o->starttime);
|
2004-05-18 20:57:06 +02:00
|
|
|
o->area_list = list_new();
|
|
|
|
o->area_list->cmp = ospf6_area_cmp;
|
2004-08-15 07:52:07 +02:00
|
|
|
o->lsdb = ospf6_lsdb_create(o);
|
|
|
|
o->lsdb_self = ospf6_lsdb_create(o);
|
2004-05-18 20:57:06 +02:00
|
|
|
o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
|
|
|
|
o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2013-08-24 09:54:09 +02:00
|
|
|
o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
|
|
|
|
o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
|
|
|
|
o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
|
|
|
|
o->spf_hold_multiplier = 1;
|
|
|
|
|
2021-02-10 05:53:46 +01:00
|
|
|
o->default_originate = DEFAULT_ORIGINATE_NONE;
|
2021-02-10 07:44:44 +01:00
|
|
|
o->redistribute = 0;
|
2015-05-20 03:04:07 +02:00
|
|
|
/* LSA timers value init */
|
|
|
|
o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
|
|
|
|
|
2006-05-15 12:46:07 +02:00
|
|
|
o->route_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, ROUTES);
|
|
|
|
o->route_table->scope = o;
|
2004-08-04 22:02:13 +02:00
|
|
|
o->route_table->hook_add = ospf6_top_route_hook_add;
|
|
|
|
o->route_table->hook_remove = ospf6_top_route_hook_remove;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2006-05-15 12:46:07 +02:00
|
|
|
o->brouter_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, BORDER_ROUTERS);
|
|
|
|
o->brouter_table->scope = o;
|
2004-08-15 07:52:07 +02:00
|
|
|
o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
|
|
|
|
o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
|
2004-08-04 22:02:13 +02:00
|
|
|
|
2006-05-15 12:46:07 +02:00
|
|
|
o->external_table = OSPF6_ROUTE_TABLE_CREATE(GLOBAL, EXTERNAL_ROUTES);
|
|
|
|
o->external_table->scope = o;
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
o->external_id_table = route_table_init();
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2012-10-24 16:45:54 +02:00
|
|
|
o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
|
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
o->distance_table = route_table_init();
|
2020-09-05 09:07:25 +02:00
|
|
|
o->fd = -1;
|
2014-03-05 09:13:43 +01:00
|
|
|
|
2021-01-28 09:50:39 +01:00
|
|
|
o->max_multipath = MULTIPATH_NUM;
|
|
|
|
|
2016-12-07 13:25:38 +01:00
|
|
|
QOBJ_REG(o, ospf6);
|
2015-11-03 19:48:30 +01:00
|
|
|
|
2020-09-05 09:07:25 +02:00
|
|
|
/* Make ospf protocol socket. */
|
|
|
|
ospf6_serv_sock(o);
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return o;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6_instance_create(const char *name)
|
2020-09-05 09:07:25 +02:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
|
|
|
|
2020-09-05 09:07:25 +02:00
|
|
|
ospf6 = ospf6_create(name);
|
|
|
|
if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
|
|
|
|
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
|
|
|
|
if (ospf6->router_id == 0)
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_router_id_update(ospf6);
|
|
|
|
ospf6_add(ospf6);
|
2021-05-05 22:17:01 +02:00
|
|
|
if (ospf6->fd < 0)
|
|
|
|
return ospf6;
|
|
|
|
|
2020-09-05 09:07:25 +02:00
|
|
|
thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
|
|
|
|
&ospf6->t_ospf6_receive);
|
2020-10-08 07:38:43 +02:00
|
|
|
|
|
|
|
return ospf6;
|
2020-09-05 09:07:25 +02:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
void ospf6_delete(struct ospf6 *o)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_area *oa;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-12-07 13:25:38 +01:00
|
|
|
QOBJ_UNREG(o);
|
ospf6d: Handle Premature Aging of LSAs
RFC 2328 (14.1) Premature aging of LSAs from
routing domain :
When ospf6d is going away (router going down),
send MAXAGEd self originated LSAs to all
neighbors in routing domain to trigger
Premature aging to remove from resepective LSDBs.
Neighbor Router Reboot:
Upon receiving Self-originate MAXAGEd LSA, simply
discard, Current copy could be non maxaged latest.
For neighbor advertised LSA's (current copy in LSDB)
is set to MAXAGE but received new LSA with Non-MAXAGE
(with current age), discard the current MAXAGE LSA,
Send latest copy of LSA to neighbors and update the
LSDB with new LSA.
When a neighbor transition to FULL, trigger AS-External
LSAs update from external LSDB to new neighbor.
Testing:
R1 ---- DUT --- R5
| \
R2 R3
|
R4
Area 1: R5 and DUT
Area 0: DUT, R1, R2, R3
Area 2: R2 R4
Add IPv6 static routes at R5
Redistribute kernel routes at R5,
Validate routes at R4, redistributed via backbone
to area 2.
Stop n start frr.service at R5 and validated
MAXAGE LSAs then recent age LSAs in Database at DUT-R4.
Validated external routes installed DUT to R4.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
2018-01-26 23:53:43 +01:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_flush_self_originated_lsas_now(o);
|
|
|
|
ospf6_disable(o);
|
|
|
|
ospf6_del(o);
|
2010-11-10 22:01:41 +01:00
|
|
|
|
2021-05-05 22:17:01 +02:00
|
|
|
ospf6_zebra_vrf_deregister(o);
|
|
|
|
|
2020-11-20 04:06:51 +01:00
|
|
|
ospf6_serv_close(&o->fd);
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
|
|
|
|
ospf6_area_delete(oa);
|
2013-03-08 21:47:35 +01:00
|
|
|
|
|
|
|
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&o->area_list);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
ospf6_lsdb_delete(o->lsdb);
|
2004-08-15 07:52:07 +02:00
|
|
|
ospf6_lsdb_delete(o->lsdb_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-20 02:13:52 +01:00
|
|
|
ospf6_route_table_delete(o->route_table);
|
|
|
|
ospf6_route_table_delete(o->brouter_table);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-11-20 02:13:52 +01:00
|
|
|
ospf6_route_table_delete(o->external_table);
|
2004-05-18 20:57:06 +02:00
|
|
|
route_table_finish(o->external_id_table);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
ospf6_distance_reset(o);
|
|
|
|
route_table_finish(o->distance_table);
|
|
|
|
|
2020-09-05 09:07:25 +02:00
|
|
|
XFREE(MTYPE_OSPF6_TOP, o->name);
|
2004-05-18 20:57:06 +02:00
|
|
|
XFREE(MTYPE_OSPF6_TOP, o);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
static void ospf6_disable(struct ospf6 *o)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_area *oa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
if (!CHECK_FLAG(o->flag, OSPF6_DISABLED)) {
|
|
|
|
SET_FLAG(o->flag, OSPF6_DISABLED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
|
|
|
|
ospf6_area_disable(oa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-03-08 21:47:35 +01:00
|
|
|
/* XXX: This also changes persistent settings */
|
2020-11-09 16:51:29 +01:00
|
|
|
/* Unregister redistribution */
|
|
|
|
ospf6_asbr_redistribute_reset(o);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
ospf6_lsdb_remove_all(o->lsdb);
|
2020-11-20 02:13:52 +01:00
|
|
|
ospf6_route_remove_all(o->route_table);
|
|
|
|
ospf6_route_remove_all(o->brouter_table);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-03-08 21:47:35 +01:00
|
|
|
THREAD_OFF(o->maxage_remover);
|
|
|
|
THREAD_OFF(o->t_spf_calc);
|
|
|
|
THREAD_OFF(o->t_ase_calc);
|
2018-01-25 04:02:19 +01:00
|
|
|
THREAD_OFF(o->t_distribute_update);
|
2020-09-05 09:07:25 +02:00
|
|
|
THREAD_OFF(o->t_ospf6_receive);
|
2004-05-18 20:57:06 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
void ospf6_master_init(struct thread_master *master)
|
2018-02-27 20:24:16 +01:00
|
|
|
{
|
|
|
|
memset(&ospf6_master, 0, sizeof(struct ospf6_master));
|
|
|
|
|
|
|
|
om6 = &ospf6_master;
|
2020-10-08 07:38:43 +02:00
|
|
|
om6->ospf6 = list_new();
|
|
|
|
om6->master = master;
|
2018-02-27 20:24:16 +01:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
static int ospf6_maxage_remover(struct thread *thread)
|
|
|
|
{
|
|
|
|
struct ospf6 *o = (struct ospf6 *)THREAD_ARG(thread);
|
|
|
|
struct ospf6_area *oa;
|
|
|
|
struct ospf6_interface *oi;
|
|
|
|
struct ospf6_neighbor *on;
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *i, *j, *k;
|
2013-08-24 09:54:17 +02:00
|
|
|
int reschedule = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
o->maxage_remover = (struct thread *)NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
|
2004-05-18 20:57:06 +02:00
|
|
|
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
|
|
|
|
&& on->state != OSPF6_NEIGHBOR_LOADING)
|
2013-08-24 09:54:17 +02:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-08-24 09:54:17 +02:00
|
|
|
ospf6_maxage_remove(o);
|
2004-05-18 20:57:06 +02:00
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2013-08-24 09:54:17 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-08-24 09:54:17 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
|
2013-08-24 09:54:17 +02:00
|
|
|
if (ospf6_lsdb_maxage_remover(oi->lsdb)) {
|
|
|
|
reschedule = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-24 09:54:17 +02:00
|
|
|
if (ospf6_lsdb_maxage_remover(oa->lsdb)) {
|
|
|
|
reschedule = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2013-08-24 09:54:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ospf6_lsdb_maxage_remover(o->lsdb)) {
|
|
|
|
reschedule = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (reschedule) {
|
|
|
|
ospf6_maxage_remove(o);
|
2004-05-18 20:57:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
void ospf6_maxage_remove(struct ospf6 *o)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-05-05 23:22:25 +02:00
|
|
|
if (o)
|
|
|
|
thread_add_timer(master, ospf6_maxage_remover, o,
|
|
|
|
OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT,
|
|
|
|
&o->maxage_remover);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
void ospf6_router_id_update(struct ospf6 *ospf6)
|
2018-02-27 20:24:16 +01:00
|
|
|
{
|
|
|
|
if (!ospf6)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ospf6->router_id_static != 0)
|
|
|
|
ospf6->router_id = ospf6->router_id_static;
|
|
|
|
else
|
|
|
|
ospf6->router_id = om6->zebra_router_id;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* start ospf6 */
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN_NOSH(router_ospf6, router_ospf6_cmd, "router ospf6 [vrf NAME]",
|
|
|
|
ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
|
|
|
int idx_vrf = 0;
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
|
|
|
|
vrf_name = argv[idx_vrf + 1]->arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
|
2020-09-05 09:07:25 +02:00
|
|
|
if (ospf6 == NULL)
|
2021-05-05 22:19:01 +02:00
|
|
|
ospf6 = ospf6_instance_create(vrf_name);
|
2020-09-05 09:07:25 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* set current ospf point. */
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
|
2004-05-18 20:57:06 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* stop ospf6 */
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN(no_router_ospf6, no_router_ospf6_cmd, "no router ospf6 [vrf NAME]",
|
|
|
|
NO_STR ROUTER_STR OSPF6_STR VRF_CMD_HELP_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
|
|
|
int idx_vrf = 0;
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
if (argv_find(argv, argc, "vrf", &idx_vrf)) {
|
|
|
|
vrf_name = argv[idx_vrf + 1]->arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
|
2017-04-22 22:41:54 +02:00
|
|
|
if (ospf6 == NULL)
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out(vty, "OSPFv3 is not configured\n");
|
2017-04-22 22:41:54 +02:00
|
|
|
else {
|
|
|
|
ospf6_delete(ospf6);
|
|
|
|
ospf6 = NULL;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* return to config node . */
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_PUSH_CONTEXT_NULL(CONFIG_NODE);
|
2004-05-18 20:57:06 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* change Router_ID commands. */
|
2017-08-30 17:23:01 +02:00
|
|
|
DEFUN(ospf6_router_id,
|
|
|
|
ospf6_router_id_cmd,
|
|
|
|
"ospf6 router-id A.B.C.D",
|
|
|
|
OSPF6_STR
|
|
|
|
"Configure OSPF6 Router-ID\n"
|
|
|
|
V4NOTATION_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, o);
|
2017-08-28 19:38:42 +02:00
|
|
|
int idx = 0;
|
2004-05-18 20:57:06 +02:00
|
|
|
int ret;
|
2017-08-28 19:38:42 +02:00
|
|
|
const char *router_id_str;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t router_id;
|
2018-02-12 22:22:04 +01:00
|
|
|
struct ospf6_area *oa;
|
|
|
|
struct listnode *node;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-28 19:38:42 +02:00
|
|
|
argv_find(argv, argc, "A.B.C.D", &idx);
|
|
|
|
router_id_str = argv[idx]->arg;
|
|
|
|
|
|
|
|
ret = inet_pton(AF_INET, router_id_str, &router_id);
|
2004-05-18 20:57:06 +02:00
|
|
|
if (ret == 0) {
|
2017-08-30 17:23:01 +02:00
|
|
|
vty_out(vty, "malformed OSPF Router-ID: %s\n", router_id_str);
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-10-11 19:02:40 +02:00
|
|
|
o->router_id_static = router_id;
|
2018-02-12 22:22:04 +01:00
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
|
|
|
|
if (oa->full_nbrs) {
|
|
|
|
vty_out(vty,
|
2020-03-27 12:35:23 +01:00
|
|
|
"For this router-id change to take effect, save config and restart ospf6d\n");
|
2018-02-12 22:22:04 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
o->router_id = router_id;
|
2004-10-11 19:02:40 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2017-08-30 17:23:01 +02:00
|
|
|
DEFUN(no_ospf6_router_id,
|
|
|
|
no_ospf6_router_id_cmd,
|
|
|
|
"no ospf6 router-id [A.B.C.D]",
|
|
|
|
NO_STR OSPF6_STR
|
|
|
|
"Configure OSPF6 Router-ID\n"
|
|
|
|
V4NOTATION_STR)
|
2017-08-28 19:38:42 +02:00
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, o);
|
2018-02-12 22:22:04 +01:00
|
|
|
struct ospf6_area *oa;
|
|
|
|
struct listnode *node;
|
|
|
|
|
2017-08-28 19:38:42 +02:00
|
|
|
o->router_id_static = 0;
|
2018-02-12 22:22:04 +01:00
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
|
|
|
|
if (oa->full_nbrs) {
|
|
|
|
vty_out(vty,
|
2020-03-27 12:35:23 +01:00
|
|
|
"For this router-id change to take effect, save config and restart ospf6d\n");
|
2018-02-12 22:22:04 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
2017-08-28 19:38:42 +02:00
|
|
|
o->router_id = 0;
|
2018-02-12 22:22:04 +01:00
|
|
|
if (o->router_id_zebra.s_addr)
|
|
|
|
o->router_id = (uint32_t)o->router_id_zebra.s_addr;
|
2017-08-28 19:38:42 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-08-26 05:40:16 +02:00
|
|
|
DEFUN (ospf6_log_adjacency_changes,
|
|
|
|
ospf6_log_adjacency_changes_cmd,
|
|
|
|
"log-adjacency-changes",
|
|
|
|
"Log changes in adjacency state\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2013-08-26 05:40:16 +02:00
|
|
|
|
|
|
|
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
|
2015-11-03 19:48:30 +01:00
|
|
|
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
|
2013-08-26 05:40:16 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ospf6_log_adjacency_changes_detail,
|
|
|
|
ospf6_log_adjacency_changes_detail_cmd,
|
|
|
|
"log-adjacency-changes detail",
|
2015-11-03 19:48:30 +01:00
|
|
|
"Log changes in adjacency state\n"
|
2013-08-26 05:40:16 +02:00
|
|
|
"Log all state changes\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2013-08-26 05:40:16 +02:00
|
|
|
|
|
|
|
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
|
|
|
|
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ospf6_log_adjacency_changes,
|
|
|
|
no_ospf6_log_adjacency_changes_cmd,
|
|
|
|
"no log-adjacency-changes",
|
2015-11-03 19:48:30 +01:00
|
|
|
NO_STR
|
2013-08-26 05:40:16 +02:00
|
|
|
"Log changes in adjacency state\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2013-08-26 05:40:16 +02:00
|
|
|
|
|
|
|
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
|
|
|
|
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ospf6_log_adjacency_changes_detail,
|
|
|
|
no_ospf6_log_adjacency_changes_detail_cmd,
|
|
|
|
"no log-adjacency-changes detail",
|
2015-11-03 19:48:30 +01:00
|
|
|
NO_STR
|
|
|
|
"Log changes in adjacency state\n"
|
2013-08-26 05:40:16 +02:00
|
|
|
"Log all state changes\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2013-08-26 05:40:16 +02:00
|
|
|
|
|
|
|
UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-05-20 03:04:07 +02:00
|
|
|
DEFUN (ospf6_timers_lsa,
|
|
|
|
ospf6_timers_lsa_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"timers lsa min-arrival (0-600000)",
|
2015-05-20 03:04:07 +02:00
|
|
|
"Adjust routing timers\n"
|
|
|
|
"OSPF6 LSA timers\n"
|
|
|
|
"Minimum delay in receiving new version of a LSA\n"
|
|
|
|
"Delay in milliseconds\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf);
|
2016-09-23 21:56:31 +02:00
|
|
|
int idx_number = 3;
|
2015-05-20 03:04:07 +02:00
|
|
|
unsigned int minarrival;
|
|
|
|
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
|
2015-05-20 03:04:07 +02:00
|
|
|
ospf->lsa_minarrival = minarrival;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ospf6_timers_lsa,
|
|
|
|
no_ospf6_timers_lsa_cmd,
|
2016-09-30 03:27:05 +02:00
|
|
|
"no timers lsa min-arrival [(0-600000)]",
|
2015-05-20 03:04:07 +02:00
|
|
|
NO_STR
|
|
|
|
"Adjust routing timers\n"
|
|
|
|
"OSPF6 LSA timers\n"
|
2016-11-30 00:07:11 +01:00
|
|
|
"Minimum delay in receiving new version of a LSA\n"
|
|
|
|
"Delay in milliseconds\n")
|
2015-05-20 03:04:07 +02:00
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf);
|
2016-09-30 03:27:05 +02:00
|
|
|
int idx_number = 4;
|
2015-05-20 03:04:07 +02:00
|
|
|
unsigned int minarrival;
|
|
|
|
|
2016-09-30 03:27:05 +02:00
|
|
|
if (argc == 5) {
|
*: remove VTY_GET_*
CLI validates input tokens, so there's no need to do it in handler
functions anymore.
spatch follows
----------------
@getull@
expression v;
expression str;
@@
<...
- VTY_GET_ULL(..., v, str)
+ v = strtoull (str, NULL, 10)
...>
@getul@
expression v;
expression str;
@@
<...
- VTY_GET_ULONG(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getintrange@
expression name;
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER_RANGE(name, v, str, ...)
+ v = strtoul (str, NULL, 10)
...>
@getint@
expression v;
expression str;
@@
<...
- VTY_GET_INTEGER(..., v, str)
+ v = strtoul (str, NULL, 10)
...>
@getv4@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_ADDRESS(..., v, str)
+ inet_aton (str, &v)
...>
@getv4pfx@
expression v;
expression str;
@@
<...
- VTY_GET_IPV4_PREFIX(..., v, str)
+ str2prefix_ipv4 (str, &v)
...>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
2017-06-27 20:47:03 +02:00
|
|
|
minarrival = strtoul(argv[idx_number]->arg, NULL, 10);
|
2015-05-20 03:04:07 +02:00
|
|
|
|
|
|
|
if (ospf->lsa_minarrival != minarrival
|
|
|
|
|| minarrival == OSPF_MIN_LS_ARRIVAL)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
DEFUN (ospf6_distance,
|
|
|
|
ospf6_distance_cmd,
|
2016-10-21 21:27:49 +02:00
|
|
|
"distance (1-255)",
|
2014-03-05 09:13:43 +01:00
|
|
|
"Administrative distance\n"
|
|
|
|
"OSPF6 Administrative distance\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, o);
|
2014-03-05 09:13:43 +01:00
|
|
|
|
2016-10-21 21:27:49 +02:00
|
|
|
o->distance_all = atoi(argv[1]->arg);
|
2014-03-05 09:13:43 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ospf6_distance,
|
|
|
|
no_ospf6_distance_cmd,
|
2016-10-21 21:27:49 +02:00
|
|
|
"no distance (1-255)",
|
2014-03-05 09:13:43 +01:00
|
|
|
NO_STR
|
|
|
|
"Administrative distance\n"
|
|
|
|
"OSPF6 Administrative distance\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, o);
|
2014-03-05 09:13:43 +01:00
|
|
|
|
|
|
|
o->distance_all = 0;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ospf6_distance_ospf6,
|
|
|
|
ospf6_distance_ospf6_cmd,
|
2017-04-03 22:17:12 +02:00
|
|
|
"distance ospf6 {intra-area (1-255)|inter-area (1-255)|external (1-255)}",
|
2014-03-05 09:13:43 +01:00
|
|
|
"Administrative distance\n"
|
2017-04-03 22:17:12 +02:00
|
|
|
"OSPF6 administrative distance\n"
|
2016-10-21 21:27:49 +02:00
|
|
|
"Intra-area routes\n"
|
|
|
|
"Distance for intra-area routes\n"
|
|
|
|
"Inter-area routes\n"
|
|
|
|
"Distance for inter-area routes\n"
|
|
|
|
"External routes\n"
|
2014-03-05 09:13:43 +01:00
|
|
|
"Distance for external routes\n")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, o);
|
2016-10-21 21:27:49 +02:00
|
|
|
int idx = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-02-12 05:17:11 +01:00
|
|
|
o->distance_intra = 0;
|
|
|
|
o->distance_inter = 0;
|
|
|
|
o->distance_external = 0;
|
|
|
|
|
2017-04-03 22:17:12 +02:00
|
|
|
if (argv_find(argv, argc, "intra-area", &idx))
|
|
|
|
o->distance_intra = atoi(argv[idx + 1]->arg);
|
2017-07-17 14:03:14 +02:00
|
|
|
idx = 0;
|
2016-10-21 21:27:49 +02:00
|
|
|
if (argv_find(argv, argc, "inter-area", &idx))
|
2017-04-03 22:17:12 +02:00
|
|
|
o->distance_inter = atoi(argv[idx + 1]->arg);
|
2017-07-17 14:03:14 +02:00
|
|
|
idx = 0;
|
2016-10-21 21:27:49 +02:00
|
|
|
if (argv_find(argv, argc, "external", &idx))
|
2017-04-03 22:17:12 +02:00
|
|
|
o->distance_external = atoi(argv[idx + 1]->arg);
|
2016-10-21 21:27:49 +02:00
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ospf6_distance_ospf6,
|
|
|
|
no_ospf6_distance_ospf6_cmd,
|
2017-04-03 22:17:12 +02:00
|
|
|
"no distance ospf6 [{intra-area [(1-255)]|inter-area [(1-255)]|external [(1-255)]}]",
|
2014-03-05 09:13:43 +01:00
|
|
|
NO_STR
|
|
|
|
"Administrative distance\n"
|
|
|
|
"OSPF6 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")
|
|
|
|
{
|
2016-12-07 17:15:32 +01:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, o);
|
2016-10-21 21:27:49 +02:00
|
|
|
int idx = 0;
|
2014-03-05 09:13:43 +01:00
|
|
|
|
2017-04-03 22:17:12 +02:00
|
|
|
if (argv_find(argv, argc, "intra-area", &idx) || argc == 3)
|
|
|
|
idx = o->distance_intra = 0;
|
|
|
|
if (argv_find(argv, argc, "inter-area", &idx) || argc == 3)
|
|
|
|
idx = o->distance_inter = 0;
|
|
|
|
if (argv_find(argv, argc, "external", &idx) || argc == 3)
|
2014-03-05 09:13:43 +01:00
|
|
|
o->distance_external = 0;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
DEFUN (ospf6_interface_area,
|
|
|
|
ospf6_interface_area_cmd,
|
2018-10-03 19:22:34 +02:00
|
|
|
"interface IFNAME area <A.B.C.D|(0-4294967295)>",
|
2004-05-18 20:57:06 +02:00
|
|
|
"Enable routing on an IPv6 interface\n"
|
|
|
|
IFNAME_STR
|
|
|
|
"Specify the OSPF6 area ID\n"
|
|
|
|
"OSPF6 area ID in IPv4 address notation\n"
|
2018-10-03 19:22:34 +02:00
|
|
|
"OSPF6 area ID in decimal notation\n"
|
2004-05-18 20:57:06 +02:00
|
|
|
)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-05-05 22:19:01 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2016-09-23 21:56:31 +02:00
|
|
|
int idx_ifname = 1;
|
|
|
|
int idx_ipv4 = 3;
|
2004-08-19 08:56:53 +02:00
|
|
|
struct ospf6_area *oa;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_interface *oi;
|
|
|
|
struct interface *ifp;
|
2021-05-05 22:19:01 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
2021-05-04 17:06:49 +02:00
|
|
|
int ipv6_count = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
if (ospf6->vrf_id != VRF_UNKNOWN)
|
|
|
|
vrf_id = ospf6->vrf_id;
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* find/create ospf6 interface */
|
2021-05-05 22:19:01 +02:00
|
|
|
ifp = if_get_by_name(argv[idx_ifname]->arg, vrf_id);
|
2004-05-18 20:57:06 +02:00
|
|
|
oi = (struct ospf6_interface *)ifp->info;
|
|
|
|
if (oi == NULL)
|
2017-05-18 19:27:09 +02:00
|
|
|
oi = ospf6_interface_create(ifp);
|
|
|
|
if (oi->area) {
|
2004-05-18 20:57:06 +02:00
|
|
|
vty_out(vty, "%s already attached to Area %s\n",
|
2004-08-15 07:52:07 +02:00
|
|
|
oi->interface->name, oi->area->name);
|
2013-03-08 21:47:35 +01:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2004-08-15 07:52:07 +02:00
|
|
|
|
2021-05-04 17:06:49 +02:00
|
|
|
/* if more than OSPF6_MAX_IF_ADDRS are configured on this interface
|
|
|
|
* then don't allow ospfv3 to be configured
|
|
|
|
*/
|
|
|
|
ipv6_count = connected_count_by_family(ifp, AF_INET6);
|
|
|
|
if (oi->ifmtu == OSPF6_DEFAULT_MTU && ipv6_count > OSPF6_MAX_IF_ADDRS) {
|
|
|
|
vty_out(vty,
|
|
|
|
"can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
|
|
|
|
ifp->name, OSPF6_MAX_IF_ADDRS, ipv6_count);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
} else if (oi->ifmtu >= OSPF6_JUMBO_MTU
|
|
|
|
&& ipv6_count > OSPF6_MAX_IF_ADDRS_JUMBO) {
|
|
|
|
vty_out(vty,
|
|
|
|
"can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
|
|
|
|
ifp->name, OSPF6_MAX_IF_ADDRS_JUMBO, ipv6_count);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* parse Area-ID */
|
2020-10-08 07:38:43 +02:00
|
|
|
OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* attach interface to area */
|
|
|
|
listnode_add(oa->if_list, oi); /* sort ?? */
|
|
|
|
oi->area = oa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-08-15 07:52:07 +02:00
|
|
|
SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-03-08 21:47:35 +01:00
|
|
|
/* ospf6 process is currently disabled, not much more to do */
|
2020-10-08 07:38:43 +02:00
|
|
|
if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* start up */
|
2013-03-08 21:47:35 +01:00
|
|
|
ospf6_interface_enable(oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-08-19 08:56:53 +02:00
|
|
|
/* If the router is ABR, originate summary routes */
|
2020-10-08 07:38:43 +02:00
|
|
|
if (ospf6_is_router_abr(ospf6))
|
2004-08-19 08:56:53 +02:00
|
|
|
ospf6_abr_enable_area(oa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
DEFUN (no_ospf6_interface_area,
|
|
|
|
no_ospf6_interface_area_cmd,
|
2018-10-03 19:22:34 +02:00
|
|
|
"no interface IFNAME area <A.B.C.D|(0-4294967295)>",
|
2004-05-18 20:57:06 +02:00
|
|
|
NO_STR
|
|
|
|
"Disable routing on an IPv6 interface\n"
|
|
|
|
IFNAME_STR
|
|
|
|
"Specify the OSPF6 area ID\n"
|
|
|
|
"OSPF6 area ID in IPv4 address notation\n"
|
2018-10-03 19:22:34 +02:00
|
|
|
"OSPF6 area ID in decimal notation\n"
|
2004-05-18 20:57:06 +02:00
|
|
|
)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-05-05 22:19:01 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2016-09-23 21:56:31 +02:00
|
|
|
int idx_ifname = 2;
|
|
|
|
int idx_ipv4 = 4;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_interface *oi;
|
|
|
|
struct ospf6_area *oa;
|
|
|
|
struct interface *ifp;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t area_id;
|
2021-05-05 22:19:01 +02:00
|
|
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
|
|
|
|
|
|
|
if (ospf6->vrf_id != VRF_UNKNOWN)
|
|
|
|
vrf_id = ospf6->vrf_id;
|
|
|
|
|
|
|
|
/* find/create ospf6 interface */
|
|
|
|
ifp = if_get_by_name(argv[idx_ifname]->arg, vrf_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-02-12 02:30:44 +01:00
|
|
|
if (ifp == NULL) {
|
2017-07-13 19:42:42 +02:00
|
|
|
vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2004-08-15 07:52:07 +02:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
oi = (struct ospf6_interface *)ifp->info;
|
|
|
|
if (oi == NULL) {
|
2017-07-13 19:42:42 +02:00
|
|
|
vty_out(vty, "Interface %s not enabled\n", ifp->name);
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* parse Area-ID */
|
2018-10-03 19:22:34 +02:00
|
|
|
if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
|
|
|
|
area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-02-12 02:30:44 +01:00
|
|
|
/* Verify Area */
|
2004-05-18 20:57:06 +02:00
|
|
|
if (oi->area == NULL) {
|
2021-03-17 00:14:26 +01:00
|
|
|
vty_out(vty, "%s not attached to area %s\n",
|
2021-04-18 13:10:18 +02:00
|
|
|
oi->interface->name, argv[idx_ipv4]->arg);
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
if (oi->area->area_id != area_id) {
|
2017-07-13 19:42:42 +02:00
|
|
|
vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
|
|
|
|
oi->interface->name, oi->area->name);
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2020-12-01 07:21:04 +01:00
|
|
|
ospf6_interface_disable(oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-08-15 07:52:07 +02:00
|
|
|
oa = oi->area;
|
2004-05-18 20:57:06 +02:00
|
|
|
listnode_delete(oi->area->if_list, oi);
|
|
|
|
oi->area = (struct ospf6_area *)NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-08-15 07:52:07 +02:00
|
|
|
/* Withdraw inter-area routes from this area, if necessary */
|
|
|
|
if (oa->if_list->count == 0) {
|
|
|
|
UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
|
2004-08-19 08:56:53 +02:00
|
|
|
ospf6_abr_disable_area(oa);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2013-08-24 10:00:37 +02:00
|
|
|
DEFUN (ospf6_stub_router_admin,
|
|
|
|
ospf6_stub_router_admin_cmd,
|
|
|
|
"stub-router administrative",
|
|
|
|
"Make router a stub router\n"
|
|
|
|
"Administratively applied, for an indefinite period\n")
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct ospf6_area *oa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
2013-08-24 10:00:37 +02:00
|
|
|
if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
|
|
|
|
OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
|
|
|
|
OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_R);
|
|
|
|
OSPF6_ROUTER_LSA_SCHEDULE(oa);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2013-08-24 10:00:37 +02:00
|
|
|
SET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_ospf6_stub_router_admin,
|
|
|
|
no_ospf6_stub_router_admin_cmd,
|
|
|
|
"no stub-router administrative",
|
|
|
|
NO_STR
|
|
|
|
"Make router a stub router\n"
|
|
|
|
"Administratively applied, for an indefinite period\n")
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct ospf6_area *oa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
2013-08-24 10:00:37 +02:00
|
|
|
if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
|
|
|
|
OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
|
|
|
|
OSPF6_OPT_SET(oa->options, OSPF6_OPT_R);
|
|
|
|
OSPF6_ROUTER_LSA_SCHEDULE(oa);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2013-08-24 10:00:37 +02:00
|
|
|
UNSET_FLAG(ospf6->flag, OSPF6_STUB_ROUTER);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-01-28 09:50:39 +01:00
|
|
|
/* Restart OSPF SPF algorithm*/
|
|
|
|
static void ospf6_restart_spf(struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
ospf6_route_remove_all(ospf6->route_table);
|
|
|
|
ospf6_route_remove_all(ospf6->brouter_table);
|
|
|
|
|
|
|
|
/* Trigger SPF */
|
|
|
|
ospf6_spf_schedule(ospf6, OSPF6_SPF_FLAGS_CONFIG_CHANGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the max paths */
|
|
|
|
static void ospf6_maxpath_set(struct ospf6 *ospf6, uint16_t paths)
|
|
|
|
{
|
|
|
|
if (ospf6->max_multipath == paths)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ospf6->max_multipath = paths;
|
|
|
|
|
|
|
|
/* Send deletion to zebra to delete all
|
|
|
|
* ospf specific routes and reinitiate
|
|
|
|
* SPF to reflect the new max multipath.
|
|
|
|
*/
|
|
|
|
ospf6_restart_spf(ospf6);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ospf Maximum-paths config support */
|
|
|
|
DEFUN(ospf6_max_multipath,
|
|
|
|
ospf6_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_CONTEXT(ospf6, ospf6);
|
|
|
|
int idx_number = 1;
|
|
|
|
int maximum_paths = strtol(argv[idx_number]->arg, NULL, 10);
|
|
|
|
|
|
|
|
ospf6_maxpath_set(ospf6, maximum_paths);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(no_ospf6_max_multipath,
|
|
|
|
no_ospf6_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_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
ospf6_maxpath_set(ospf6, MULTIPATH_NUM);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-10-13 14:44:52 +02:00
|
|
|
static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json,
|
|
|
|
bool use_json)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *n;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_area *oa;
|
|
|
|
char router_id[16], duration[32];
|
2013-08-26 05:40:23 +02:00
|
|
|
struct timeval now, running, result;
|
|
|
|
char buf[32], rbuf[32];
|
2020-10-13 14:44:52 +02:00
|
|
|
json_object *json_areas = NULL;
|
|
|
|
const char *adjacency;
|
|
|
|
|
|
|
|
if (use_json) {
|
|
|
|
json_areas = json_object_new_object();
|
|
|
|
|
|
|
|
/* process id, router id */
|
|
|
|
inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
|
|
|
|
json_object_string_add(json, "routerId", router_id);
|
|
|
|
|
|
|
|
/* running time */
|
|
|
|
monotime(&now);
|
|
|
|
timersub(&now, &o->starttime, &running);
|
|
|
|
timerstring(&running, duration, sizeof(duration));
|
|
|
|
json_object_string_add(json, "running", duration);
|
|
|
|
|
|
|
|
/* Redistribute configuration */
|
|
|
|
/* XXX */
|
|
|
|
json_object_int_add(json, "lsaMinimumArrivalMsecs",
|
|
|
|
o->lsa_minarrival);
|
|
|
|
|
|
|
|
/* Show SPF parameters */
|
|
|
|
json_object_int_add(json, "spfScheduleDelayMsecs",
|
|
|
|
o->spf_delay);
|
|
|
|
json_object_int_add(json, "holdTimeMinMsecs", o->spf_holdtime);
|
|
|
|
json_object_int_add(json, "holdTimeMaxMsecs",
|
|
|
|
o->spf_max_holdtime);
|
|
|
|
json_object_int_add(json, "holdTimeMultiplier",
|
|
|
|
o->spf_hold_multiplier);
|
|
|
|
|
2021-01-28 09:50:39 +01:00
|
|
|
json_object_int_add(json, "maximumPaths", o->max_multipath);
|
2020-10-13 14:44:52 +02:00
|
|
|
|
|
|
|
if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
|
|
|
|
timersub(&now, &o->ts_spf, &result);
|
|
|
|
timerstring(&result, buf, sizeof(buf));
|
|
|
|
ospf6_spf_reason_string(o->last_spf_reason, rbuf,
|
|
|
|
sizeof(rbuf));
|
|
|
|
json_object_boolean_true_add(json, "spfHasRun");
|
|
|
|
json_object_string_add(json, "spfLastExecutedMsecs",
|
|
|
|
buf);
|
|
|
|
json_object_string_add(json, "spfLastExecutedReason",
|
|
|
|
rbuf);
|
|
|
|
|
|
|
|
json_object_int_add(
|
|
|
|
json, "spfLastDurationSecs",
|
|
|
|
(long long)o->ts_spf_duration.tv_sec);
|
|
|
|
|
|
|
|
json_object_int_add(
|
|
|
|
json, "spfLastDurationMsecs",
|
|
|
|
(long long)o->ts_spf_duration.tv_usec);
|
|
|
|
} else
|
|
|
|
json_object_boolean_false_add(json, "spfHasRun");
|
|
|
|
|
|
|
|
|
|
|
|
threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
|
|
|
|
if (o->t_spf_calc) {
|
|
|
|
long time_store;
|
|
|
|
|
|
|
|
json_object_boolean_true_add(json, "spfTimerActive");
|
|
|
|
time_store =
|
|
|
|
monotime_until(&o->t_spf_calc->u.sands, NULL)
|
|
|
|
/ 1000LL;
|
|
|
|
json_object_int_add(json, "spfTimerDueInMsecs",
|
|
|
|
time_store);
|
|
|
|
} else
|
|
|
|
json_object_boolean_false_add(json, "spfTimerActive");
|
|
|
|
|
|
|
|
json_object_boolean_add(json, "routerIsStubRouter",
|
|
|
|
CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER));
|
|
|
|
|
|
|
|
/* LSAs */
|
|
|
|
json_object_int_add(json, "numberOfAsScopedLsa",
|
|
|
|
o->lsdb->count);
|
|
|
|
/* Areas */
|
|
|
|
json_object_int_add(json, "numberOfAreaInRouter",
|
|
|
|
listcount(o->area_list));
|
|
|
|
|
|
|
|
if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
|
|
|
|
if (CHECK_FLAG(o->config_flags,
|
|
|
|
OSPF6_LOG_ADJACENCY_DETAIL))
|
|
|
|
adjacency = "LoggedAll";
|
|
|
|
else
|
|
|
|
adjacency = "Logged";
|
|
|
|
} else
|
|
|
|
adjacency = "NotLogged";
|
|
|
|
json_object_string_add(json, "adjacencyChanges", adjacency);
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
|
|
|
|
ospf6_area_show(vty, oa, json_areas, use_json);
|
|
|
|
|
|
|
|
json_object_object_add(json, "areas", json_areas);
|
|
|
|
|
|
|
|
vty_out(vty, "%s\n",
|
|
|
|
json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* process id, router id */
|
|
|
|
inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id));
|
|
|
|
vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n",
|
|
|
|
router_id);
|
|
|
|
|
|
|
|
/* running time */
|
|
|
|
monotime(&now);
|
|
|
|
timersub(&now, &o->starttime, &running);
|
|
|
|
timerstring(&running, duration, sizeof(duration));
|
|
|
|
vty_out(vty, " Running %s\n", duration);
|
|
|
|
|
|
|
|
/* Redistribute configuration */
|
|
|
|
/* XXX */
|
|
|
|
vty_out(vty, " LSA minimum arrival %d msecs\n",
|
|
|
|
o->lsa_minarrival);
|
|
|
|
|
2021-01-28 09:50:39 +01:00
|
|
|
vty_out(vty, " Maximum-paths %u\n", o->max_multipath);
|
2020-10-13 14:44:52 +02:00
|
|
|
|
|
|
|
/* Show SPF parameters */
|
|
|
|
vty_out(vty,
|
|
|
|
" Initial SPF scheduling delay %d millisec(s)\n"
|
|
|
|
" Minimum hold time between consecutive SPFs %d millsecond(s)\n"
|
|
|
|
" Maximum hold time between consecutive SPFs %d millsecond(s)\n"
|
|
|
|
" Hold time multiplier is currently %d\n",
|
|
|
|
o->spf_delay, o->spf_holdtime, o->spf_max_holdtime,
|
|
|
|
o->spf_hold_multiplier);
|
|
|
|
|
|
|
|
|
|
|
|
vty_out(vty, " SPF algorithm ");
|
|
|
|
if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) {
|
|
|
|
timersub(&now, &o->ts_spf, &result);
|
|
|
|
timerstring(&result, buf, sizeof(buf));
|
|
|
|
ospf6_spf_reason_string(o->last_spf_reason, rbuf,
|
|
|
|
sizeof(rbuf));
|
|
|
|
vty_out(vty, "last executed %s ago, reason %s\n", buf,
|
|
|
|
rbuf);
|
|
|
|
vty_out(vty, " Last SPF duration %lld sec %lld usec\n",
|
|
|
|
(long long)o->ts_spf_duration.tv_sec,
|
|
|
|
(long long)o->ts_spf_duration.tv_usec);
|
|
|
|
} else
|
|
|
|
vty_out(vty, "has not been run\n");
|
|
|
|
|
|
|
|
threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
|
|
|
|
vty_out(vty, " SPF timer %s%s\n",
|
|
|
|
(o->t_spf_calc ? "due in " : "is "), buf);
|
|
|
|
|
|
|
|
if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER))
|
|
|
|
vty_out(vty, " Router Is Stub Router\n");
|
|
|
|
|
|
|
|
/* LSAs */
|
|
|
|
vty_out(vty, " Number of AS scoped LSAs is %u\n",
|
|
|
|
o->lsdb->count);
|
|
|
|
|
|
|
|
/* Areas */
|
|
|
|
vty_out(vty, " Number of areas in this router is %u\n",
|
|
|
|
listcount(o->area_list));
|
|
|
|
|
|
|
|
if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
|
|
|
|
if (CHECK_FLAG(o->config_flags,
|
|
|
|
OSPF6_LOG_ADJACENCY_DETAIL))
|
|
|
|
vty_out(vty,
|
|
|
|
" All adjacency changes are logged\n");
|
|
|
|
else
|
|
|
|
vty_out(vty, " Adjacency changes are logged\n");
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
|
2020-10-13 14:44:52 +02:00
|
|
|
vty_out(vty, "\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-13 14:44:52 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa))
|
|
|
|
ospf6_area_show(vty, oa, json_areas, use_json);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-02-17 15:41:54 +01:00
|
|
|
DEFUN(show_ipv6_ospf6_vrfs, show_ipv6_ospf6_vrfs_cmd,
|
|
|
|
"show ipv6 ospf6 vrfs [json]",
|
|
|
|
SHOW_STR IP6_STR OSPF6_STR "Show OSPF6 VRFs \n" JSON_STR)
|
|
|
|
{
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_vrfs = NULL;
|
|
|
|
struct ospf6 *ospf6 = NULL;
|
|
|
|
struct listnode *node = NULL;
|
|
|
|
int count = 0;
|
|
|
|
char buf[PREFIX_STRLEN];
|
|
|
|
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(om6->ospf6, node, ospf6)) {
|
|
|
|
json_object *json_vrf = NULL;
|
|
|
|
const char *name = NULL;
|
|
|
|
int64_t vrf_id_ui = 0;
|
|
|
|
struct in_addr router_id;
|
|
|
|
|
|
|
|
router_id.s_addr = ospf6->router_id;
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if (!uj && count == 1)
|
|
|
|
vty_out(vty, "%s\n", header);
|
|
|
|
if (uj)
|
|
|
|
json_vrf = json_object_new_object();
|
|
|
|
|
|
|
|
if (ospf6->vrf_id == VRF_DEFAULT)
|
|
|
|
name = VRF_DEFAULT_NAME;
|
|
|
|
else
|
|
|
|
name = ospf6->name;
|
|
|
|
|
|
|
|
vrf_id_ui = (ospf6->vrf_id == VRF_UNKNOWN)
|
|
|
|
? -1
|
|
|
|
: (int64_t)ospf6->vrf_id;
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
|
|
|
|
json_object_string_add(json_vrf, "routerId",
|
|
|
|
inet_ntop(AF_INET, &router_id,
|
|
|
|
buf, sizeof(buf)));
|
|
|
|
json_object_object_add(json_vrfs, name, json_vrf);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-25s %-5d %-16s \n", name,
|
|
|
|
ospf6->vrf_id,
|
|
|
|
inet_ntop(AF_INET, &router_id, buf,
|
|
|
|
sizeof(buf)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uj) {
|
|
|
|
json_object_object_add(json, "vrfs", json_vrfs);
|
|
|
|
json_object_int_add(json, "totalVrfs", count);
|
|
|
|
|
|
|
|
vty_out(vty, "%s\n",
|
|
|
|
json_object_to_json_string_ext(
|
|
|
|
json, JSON_C_TO_STRING_PRETTY));
|
|
|
|
json_object_free(json);
|
|
|
|
} else {
|
|
|
|
if (count)
|
|
|
|
vty_out(vty, "\nTotal number of OSPF VRFs: %d\n",
|
|
|
|
count);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* show top level structures */
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN(show_ipv6_ospf6, show_ipv6_ospf6_cmd,
|
|
|
|
"show ipv6 ospf6 [vrf <NAME|all>] [json]",
|
|
|
|
SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR "All VRFs\n" JSON_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
struct listnode *node;
|
|
|
|
const char *vrf_name = NULL;
|
|
|
|
bool all_vrf = false;
|
|
|
|
int idx_vrf = 0;
|
|
|
|
|
2020-10-13 14:44:52 +02:00
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
json_object *json = NULL;
|
2004-05-18 20:57:06 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
OSPF6_CMD_CHECK_RUNNING();
|
|
|
|
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
2020-10-13 14:44:52 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
|
|
|
|
if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
ospf6_show(vty, ospf6, json, uj);
|
2020-10-13 14:44:52 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
if (!all_vrf)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-10-13 14:44:52 +02:00
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json_object_free(json);
|
2021-05-05 22:19:01 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN(show_ipv6_ospf6_route, show_ipv6_ospf6_route_cmd,
|
|
|
|
"show ipv6 ospf6 [vrf <NAME|all>] route [<intra-area|inter-area|external-1|external-2|X:X::X:X|X:X::X:X/M|detail|summary>] [json]",
|
|
|
|
SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
|
|
|
|
"All VRFs\n" ROUTE_STR
|
|
|
|
"Display Intra-Area routes\n"
|
|
|
|
"Display Inter-Area routes\n"
|
|
|
|
"Display Type-1 External routes\n"
|
|
|
|
"Display Type-2 External routes\n"
|
|
|
|
"Specify IPv6 address\n"
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Detailed information\n"
|
|
|
|
"Summary of route table\n" JSON_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
struct listnode *node;
|
|
|
|
const char *vrf_name = NULL;
|
|
|
|
bool all_vrf = false;
|
|
|
|
int idx_vrf = 0;
|
|
|
|
int idx_arg_start = 4;
|
2020-10-28 11:51:39 +01:00
|
|
|
bool uj = use_json(argc, argv);
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
OSPF6_CMD_CHECK_RUNNING();
|
|
|
|
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (idx_vrf > 0)
|
|
|
|
idx_arg_start += 2;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
|
|
|
|
if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
|
|
|
|
ospf6_route_table_show(vty, idx_arg_start, argc, argv,
|
|
|
|
ospf6->route_table, uj);
|
|
|
|
|
|
|
|
if (!all_vrf)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-05-20 03:03:41 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN(show_ipv6_ospf6_route_match, show_ipv6_ospf6_route_match_cmd,
|
|
|
|
"show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M <match|longer> [json]",
|
|
|
|
SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
|
|
|
|
"All VRFs\n" ROUTE_STR
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Display routes which match the specified route\n"
|
|
|
|
"Display routes longer than the specified route\n" JSON_STR)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
struct listnode *node;
|
|
|
|
const char *vrf_name = NULL;
|
|
|
|
bool all_vrf = false;
|
|
|
|
int idx_vrf = 0;
|
|
|
|
int idx_start_arg = 4;
|
2020-10-28 11:51:39 +01:00
|
|
|
bool uj = use_json(argc, argv);
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
OSPF6_CMD_CHECK_RUNNING();
|
|
|
|
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (idx_vrf > 0)
|
|
|
|
idx_start_arg += 2;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
|
|
|
|
if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
|
|
|
|
ospf6_route_table_show(vty, idx_start_arg, argc, argv,
|
|
|
|
ospf6->route_table, uj);
|
|
|
|
|
|
|
|
if (!all_vrf)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-05-20 03:03:41 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN(show_ipv6_ospf6_route_match_detail,
|
|
|
|
show_ipv6_ospf6_route_match_detail_cmd,
|
|
|
|
"show ipv6 ospf6 [vrf <NAME|all>] route X:X::X:X/M match detail [json]",
|
|
|
|
SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
|
|
|
|
"All VRFs\n" ROUTE_STR
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Display routes which match the specified route\n"
|
|
|
|
"Detailed information\n" JSON_STR)
|
2004-05-18 20:57:06 +02:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
struct listnode *node;
|
|
|
|
const char *vrf_name = NULL;
|
|
|
|
bool all_vrf = false;
|
|
|
|
int idx_vrf = 0;
|
|
|
|
int idx_start_arg = 4;
|
2020-10-28 11:51:39 +01:00
|
|
|
bool uj = use_json(argc, argv);
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
OSPF6_CMD_CHECK_RUNNING();
|
|
|
|
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (idx_vrf > 0)
|
|
|
|
idx_start_arg += 2;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
|
|
|
|
if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
|
|
|
|
ospf6_route_table_show(vty, idx_start_arg, argc, argv,
|
|
|
|
ospf6->route_table, uj);
|
|
|
|
|
|
|
|
if (!all_vrf)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-05-20 03:03:41 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
DEFUN(show_ipv6_ospf6_route_type_detail, show_ipv6_ospf6_route_type_detail_cmd,
|
|
|
|
"show ipv6 ospf6 [vrf <NAME|all>] route <intra-area|inter-area|external-1|external-2> detail [json]",
|
|
|
|
SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
|
|
|
|
"All VRFs\n" ROUTE_STR
|
|
|
|
"Display Intra-Area routes\n"
|
|
|
|
"Display Inter-Area routes\n"
|
|
|
|
"Display Type-1 External routes\n"
|
|
|
|
"Display Type-2 External routes\n"
|
|
|
|
"Detailed information\n" JSON_STR)
|
2004-09-03 08:04:00 +02:00
|
|
|
{
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
2021-05-05 22:19:01 +02:00
|
|
|
struct listnode *node;
|
|
|
|
const char *vrf_name = NULL;
|
|
|
|
bool all_vrf = false;
|
|
|
|
int idx_vrf = 0;
|
|
|
|
int idx_start_arg = 4;
|
2020-10-28 11:51:39 +01:00
|
|
|
bool uj = use_json(argc, argv);
|
2020-10-08 07:38:43 +02:00
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
OSPF6_CMD_CHECK_RUNNING();
|
|
|
|
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
|
|
|
if (idx_vrf > 0)
|
|
|
|
idx_start_arg += 2;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
|
|
|
|
if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
|
|
|
|
ospf6_route_table_show(vty, idx_start_arg, argc, argv,
|
|
|
|
ospf6->route_table, uj);
|
|
|
|
|
|
|
|
if (!all_vrf)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-05-20 03:03:41 +02:00
|
|
|
|
2004-09-03 08:04:00 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
|
2013-08-24 10:00:37 +02:00
|
|
|
{
|
|
|
|
if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
|
2017-07-13 19:12:39 +02:00
|
|
|
vty_out(vty, " stub-router administrative\n");
|
2013-08-24 10:00:37 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
|
2014-03-05 09:13:43 +01:00
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf6_distance *odistance;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
if (ospf6->distance_all)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " distance %u\n", ospf6->distance_all);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
if (ospf6->distance_intra || ospf6->distance_inter
|
|
|
|
|| ospf6->distance_external) {
|
|
|
|
vty_out(vty, " distance ospf6");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
if (ospf6->distance_intra)
|
|
|
|
vty_out(vty, " intra-area %u", ospf6->distance_intra);
|
|
|
|
if (ospf6->distance_inter)
|
|
|
|
vty_out(vty, " inter-area %u", ospf6->distance_inter);
|
|
|
|
if (ospf6->distance_external)
|
|
|
|
vty_out(vty, " external %u", ospf6->distance_external);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2014-03-05 09:13:43 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
|
2020-10-18 13:33:54 +02:00
|
|
|
if ((odistance = rn->info) != NULL)
|
|
|
|
vty_out(vty, " distance %u %pFX %s\n",
|
|
|
|
odistance->distance, &rn->p,
|
2017-06-21 05:10:57 +02:00
|
|
|
odistance->access_list ? odistance->access_list
|
|
|
|
: "");
|
2014-03-05 09:13:43 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* OSPF configuration write function. */
|
|
|
|
static int config_write_ospf6(struct vty *vty)
|
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *j, *k;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_area *oa;
|
|
|
|
struct ospf6_interface *oi;
|
2020-10-08 07:38:43 +02:00
|
|
|
struct ospf6 *ospf6;
|
|
|
|
struct listnode *node, *nnode;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-13 02:20:15 +02:00
|
|
|
/* OSPFv3 configuration. */
|
2020-10-08 07:38:43 +02:00
|
|
|
if (om6 == NULL)
|
2004-05-18 20:57:06 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
|
2021-05-05 22:19:01 +02:00
|
|
|
if (ospf6->name && strcmp(ospf6->name, VRF_DEFAULT_NAME))
|
|
|
|
vty_out(vty, "router ospf6 vrf %s\n", ospf6->name);
|
|
|
|
else
|
|
|
|
vty_out(vty, "router ospf6\n");
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
if (ospf6->router_id_static != 0)
|
|
|
|
vty_out(vty, " ospf6 router-id %pI4\n",
|
|
|
|
&ospf6->router_id_static);
|
|
|
|
|
|
|
|
/* log-adjacency-changes flag print. */
|
|
|
|
if (CHECK_FLAG(ospf6->config_flags,
|
|
|
|
OSPF6_LOG_ADJACENCY_CHANGES)) {
|
|
|
|
if (CHECK_FLAG(ospf6->config_flags,
|
|
|
|
OSPF6_LOG_ADJACENCY_DETAIL))
|
|
|
|
vty_out(vty, " log-adjacency-changes detail\n");
|
|
|
|
else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
|
|
|
|
vty_out(vty, " log-adjacency-changes\n");
|
|
|
|
} else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
|
|
|
|
vty_out(vty, " no log-adjacency-changes\n");
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
|
|
|
|
vty_out(vty, " auto-cost reference-bandwidth %d\n",
|
|
|
|
ospf6->ref_bandwidth);
|
|
|
|
|
|
|
|
/* LSA timers print. */
|
|
|
|
if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
|
|
|
|
vty_out(vty, " timers lsa min-arrival %d\n",
|
|
|
|
ospf6->lsa_minarrival);
|
|
|
|
|
2021-01-28 09:50:39 +01:00
|
|
|
/* ECMP max path config */
|
|
|
|
if (ospf6->max_multipath != MULTIPATH_NUM)
|
|
|
|
vty_out(vty, " maximum-paths %d\n",
|
|
|
|
ospf6->max_multipath);
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_stub_router_config_write(vty, ospf6);
|
|
|
|
ospf6_redistribute_config_write(vty, ospf6);
|
|
|
|
ospf6_area_config_write(vty, ospf6);
|
|
|
|
ospf6_spf_config_write(vty, ospf6);
|
|
|
|
ospf6_distance_config_write(vty, ospf6);
|
2021-02-10 05:53:46 +01:00
|
|
|
ospf6_distribute_config_write(vty, ospf6);
|
2020-10-08 07:38:43 +02:00
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
|
|
|
|
vty_out(vty, " interface %s area %s\n",
|
|
|
|
oi->interface->name, oa->name);
|
|
|
|
}
|
|
|
|
vty_out(vty, "!\n");
|
2004-05-18 20:57:06 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-09-08 22:31:43 +02:00
|
|
|
static int config_write_ospf6(struct vty *vty);
|
2004-05-18 20:57:06 +02:00
|
|
|
/* OSPF6 node structure. */
|
2008-12-01 20:10:34 +01:00
|
|
|
static struct cmd_node ospf6_node = {
|
2018-09-09 00:15:50 +02:00
|
|
|
.name = "ospf6",
|
2018-09-08 21:46:23 +02:00
|
|
|
.node = OSPF6_NODE,
|
2018-09-08 23:15:09 +02:00
|
|
|
.parent_node = CONFIG_NODE,
|
2018-09-08 21:46:23 +02:00
|
|
|
.prompt = "%s(config-ospf6)# ",
|
2018-09-08 22:31:43 +02:00
|
|
|
.config_write = config_write_ospf6,
|
2004-05-18 20:57:06 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Install ospf related commands. */
|
2008-08-15 14:45:30 +02:00
|
|
|
void ospf6_top_init(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-05-18 20:57:06 +02:00
|
|
|
/* Install ospf6 top node. */
|
2018-09-08 22:31:43 +02:00
|
|
|
install_node(&ospf6_node);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_cmd);
|
2021-02-17 15:41:54 +01:00
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_vrfs_cmd);
|
2004-05-18 20:57:06 +02:00
|
|
|
install_element(CONFIG_NODE, &router_ospf6_cmd);
|
2009-02-12 02:19:07 +01:00
|
|
|
install_element(CONFIG_NODE, &no_router_ospf6_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_route_cmd);
|
2004-05-18 20:57:06 +02:00
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
|
2004-09-03 08:04:00 +02:00
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
install_default(OSPF6_NODE);
|
|
|
|
install_element(OSPF6_NODE, &ospf6_router_id_cmd);
|
2017-08-28 19:38:42 +02:00
|
|
|
install_element(OSPF6_NODE, &no_ospf6_router_id_cmd);
|
2013-08-26 05:40:16 +02:00
|
|
|
install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
|
|
|
|
install_element(OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 03:04:07 +02:00
|
|
|
/* LSA timers commands */
|
|
|
|
install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
|
2013-08-24 10:00:37 +02:00
|
|
|
install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
|
2004-05-18 20:57:06 +02:00
|
|
|
|
2021-01-28 09:50:39 +01:00
|
|
|
/* maximum-paths command */
|
|
|
|
install_element(OSPF6_NODE, &ospf6_max_multipath_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_max_multipath_cmd);
|
|
|
|
|
2014-03-05 09:13:43 +01:00
|
|
|
install_element(OSPF6_NODE, &ospf6_distance_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_distance_cmd);
|
|
|
|
install_element(OSPF6_NODE, &ospf6_distance_ospf6_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_distance_ospf6_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|