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"
|
2021-06-28 13:55:27 +02:00
|
|
|
#include "ospf6_gr.h"
|
2020-10-28 11:51:39 +01:00
|
|
|
#include "lib/json.h"
|
2021-03-25 12:29:51 +01:00
|
|
|
#include "ospf6_nssa.h"
|
2021-05-30 18:33:41 +02:00
|
|
|
#include "ospf6_auth_trailer.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
|
|
|
);
|
|
|
|
|
2021-05-03 13:46:41 +02:00
|
|
|
#ifndef VTYSH_EXTRACT_PL
|
|
|
|
#include "ospf6d/ospf6_top_clippy.c"
|
|
|
|
#endif
|
|
|
|
|
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);
|
|
|
|
}
|
2021-05-18 00:24:22 +02:00
|
|
|
|
|
|
|
red_list = ospf6->redist[DEFAULT_ROUTE];
|
|
|
|
if (red_list) {
|
|
|
|
if (set)
|
|
|
|
vrf_bitmap_set(zclient->default_information[AFI_IP6],
|
|
|
|
ospf6->vrf_id);
|
|
|
|
else
|
|
|
|
vrf_bitmap_unset(zclient->default_information[AFI_IP6],
|
|
|
|
ospf6->vrf_id);
|
|
|
|
}
|
2021-05-05 22:17:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
2021-06-04 14:22:06 +02:00
|
|
|
ospf6_router_id_update(ospf6, true);
|
2021-05-05 22:17:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ospf6_vrf_init(void)
|
|
|
|
{
|
|
|
|
vrf_init(ospf6_vrf_new, ospf6_vrf_enable, ospf6_vrf_disable,
|
*: rework renaming the default VRF
Currently, it is possible to rename the default VRF either by passing
`-o` option to zebra or by creating a file in `/var/run/netns` and
binding it to `/proc/self/ns/net`.
In both cases, only zebra knows about the rename and other daemons learn
about it only after they connect to zebra. This is a problem, because
daemons may read their config before they connect to zebra. To handle
this rename after the config is read, we have some special code in every
single daemon, which is not very bad but not desirable in my opinion.
But things are getting worse when we need to handle this in northbound
layer as we have to manually rewrite the config nodes. This approach is
already hacky, but still works as every daemon handles its own NB
structures. But it is completely incompatible with the central
management daemon architecture we are aiming for, as mgmtd doesn't even
have a connection with zebra to learn from it. And it shouldn't have it,
because operational state changes should never affect configuration.
To solve the problem and simplify the code, I propose to expand the `-o`
option to all daemons. By using the startup option, we let daemons know
about the rename before they read their configs so we don't need any
special code to deal with it. There's an easy way to pass the option to
all daemons by using `frr_global_options` variable.
Unfortunately, the second way of renaming by creating a file in
`/var/run/netns` is incompatible with the new mgmtd architecture.
Theoretically, we could force daemons to read their configs only after
they connect to zebra, but it means adding even more code to handle a
very specific use-case. And anyway this won't work for mgmtd as it
doesn't have a connection with zebra. So I had to remove this option.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
2021-12-03 23:22:55 +01:00
|
|
|
ospf6_vrf_delete);
|
2021-06-21 17:04:46 +02:00
|
|
|
|
2021-08-25 18:29:42 +02:00
|
|
|
vrf_cmd_init(NULL);
|
2021-05-05 22:17:01 +02:00
|
|
|
}
|
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
|
|
|
{
|
2021-03-25 12:29:51 +01:00
|
|
|
struct ospf6 *ospf6 = NULL;
|
|
|
|
struct ospf6_area *oa = NULL;
|
|
|
|
|
|
|
|
if (route->table->scope_type == OSPF6_SCOPE_TYPE_GLOBAL)
|
|
|
|
ospf6 = route->table->scope;
|
|
|
|
else if (route->table->scope_type == OSPF6_SCOPE_TYPE_AREA) {
|
|
|
|
oa = (struct ospf6_area *)route->table->scope;
|
|
|
|
ospf6 = oa->ospf6;
|
2021-06-10 13:46:36 +02:00
|
|
|
} else {
|
|
|
|
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)
|
|
|
|
|| IS_OSPF6_DEBUG_BROUTER)
|
|
|
|
zlog_debug(
|
|
|
|
"%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
|
|
|
|
__func__, &route->prefix);
|
|
|
|
return;
|
2021-03-25 12:29:51 +01:00
|
|
|
}
|
2020-11-20 02:13:52 +01:00
|
|
|
|
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
|
|
|
{
|
2021-03-25 12:29:51 +01:00
|
|
|
struct ospf6 *ospf6 = NULL;
|
|
|
|
struct ospf6_area *oa = NULL;
|
|
|
|
|
|
|
|
if (route->table->scope_type == OSPF6_SCOPE_TYPE_GLOBAL)
|
|
|
|
ospf6 = route->table->scope;
|
|
|
|
else if (route->table->scope_type == OSPF6_SCOPE_TYPE_AREA) {
|
|
|
|
oa = (struct ospf6_area *)route->table->scope;
|
|
|
|
ospf6 = oa->ospf6;
|
2021-06-10 13:46:36 +02:00
|
|
|
} else {
|
|
|
|
if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)
|
|
|
|
|| IS_OSPF6_DEBUG_BROUTER)
|
|
|
|
zlog_debug(
|
|
|
|
"%s: Route is not GLOBAL or scope is not of TYPE_AREA: %pFX",
|
|
|
|
__func__, &route->prefix);
|
|
|
|
return;
|
2021-03-25 12:29:51 +01:00
|
|
|
}
|
2020-11-20 02:13:52 +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_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;
|
2021-05-28 11:33:03 +02:00
|
|
|
/* Setting this to 1, so that the LS ID 0 can be considered as invalid
|
|
|
|
* for self originated external LSAs. This helps in differentiating if
|
|
|
|
* an LSA is originated for any route or not in the route data.
|
|
|
|
* rt->route_option->id is by default 0
|
|
|
|
* Consider a route having id as 0 and prefix as 1::1, an external LSA
|
|
|
|
* is originated with ID 0.0.0.0. Now consider another route 2::2
|
|
|
|
* and for this LSA was not originated because of some configuration
|
|
|
|
* but the ID field rt->route_option->id is still 0.Consider now this
|
|
|
|
* 2::2 is being deleted, it will search LSA with LS ID as 0 and it
|
|
|
|
* will find the LSA and hence delete it but the LSA belonged to prefix
|
|
|
|
* 1::1, this happened because of LS ID 0.
|
|
|
|
*/
|
|
|
|
o->external_id = OSPF6_EXT_INIT_LS_ID;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-05-06 12:39:58 +02:00
|
|
|
o->write_oi_count = OSPF6_WRITE_INTERFACE_COUNT_DEFAULT;
|
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();
|
2021-05-28 11:33:03 +02:00
|
|
|
|
|
|
|
o->rt_aggr_tbl = route_table_init();
|
|
|
|
o->aggr_delay_interval = OSPF6_EXTL_AGGR_DEFAULT_DELAY;
|
|
|
|
o->aggr_action = OSPF6_ROUTE_AGGR_NONE;
|
|
|
|
|
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;
|
|
|
|
|
2021-03-10 18:59:07 +01:00
|
|
|
o->oi_write_q = list_new();
|
|
|
|
|
2021-06-28 09:04:54 +02:00
|
|
|
ospf6_gr_helper_init(o);
|
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);
|
|
|
|
|
2021-05-30 18:33:41 +02:00
|
|
|
/* If sequence number is stored in persistent storage, read it.
|
|
|
|
*/
|
|
|
|
if (ospf6_auth_nvm_file_exist() == OSPF6_AUTH_FILE_EXIST) {
|
|
|
|
ospf6_auth_seqno_nvm_read(o);
|
|
|
|
o->seqnum_h = o->seqnum_h + 1;
|
|
|
|
ospf6_auth_seqno_nvm_update(o);
|
|
|
|
} else {
|
|
|
|
o->seqnum_l = o->seqnum_h = 0;
|
|
|
|
ospf6_auth_seqno_nvm_update(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;
|
2021-05-26 00:49:30 +02:00
|
|
|
struct vrf *vrf;
|
|
|
|
struct interface *ifp;
|
2020-10-08 07:38:43 +02:00
|
|
|
|
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)
|
2021-06-04 14:22:06 +02:00
|
|
|
ospf6_router_id_update(ospf6, true);
|
2020-10-08 07:38:43 +02:00
|
|
|
ospf6_add(ospf6);
|
2021-05-26 00:49:30 +02:00
|
|
|
if (ospf6->vrf_id != VRF_UNKNOWN) {
|
|
|
|
vrf = vrf_lookup_by_id(ospf6->vrf_id);
|
|
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
|
|
|
if (ifp->info)
|
|
|
|
ospf6_interface_start(ifp->info);
|
|
|
|
}
|
|
|
|
}
|
2021-05-05 22:17:01 +02:00
|
|
|
if (ospf6->fd < 0)
|
|
|
|
return ospf6;
|
|
|
|
|
2021-07-02 18:01:32 +02:00
|
|
|
/*
|
|
|
|
* Read from non-volatile memory whether this instance is performing a
|
|
|
|
* graceful restart or not.
|
|
|
|
*/
|
|
|
|
ospf6_gr_nvm_read(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;
|
2021-05-28 11:33:03 +02:00
|
|
|
struct route_node *rn = NULL;
|
2004-05-18 20:57:06 +02:00
|
|
|
struct ospf6_area *oa;
|
2021-05-27 12:16:40 +02:00
|
|
|
struct vrf *vrf;
|
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
|
|
|
|
2021-06-28 09:04:54 +02:00
|
|
|
ospf6_gr_helper_deinit(o);
|
2021-07-02 18:01:32 +02:00
|
|
|
if (!o->gr_info.prepare_in_progress)
|
|
|
|
ospf6_flush_self_originated_lsas_now(o);
|
2020-10-08 07:38:43 +02:00
|
|
|
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);
|
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);
|
2021-03-10 18:59:07 +01:00
|
|
|
list_delete(&o->oi_write_q);
|
2014-03-05 09:13:43 +01:00
|
|
|
|
2021-05-27 12:16:40 +02:00
|
|
|
if (o->vrf_id != VRF_UNKNOWN) {
|
|
|
|
vrf = vrf_lookup_by_id(o->vrf_id);
|
|
|
|
if (vrf)
|
|
|
|
ospf6_vrf_unlink(o, vrf);
|
|
|
|
}
|
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
for (rn = route_top(o->rt_aggr_tbl); rn; rn = route_next(rn))
|
|
|
|
if (rn->info)
|
|
|
|
ospf6_external_aggregator_free(rn->info);
|
|
|
|
route_table_finish(o->rt_aggr_tbl);
|
|
|
|
|
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 */
|
2021-05-03 13:46:41 +02:00
|
|
|
ospf6_asbr_redistribute_disable(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);
|
2021-05-28 11:33:03 +02:00
|
|
|
THREAD_OFF(o->t_external_aggr);
|
2021-07-02 18:01:32 +02:00
|
|
|
THREAD_OFF(o->gr_info.t_grace_period);
|
ospf6d: Prevent use after free
I encountered a crash where the ospf6_write thread
was already thought to be scheduled by ospf6d:
(gdb) bt
t_ptr=0x5624ee6bd260) at lib/thread.c:972
(gdb)
When poking around it was noticed that the ospf6 pointer was crap:
(gdb) p (struct ospf6 *)$7
$8 = (struct ospf6 *) 0x5624ee6c6b20
(gdb) p *$8
$9 = {vrf_id = 3998487040, name = 0x5624ee420010 "\a", router_id = 65892, router_id_static = 65892, router_id_zebra = 0, starttime = {tv_sec = 1654674, tv_usec = 678673},
area_list = 0x0, backbone = 0x5624ee6c6710, lsdb = 0x5624ee6c2370, lsdb_self = 0x5624ee6c5d80, route_table = 0x5624ee6c5c10, brouter_table = 0x5624ee6c4690,
external_table = 0x5624ee6c4710, external_id_table = 0x5624ee6c4f10, external_id = 24, redist = {0x0 <repeats 32 times>}, nssa_default_import_check = {refcnt = 0,
status = false}, flag = 1 '\001', redistribute = 0, config_flags = 0 '\000', default_originate = 0, lsa_minarrival = 1000, spf_delay = 0, spf_holdtime = 50,
spf_max_holdtime = 5000, spf_hold_multiplier = 1, spf_reason = 554, ts_spf = {tv_sec = 1654712, tv_usec = 122041}, ts_spf_duration = {tv_sec = 0, tv_usec = 48},
last_spf_reason = 11, fd = -1, t_spf_calc = 0x0, t_ase_calc = 0x0, maxage_remover = 0x0, t_distribute_update = 0x0, t_ospf6_receive = 0x0, t_external_aggr = 0x0,
t_write = 0x5624ee6cc930, write_oi_count = 20, ref_bandwidth = 100000, distance_all = 0 '\000', distance_intra = 0 '\000', distance_inter = 0 '\000',
distance_external = 0 '\000', distance_table = 0x5624ee6c4f50, inst_shutdown = 1 '\001', max_multipath = 128, gr_info = {restart_support = false, restart_in_progress = false,
prepare_in_progress = false, finishing_restart = false, grace_period = 0, t_grace_period = 0x0}, ospf6_helper_cfg = {supported_grace_time = 1800, is_helper_supported = false,
strict_lsa_check = true, only_planned_restart = false, enable_rtr_list = 0x0, active_restarter_cnt = 0, last_exit_reason = 0}, anyNSSA = 0 '\000', t_abr_task = 0x0,
oi_write_q = 0x0, redist_count = 0, aggr_action = 1, aggr_delay_interval = 6, rt_aggr_tbl = 0x5624ee6c51b0, qobj_node = {nid = 6163304287853836241, nodehash = {hi = {next = 0x0,
hashval = 1613461457}}, type = 0x5624ed65e4e0 <qobj_t_ospf6>}}
Upon code inspection there was no place where we disabled the t_write thread upon ospf6 deletion.
If the code were to issue a `no router ospf6` and then recreate it. We could see this crash.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-11-18 00:46:06 +01:00
|
|
|
THREAD_OFF(o->t_write);
|
|
|
|
THREAD_OFF(o->t_abr_task);
|
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
|
|
|
}
|
|
|
|
|
2022-02-23 01:04:25 +01:00
|
|
|
static void ospf6_maxage_remover(struct thread *thread)
|
2004-05-18 20:57:06 +02:00
|
|
|
{
|
|
|
|
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
|
|
|
|
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);
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
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
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2021-06-30 15:18:50 +02:00
|
|
|
bool ospf6_router_id_update(struct ospf6 *ospf6, bool init)
|
2018-02-27 20:24:16 +01:00
|
|
|
{
|
2021-06-04 14:22:06 +02:00
|
|
|
in_addr_t new_router_id;
|
|
|
|
struct listnode *node;
|
|
|
|
struct ospf6_area *oa;
|
|
|
|
|
2018-02-27 20:24:16 +01:00
|
|
|
if (!ospf6)
|
2021-06-30 15:18:50 +02:00
|
|
|
return true;
|
2018-02-27 20:24:16 +01:00
|
|
|
|
|
|
|
if (ospf6->router_id_static != 0)
|
2021-06-04 14:22:06 +02:00
|
|
|
new_router_id = ospf6->router_id_static;
|
2018-02-27 20:24:16 +01:00
|
|
|
else
|
2021-06-04 14:22:06 +02:00
|
|
|
new_router_id = ospf6->router_id_zebra;
|
|
|
|
|
|
|
|
if (ospf6->router_id == new_router_id)
|
2021-06-30 15:18:50 +02:00
|
|
|
return true;
|
2021-06-04 14:22:06 +02:00
|
|
|
|
|
|
|
if (!init)
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
|
|
|
|
if (oa->full_nbrs) {
|
|
|
|
zlog_err(
|
2021-09-27 01:16:10 +02:00
|
|
|
"%s: cannot update router-id. Run the \"clear ipv6 ospf6 process\" command",
|
2021-06-04 14:22:06 +02:00
|
|
|
__func__);
|
2021-06-30 15:18:50 +02:00
|
|
|
return false;
|
2021-06-04 14:22:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf6->router_id = new_router_id;
|
2021-06-30 15:18:50 +02:00
|
|
|
return true;
|
2018-02-27 20:24:16 +01:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-05-03 13:46:41 +02:00
|
|
|
static void ospf6_db_clear(struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
struct ospf6_interface *oi;
|
|
|
|
struct interface *ifp;
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf6_area *oa;
|
|
|
|
|
|
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
|
|
|
if (if_is_operative(ifp) && ifp->info != NULL) {
|
|
|
|
oi = (struct ospf6_interface *)ifp->info;
|
|
|
|
ospf6_lsdb_remove_all(oi->lsdb);
|
|
|
|
ospf6_lsdb_remove_all(oi->lsdb_self);
|
|
|
|
ospf6_lsdb_remove_all(oi->lsupdate_list);
|
|
|
|
ospf6_lsdb_remove_all(oi->lsack_list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
|
|
|
|
ospf6_lsdb_remove_all(oa->lsdb);
|
|
|
|
ospf6_lsdb_remove_all(oa->lsdb_self);
|
|
|
|
|
|
|
|
ospf6_spf_table_finish(oa->spf_table);
|
|
|
|
ospf6_route_remove_all(oa->route_table);
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf6_lsdb_remove_all(ospf6->lsdb);
|
|
|
|
ospf6_lsdb_remove_all(ospf6->lsdb_self);
|
|
|
|
ospf6_route_remove_all(ospf6->route_table);
|
|
|
|
ospf6_route_remove_all(ospf6->brouter_table);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf6_process_reset(struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
|
|
|
|
|
2021-07-09 11:47:40 +02:00
|
|
|
ospf6_unset_all_aggr_flag(ospf6);
|
2021-05-03 13:46:41 +02:00
|
|
|
ospf6_flush_self_originated_lsas_now(ospf6);
|
|
|
|
ospf6->inst_shutdown = 0;
|
|
|
|
ospf6_db_clear(ospf6);
|
|
|
|
|
|
|
|
ospf6_asbr_redistribute_reset(ospf6);
|
|
|
|
FOR_ALL_INTERFACES (vrf, ifp)
|
|
|
|
ospf6_interface_clear(ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (clear_router_ospf6,
|
|
|
|
clear_router_ospf6_cmd,
|
|
|
|
"clear ipv6 ospf6 process [vrf NAME$name]",
|
|
|
|
CLEAR_STR
|
|
|
|
IP6_STR
|
|
|
|
OSPF6_STR
|
|
|
|
"Reset OSPF Process\n"
|
|
|
|
VRF_CMD_HELP_STR)
|
|
|
|
{
|
|
|
|
struct ospf6 *ospf6;
|
|
|
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
|
|
|
|
|
|
|
if (name != NULL)
|
|
|
|
vrf_name = name;
|
|
|
|
|
|
|
|
ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
|
2021-06-10 11:30:05 +02:00
|
|
|
if (ospf6 == NULL) {
|
2021-05-03 13:46:41 +02:00
|
|
|
vty_out(vty, "OSPFv3 is not configured\n");
|
2021-06-10 11:30:05 +02:00
|
|
|
} else {
|
|
|
|
ospf6_router_id_update(ospf6, true);
|
2021-05-03 13:46:41 +02:00
|
|
|
ospf6_process_reset(ospf6);
|
2021-06-10 11:30:05 +02:00
|
|
|
}
|
2021-05-03 13:46:41 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
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;
|
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
|
|
|
|
2021-06-10 11:30:05 +02:00
|
|
|
if (ospf6_router_id_update(o, false))
|
|
|
|
ospf6_process_reset(o);
|
|
|
|
else
|
2021-06-30 15:18:50 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
|
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
|
|
|
|
2017-08-28 19:38:42 +02:00
|
|
|
o->router_id_static = 0;
|
2018-02-12 22:22:04 +01:00
|
|
|
|
2021-06-10 11:30:05 +02:00
|
|
|
|
|
|
|
if (ospf6_router_id_update(o, false))
|
|
|
|
ospf6_process_reset(o);
|
|
|
|
else
|
2021-06-30 15:18:50 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"For this router-id change to take effect run the \"clear ipv6 ospf6 process\" command\n");
|
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;
|
|
|
|
}
|
|
|
|
|
lib, ospfd, ospf6d, zebra: add OSPF opaque route attributes
Update ospfd and ospf6d to send opaque route attributes to
zebra. Those attributes are stored in the RIB and can be viewed
using the "show ip[v6] route" commands (other than that, they are
completely ignored by zebra).
Example:
```
debian# show ip route 192.168.1.0/24
Routing entry for 192.168.1.0/24
Known via "ospf", distance 110, metric 20, best
Last update 01:57:08 ago
* 10.0.1.2, via eth-rt2, weight 1
OSPF path type : External-2
OSPF tag : 0
debian#
debian# show ip route 192.168.1.0/24 json
{
"192.168.1.0\/24":[
{
"prefix":"192.168.1.0\/24",
"prefixLen":24,
"protocol":"ospf",
"vrfId":0,
"vrfName":"default",
"selected":true,
[snip]
"ospfPathType":"External-2",
"ospfTag":"0"
}
]
}
```
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2021-09-21 03:15:55 +02:00
|
|
|
static void ospf6_reinstall_routes(struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
struct ospf6_route *route;
|
|
|
|
|
|
|
|
for (route = ospf6_route_head(ospf6->route_table); route;
|
|
|
|
route = ospf6_route_next(route))
|
|
|
|
ospf6_zebra_route_update_add(route, ospf6);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (ospf6_send_extra_data,
|
|
|
|
ospf6_send_extra_data_cmd,
|
|
|
|
"[no] ospf6 send-extra-data zebra",
|
|
|
|
NO_STR
|
|
|
|
OSPF6_STR
|
|
|
|
"Extra data to Zebra for display/use\n"
|
|
|
|
"To zebra\n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
if (no
|
|
|
|
&& CHECK_FLAG(ospf6->config_flags,
|
|
|
|
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
|
|
|
UNSET_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
|
|
|
|
ospf6_reinstall_routes(ospf6);
|
|
|
|
} else if (!CHECK_FLAG(ospf6->config_flags,
|
|
|
|
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA)) {
|
|
|
|
SET_FLAG(ospf6->config_flags, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA);
|
|
|
|
ospf6_reinstall_routes(ospf6);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
ospf6d: restart spf when distance is updated
if r1 has a route received from a neighbor and the same route
configured as static, the administrative distance will determine
which route to use
r1(config)# ipv6 route 1:1::1/128 Null0 70
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:12
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:00:49
The static route is selected. If we now change the administrative distance
in ospf6, the OSPF route should be selected
r1(config)# router ospf6
r1(config-ospf6)# distance 50
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:39
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:01:16
However the distance is not applied as there are no changes in the routing table
This commit will force the update of the routing table with the new configured distance
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
O>* 1:1::1/128 [50/20] via fe80::8cb7:e6ff:fef5:2344, r1-r2-eth0, weight 1, 00:00:03
S 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:19
Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2022-01-26 22:41:36 +01:00
|
|
|
uint8_t distance;
|
2014-03-05 09:13:43 +01:00
|
|
|
|
ospf6d: restart spf when distance is updated
if r1 has a route received from a neighbor and the same route
configured as static, the administrative distance will determine
which route to use
r1(config)# ipv6 route 1:1::1/128 Null0 70
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:12
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:00:49
The static route is selected. If we now change the administrative distance
in ospf6, the OSPF route should be selected
r1(config)# router ospf6
r1(config-ospf6)# distance 50
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:39
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:01:16
However the distance is not applied as there are no changes in the routing table
This commit will force the update of the routing table with the new configured distance
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
O>* 1:1::1/128 [50/20] via fe80::8cb7:e6ff:fef5:2344, r1-r2-eth0, weight 1, 00:00:03
S 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:19
Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2022-01-26 22:41:36 +01:00
|
|
|
distance = atoi(argv[1]->arg);
|
|
|
|
if (o->distance_all != distance) {
|
|
|
|
o->distance_all = distance;
|
|
|
|
ospf6_restart_spf(o);
|
|
|
|
}
|
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
|
|
|
|
ospf6d: restart spf when distance is updated
if r1 has a route received from a neighbor and the same route
configured as static, the administrative distance will determine
which route to use
r1(config)# ipv6 route 1:1::1/128 Null0 70
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:12
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:00:49
The static route is selected. If we now change the administrative distance
in ospf6, the OSPF route should be selected
r1(config)# router ospf6
r1(config-ospf6)# distance 50
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:39
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:01:16
However the distance is not applied as there are no changes in the routing table
This commit will force the update of the routing table with the new configured distance
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
O>* 1:1::1/128 [50/20] via fe80::8cb7:e6ff:fef5:2344, r1-r2-eth0, weight 1, 00:00:03
S 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:19
Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2022-01-26 22:41:36 +01:00
|
|
|
if (o->distance_all) {
|
|
|
|
o->distance_all = 0;
|
|
|
|
ospf6_restart_spf(o);
|
|
|
|
}
|
2014-03-05 09:13:43 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-05-26 00:49:30 +02:00
|
|
|
DEFUN_HIDDEN (ospf6_interface_area,
|
2004-05-18 20:57:06 +02:00
|
|
|
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-26 00:49:30 +02:00
|
|
|
uint32_t area_id;
|
|
|
|
int format;
|
|
|
|
|
|
|
|
vty_out(vty,
|
|
|
|
"This command is deprecated, because it is not VRF-aware.\n");
|
|
|
|
vty_out(vty,
|
|
|
|
"Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* find/create ospf6 interface */
|
2021-10-13 14:06:38 +02:00
|
|
|
ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
|
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-26 00:49:30 +02:00
|
|
|
if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
|
|
|
|
vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
oi->area_id = area_id;
|
|
|
|
oi->area_id_format = format;
|
|
|
|
|
|
|
|
oa = ospf6_area_lookup(area_id, ospf6);
|
|
|
|
if (oa == NULL)
|
|
|
|
oa = ospf6_area_create(area_id, ospf6, format);
|
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 */
|
2021-06-10 13:59:06 +02:00
|
|
|
if (ospf6_check_and_set_router_abr(ospf6)) {
|
2004-08-19 08:56:53 +02:00
|
|
|
ospf6_abr_enable_area(oa);
|
2021-03-25 12:29:51 +01:00
|
|
|
ospf6_schedule_abr_task(oa->ospf6);
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2021-05-26 00:49:30 +02:00
|
|
|
DEFUN_HIDDEN (no_ospf6_interface_area,
|
2004-05-18 20:57:06 +02:00
|
|
|
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
|
|
|
|
2021-05-26 00:49:30 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"This command is deprecated, because it is not VRF-aware.\n");
|
|
|
|
vty_out(vty,
|
|
|
|
"Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
|
|
|
|
|
2021-05-05 22:19:01 +02:00
|
|
|
/* find/create ospf6 interface */
|
2021-10-13 14:06:38 +02:00
|
|
|
ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
|
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
|
|
|
}
|
|
|
|
|
2021-05-26 00:49:30 +02:00
|
|
|
oi->area_id = 0;
|
|
|
|
oi->area_id_format = OSPF6_AREA_FMT_UNSET;
|
|
|
|
|
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*/
|
ospf6d: restart spf when distance is updated
if r1 has a route received from a neighbor and the same route
configured as static, the administrative distance will determine
which route to use
r1(config)# ipv6 route 1:1::1/128 Null0 70
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:12
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:00:49
The static route is selected. If we now change the administrative distance
in ospf6, the OSPF route should be selected
r1(config)# router ospf6
r1(config-ospf6)# distance 50
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
S>* 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:39
O 1:1::1/128 [110/20] via fe80::1833:c9ff:fe7b:3e43, r1-r2-eth0, weight 1, 00:01:16
However the distance is not applied as there are no changes in the routing table
This commit will force the update of the routing table with the new configured distance
r1# sh ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, F - PBR,
f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
O>* 1:1::1/128 [50/20] via fe80::8cb7:e6ff:fef5:2344, r1-r2-eth0, weight 1, 00:00:03
S 1:1::1/128 [70/0] unreachable (blackhole), weight 1, 00:00:19
Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
2022-01-26 22:41:36 +01:00
|
|
|
void ospf6_restart_spf(struct ospf6 *ospf6)
|
2021-01-28 09:50:39 +01:00
|
|
|
{
|
|
|
|
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);
|
2022-01-26 22:46:44 +01:00
|
|
|
json_object_int_add(json, "preference",
|
|
|
|
o->distance_all
|
|
|
|
? o->distance_all
|
|
|
|
: ZEBRA_OSPF6_DISTANCE_DEFAULT);
|
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));
|
|
|
|
|
2021-05-30 18:33:41 +02:00
|
|
|
json_object_int_add(json, "AuthTrailerHigherSeqNo",
|
|
|
|
o->seqnum_h);
|
|
|
|
json_object_int_add(json, "AuthTrailerLowerSeqNo", o->seqnum_l);
|
|
|
|
|
2020-10-13 14:44:52 +02:00
|
|
|
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);
|
2022-01-26 22:46:44 +01:00
|
|
|
vty_out(vty, " Administrative distance %u\n",
|
|
|
|
o->distance_all ? o->distance_all
|
|
|
|
: ZEBRA_OSPF6_DISTANCE_DEFAULT);
|
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));
|
|
|
|
|
2021-05-30 18:33:41 +02:00
|
|
|
vty_out(vty, " Authentication Sequence number info\n");
|
|
|
|
vty_out(vty, " Higher sequence no %u, Lower sequence no %u\n",
|
|
|
|
o->seqnum_h, o->seqnum_l);
|
|
|
|
|
2020-10-13 14:44:52 +02:00
|
|
|
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);
|
2021-11-18 09:57:55 +01:00
|
|
|
json_object_string_addf(json_vrf, "routerId", "%pI4",
|
|
|
|
&router_id);
|
2021-02-17 15:41:54 +01:00
|
|
|
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);
|
|
|
|
|
2021-11-25 16:50:37 +01:00
|
|
|
vty_json(vty, json);
|
2021-02-17 15:41:54 +01:00
|
|
|
} 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_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
|
|
|
|
2022-01-11 10:21:05 +01:00
|
|
|
OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
|
|
|
|
|
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_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
|
|
|
|
2022-01-11 10:21:05 +01:00
|
|
|
OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
|
|
|
|
|
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_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
|
|
|
|
2022-01-11 10:21:05 +01:00
|
|
|
OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
|
|
|
|
|
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_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
|
|
|
|
2022-01-11 10:21:05 +01:00
|
|
|
OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
|
|
|
|
|
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_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
|
|
|
|
2022-01-11 10:21:05 +01:00
|
|
|
OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
|
|
|
|
|
2004-09-03 08:04:00 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p)
|
|
|
|
{
|
|
|
|
struct in6_addr addr_zero;
|
|
|
|
|
|
|
|
memset(&addr_zero, 0, sizeof(struct in6_addr));
|
|
|
|
|
|
|
|
/* Default prefix validation*/
|
|
|
|
if ((is_default_prefix((struct prefix *)p))
|
|
|
|
|| (!memcmp(&p->u.prefix6, &addr_zero, sizeof(struct in6_addr)))) {
|
|
|
|
vty_out(vty, "Default address should not be configured as summary address.\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-07-09 11:47:40 +02:00
|
|
|
/* Host route should not be configured as summary address */
|
|
|
|
if (p->prefixlen == IPV6_MAX_BITLEN) {
|
2021-05-28 11:33:03 +02:00
|
|
|
vty_out(vty, "Host route should not be configured as summary address.\n");
|
2021-07-09 11:47:40 +02:00
|
|
|
return false;
|
2021-05-28 11:33:03 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 11:47:40 +02:00
|
|
|
return true;
|
2021-05-28 11:33:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* External Route Aggregation */
|
|
|
|
DEFPY (ospf6_external_route_aggregation,
|
|
|
|
ospf6_external_route_aggregation_cmd,
|
|
|
|
"summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)$mtype}]",
|
|
|
|
"External summary address\n"
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Router tag \n"
|
|
|
|
"Router tag value\n"
|
|
|
|
"Metric \n"
|
|
|
|
"Advertised metric for this route\n"
|
|
|
|
"OSPFv3 exterior metric type for summarised routes\n"
|
|
|
|
"Set OSPFv3 External Type 1/2 metrics\n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
struct prefix p;
|
|
|
|
int ret = CMD_SUCCESS;
|
2021-07-09 11:47:40 +02:00
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
p.family = AF_INET6;
|
|
|
|
ret = str2prefix(prefix_str, &p);
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "Malformed prefix\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply mask for given prefix. */
|
|
|
|
apply_mask((struct prefix *)&p);
|
|
|
|
|
|
|
|
if (!ospf6_is_valid_summary_addr(vty, &p))
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
|
|
|
if (!tag_str)
|
|
|
|
tag = 0;
|
|
|
|
|
|
|
|
if (!metric_str)
|
|
|
|
metric = -1;
|
|
|
|
|
|
|
|
if (!mtype_str)
|
|
|
|
mtype = DEFAULT_METRIC_TYPE;
|
|
|
|
|
|
|
|
ret = ospf6_external_aggr_config_set(ospf6, &p, tag, metric, mtype);
|
|
|
|
if (ret == OSPF6_FAILURE) {
|
|
|
|
vty_out(vty, "Invalid configuration!!\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY(no_ospf6_external_route_aggregation,
|
|
|
|
no_ospf6_external_route_aggregation_cmd,
|
|
|
|
"no summary-address X:X::X:X/M$prefix [tag (1-4294967295)] [{metric (0-16777215) | metric-type (1-2)}]",
|
|
|
|
NO_STR
|
|
|
|
"External summary address\n"
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Router tag\n"
|
|
|
|
"Router tag value\n"
|
|
|
|
"Metric \n"
|
|
|
|
"Advertised metric for this route\n"
|
|
|
|
"OSPFv3 exterior metric type for summarised routes\n"
|
|
|
|
"Set OSPFv3 External Type 1/2 metrics\n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
struct prefix p;
|
|
|
|
int ret = CMD_SUCCESS;
|
|
|
|
|
|
|
|
ret = str2prefix(prefix_str, &p);
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "Malformed prefix\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply mask for given prefix. */
|
|
|
|
apply_mask((struct prefix *)&p);
|
|
|
|
|
|
|
|
if (!ospf6_is_valid_summary_addr(vty, &p))
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
|
|
|
ret = ospf6_external_aggr_config_unset(ospf6, &p);
|
|
|
|
if (ret == OSPF6_INVALID)
|
|
|
|
vty_out(vty, "Invalid configuration!!\n");
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (ospf6_external_route_aggregation_no_advertise,
|
|
|
|
ospf6_external_route_aggregation_no_advertise_cmd,
|
|
|
|
"summary-address X:X::X:X/M$prefix no-advertise",
|
|
|
|
"External summary address\n"
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Don't advertise summary route \n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
struct prefix p;
|
|
|
|
int ret = CMD_SUCCESS;
|
|
|
|
|
|
|
|
ret = str2prefix(prefix_str, &p);
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "Malformed prefix\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply mask for given prefix. */
|
|
|
|
apply_mask((struct prefix *)&p);
|
|
|
|
|
|
|
|
if (!ospf6_is_valid_summary_addr(vty, &p))
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
|
|
|
ret = ospf6_asbr_external_rt_no_advertise(ospf6, &p);
|
|
|
|
if (ret == OSPF6_INVALID)
|
|
|
|
vty_out(vty, "!!Invalid configuration\n");
|
|
|
|
|
2021-07-09 11:47:40 +02:00
|
|
|
return CMD_SUCCESS;
|
2021-05-28 11:33:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (no_ospf6_external_route_aggregation_no_advertise,
|
|
|
|
no_ospf6_external_route_aggregation_no_advertise_cmd,
|
|
|
|
"no summary-address X:X::X:X/M$prefix no-advertise",
|
|
|
|
NO_STR
|
|
|
|
"External summary address\n"
|
|
|
|
"Specify IPv6 prefix\n"
|
|
|
|
"Adverise summary route to the AS \n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
struct prefix p;
|
|
|
|
int ret = CMD_SUCCESS;
|
|
|
|
|
|
|
|
ret = str2prefix(prefix_str, &p);
|
|
|
|
if (ret == 0) {
|
|
|
|
vty_out(vty, "Malformed prefix\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply mask for given prefix. */
|
|
|
|
apply_mask((struct prefix *)&p);
|
|
|
|
|
|
|
|
if (!ospf6_is_valid_summary_addr(vty, &p))
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
|
|
|
ret = ospf6_asbr_external_rt_advertise(ospf6, &p);
|
|
|
|
if (ret == OSPF6_INVALID)
|
|
|
|
vty_out(vty, "!!Invalid configuration\n");
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (ospf6_route_aggregation_timer,
|
|
|
|
ospf6_route_aggregation_timer_cmd,
|
|
|
|
"aggregation timer (5-1800)",
|
|
|
|
"External route aggregation\n"
|
|
|
|
"Delay timer (in seconds)\n"
|
|
|
|
"Timer interval(in seconds)\n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
ospf6_external_aggr_delay_timer_set(ospf6, timer);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (no_ospf6_route_aggregation_timer,
|
|
|
|
no_ospf6_route_aggregation_timer_cmd,
|
|
|
|
"no aggregation timer [5-1800]",
|
|
|
|
NO_STR
|
|
|
|
"External route aggregation\n"
|
|
|
|
"Delay timer\n"
|
|
|
|
"Timer interval(in seconds)\n")
|
|
|
|
{
|
|
|
|
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
|
|
|
|
|
|
|
ospf6_external_aggr_delay_timer_set(ospf6,
|
|
|
|
OSPF6_EXTL_AGGR_DEFAULT_DELAY);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ospf6_print_vty_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
|
|
|
|
{
|
|
|
|
struct ospf6_route *rt = bucket->data;
|
|
|
|
struct vty *vty = (struct vty *)arg;
|
|
|
|
static unsigned int count;
|
|
|
|
|
|
|
|
vty_out(vty, "%pFX ", &rt->prefix);
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if (count%5 == 0)
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
|
|
|
|
if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
|
|
|
|
count = 0;
|
|
|
|
|
|
|
|
return HASHWALK_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ospf6_print_json_external_routes_walkcb(struct hash_bucket *bucket, void *arg)
|
|
|
|
{
|
|
|
|
struct ospf6_route *rt = bucket->data;
|
|
|
|
struct json_object *json = (struct json_object *)arg;
|
|
|
|
char buf[PREFIX2STR_BUFFER];
|
|
|
|
char exnalbuf[20];
|
|
|
|
static unsigned int count;
|
|
|
|
|
|
|
|
prefix2str(&rt->prefix, buf, sizeof(buf));
|
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
snprintf(exnalbuf, sizeof(exnalbuf), "Exnl Addr-%d", count);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
|
|
|
json_object_string_add(json, exnalbuf, buf);
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if (OSPF6_EXTERNAL_RT_COUNT(rt->aggr_route) == count)
|
|
|
|
count = 0;
|
|
|
|
|
|
|
|
return HASHWALK_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
static void
|
|
|
|
ospf6_show_vrf_name(struct vty *vty, struct ospf6 *ospf6,
|
|
|
|
json_object *json)
|
|
|
|
{
|
|
|
|
if (json) {
|
|
|
|
if (ospf6->vrf_id == VRF_DEFAULT)
|
|
|
|
json_object_string_add(json, "vrfName",
|
|
|
|
"default");
|
|
|
|
else
|
|
|
|
json_object_string_add(json, "vrfName",
|
|
|
|
ospf6->name);
|
|
|
|
json_object_int_add(json, "vrfId", ospf6->vrf_id);
|
|
|
|
} else {
|
|
|
|
if (ospf6->vrf_id == VRF_DEFAULT)
|
|
|
|
vty_out(vty, "VRF Name: %s\n", "default");
|
|
|
|
else if (ospf6->name)
|
|
|
|
vty_out(vty, "VRF Name: %s\n", ospf6->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-31 14:17:03 +01:00
|
|
|
#if CONFDATE > 20230131
|
|
|
|
CPP_NOTICE("Remove JSON object commands with keys containing whitespaces")
|
|
|
|
#endif
|
2021-05-28 11:33:03 +02:00
|
|
|
static int
|
|
|
|
ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6,
|
|
|
|
json_object *json,
|
|
|
|
bool uj, const char *detail)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
2021-07-09 11:47:40 +02:00
|
|
|
static const char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n";
|
2021-07-20 07:25:10 +02:00
|
|
|
json_object *json_vrf = NULL;
|
2021-05-28 11:33:03 +02:00
|
|
|
|
|
|
|
if (!uj) {
|
2021-07-20 07:25:10 +02:00
|
|
|
ospf6_show_vrf_name(vty, ospf6, json_vrf);
|
2022-01-20 09:05:11 +01:00
|
|
|
vty_out(vty, "aggregation delay interval :%u(in seconds)\n\n",
|
|
|
|
ospf6->aggr_delay_interval);
|
2021-05-28 11:33:03 +02:00
|
|
|
vty_out(vty, "%s\n", header);
|
2021-07-09 11:47:40 +02:00
|
|
|
} else {
|
2021-07-20 07:25:10 +02:00
|
|
|
json_vrf = json_object_new_object();
|
|
|
|
|
|
|
|
ospf6_show_vrf_name(vty, ospf6, json_vrf);
|
|
|
|
|
|
|
|
json_object_int_add(json_vrf, "aggregation delay interval",
|
2022-01-31 14:17:03 +01:00
|
|
|
ospf6->aggr_delay_interval);
|
|
|
|
json_object_int_add(json_vrf, "aggregationDelayInterval",
|
|
|
|
ospf6->aggr_delay_interval);
|
2021-07-09 11:47:40 +02:00
|
|
|
}
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
|
|
|
|
if (!rn->info)
|
|
|
|
continue;
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
struct ospf6_external_aggr_rt *aggr = rn->info;
|
|
|
|
json_object *json_aggr = NULL;
|
|
|
|
char buf[PREFIX2STR_BUFFER];
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
prefix2str(&aggr->p, buf, sizeof(buf));
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
if (uj) {
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
json_aggr = json_object_new_object();
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
json_object_object_add(json_vrf,
|
2021-07-14 19:55:43 +02:00
|
|
|
buf,
|
|
|
|
json_aggr);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
json_object_string_add(json_aggr,
|
|
|
|
"Summary address",
|
|
|
|
buf);
|
2022-01-31 14:17:03 +01:00
|
|
|
json_object_string_add(json_aggr, "summaryAddress",
|
|
|
|
buf);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
json_object_string_add(
|
|
|
|
json_aggr, "Metric-type",
|
2021-05-28 11:33:03 +02:00
|
|
|
(aggr->mtype == DEFAULT_METRIC_TYPE)
|
2021-07-14 19:55:43 +02:00
|
|
|
? "E2"
|
|
|
|
: "E1");
|
2022-01-31 14:17:03 +01:00
|
|
|
json_object_string_add(
|
|
|
|
json_aggr, "metricType",
|
|
|
|
(aggr->mtype == DEFAULT_METRIC_TYPE) ? "E2"
|
|
|
|
: "E1");
|
2021-07-14 19:55:43 +02:00
|
|
|
|
|
|
|
json_object_int_add(json_aggr, "Metric",
|
|
|
|
(aggr->metric != -1)
|
|
|
|
? aggr->metric
|
|
|
|
: DEFAULT_DEFAULT_METRIC);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
json_object_int_add(json_aggr, "Tag",
|
|
|
|
aggr->tag);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
json_object_int_add(json_aggr,
|
|
|
|
"External route count",
|
2021-05-28 11:33:03 +02:00
|
|
|
OSPF6_EXTERNAL_RT_COUNT(aggr));
|
2022-01-31 14:17:03 +01:00
|
|
|
json_object_int_add(json_aggr, "externalRouteCount",
|
|
|
|
OSPF6_EXTERNAL_RT_COUNT(aggr));
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
|
|
|
|
json_object_int_add(json_aggr, "ID",
|
|
|
|
aggr->id);
|
|
|
|
json_object_int_add(json_aggr, "Flags",
|
|
|
|
aggr->aggrflags);
|
|
|
|
hash_walk(aggr->match_extnl_hash,
|
|
|
|
ospf6_print_json_external_routes_walkcb,
|
|
|
|
json_aggr);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
vty_out(vty, "%-22s", buf);
|
|
|
|
|
|
|
|
(aggr->mtype == DEFAULT_METRIC_TYPE)
|
|
|
|
? vty_out(vty, "%-16s", "E2")
|
|
|
|
: vty_out(vty, "%-16s", "E1");
|
|
|
|
vty_out(vty, "%-11d", (aggr->metric != -1)
|
|
|
|
? aggr->metric
|
|
|
|
: DEFAULT_DEFAULT_METRIC);
|
|
|
|
|
|
|
|
vty_out(vty, "%-12u", aggr->tag);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
vty_out(vty, "%-5ld\n",
|
|
|
|
OSPF6_EXTERNAL_RT_COUNT(aggr));
|
|
|
|
|
|
|
|
if (OSPF6_EXTERNAL_RT_COUNT(aggr) && detail) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Matched External routes:\n");
|
|
|
|
hash_walk(aggr->match_extnl_hash,
|
|
|
|
ospf6_print_vty_external_routes_walkcb,
|
|
|
|
vty);
|
2021-05-28 11:33:03 +02:00
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
2021-07-14 19:55:43 +02:00
|
|
|
|
|
|
|
vty_out(vty, "\n");
|
2021-05-28 11:33:03 +02:00
|
|
|
}
|
2021-07-14 19:55:43 +02:00
|
|
|
}
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
if (uj)
|
|
|
|
json_object_object_add(json, ospf6->name,
|
|
|
|
json_vrf);
|
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (show_ipv6_ospf6_external_aggregator,
|
|
|
|
show_ipv6_ospf6_external_aggregator_cmd,
|
2021-07-20 07:25:10 +02:00
|
|
|
"show ipv6 ospf6 [vrf <NAME|all>] summary-address [detail$detail] [json]",
|
2021-05-28 11:33:03 +02:00
|
|
|
SHOW_STR
|
|
|
|
IP6_STR
|
|
|
|
OSPF6_STR
|
2021-07-20 07:25:10 +02:00
|
|
|
VRF_CMD_HELP_STR
|
|
|
|
"All VRFs\n"
|
2021-05-28 11:33:03 +02:00
|
|
|
"Show external summary addresses\n"
|
2022-02-14 18:52:05 +01:00
|
|
|
"detailed information\n"
|
2021-05-28 11:33:03 +02:00
|
|
|
JSON_STR)
|
|
|
|
{
|
|
|
|
bool uj = use_json(argc, argv);
|
|
|
|
struct ospf6 *ospf6 = NULL;
|
2021-07-09 11:47:40 +02:00
|
|
|
json_object *json = NULL;
|
2021-07-20 07:25:10 +02:00
|
|
|
const char *vrf_name = NULL;
|
|
|
|
struct listnode *node;
|
|
|
|
bool all_vrf = false;
|
|
|
|
int idx_vrf = 0;
|
2021-05-28 11:33:03 +02:00
|
|
|
|
|
|
|
if (uj)
|
|
|
|
json = json_object_new_object();
|
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
|
|
|
|
if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-20 07:25:10 +02:00
|
|
|
ospf6_show_summary_address(vty, ospf6, json, uj,
|
|
|
|
detail);
|
|
|
|
|
|
|
|
if (!all_vrf)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-05-28 11:33:03 +02:00
|
|
|
|
|
|
|
if (uj) {
|
2021-11-25 16:50:37 +01:00
|
|
|
vty_json(vty, json);
|
2021-05-28 11:33:03 +02:00
|
|
|
}
|
|
|
|
|
2022-01-11 10:21:05 +01:00
|
|
|
OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
|
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2021-11-25 23:02:37 +01: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;
|
|
|
|
}
|
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
static int ospf6_asbr_summary_config_write(struct vty *vty, struct ospf6 *ospf6)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf6_external_aggr_rt *aggr;
|
|
|
|
char buf[PREFIX2STR_BUFFER];
|
|
|
|
|
|
|
|
if (ospf6->aggr_delay_interval != OSPF6_EXTL_AGGR_DEFAULT_DELAY)
|
|
|
|
vty_out(vty, " aggregation timer %u\n",
|
|
|
|
ospf6->aggr_delay_interval);
|
|
|
|
|
|
|
|
/* print 'summary-address A:B::C:D/M' */
|
2021-07-14 19:55:43 +02:00
|
|
|
for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {
|
|
|
|
if (!rn->info)
|
|
|
|
continue;
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
aggr = rn->info;
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
prefix2str(&aggr->p, buf, sizeof(buf));
|
|
|
|
vty_out(vty, " summary-address %s", buf);
|
|
|
|
if (aggr->tag)
|
|
|
|
vty_out(vty, " tag %u", aggr->tag);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
if (aggr->metric != -1)
|
|
|
|
vty_out(vty, " metric %d", aggr->metric);
|
2021-05-28 11:33:03 +02:00
|
|
|
|
2021-07-14 19:55:43 +02:00
|
|
|
if (aggr->mtype != DEFAULT_METRIC_TYPE)
|
|
|
|
vty_out(vty, " metric-type %d", aggr->mtype);
|
|
|
|
|
|
|
|
if (CHECK_FLAG(aggr->aggrflags,
|
|
|
|
OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE))
|
|
|
|
vty_out(vty, " no-advertise");
|
|
|
|
|
|
|
|
vty_out(vty, "\n");
|
|
|
|
}
|
2021-05-28 11:33:03 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:57:06 +02:00
|
|
|
/* OSPF configuration write function. */
|
|
|
|
static int config_write_ospf6(struct vty *vty)
|
|
|
|
{
|
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);
|
|
|
|
|
2022-01-23 14:08:46 +01:00
|
|
|
if (CHECK_FLAG(ospf6->config_flags,
|
|
|
|
OSPF6_SEND_EXTRA_DATA_TO_ZEBRA))
|
|
|
|
vty_out(vty, " ospf6 send-extra-data zebra\n");
|
lib, ospfd, ospf6d, zebra: add OSPF opaque route attributes
Update ospfd and ospf6d to send opaque route attributes to
zebra. Those attributes are stored in the RIB and can be viewed
using the "show ip[v6] route" commands (other than that, they are
completely ignored by zebra).
Example:
```
debian# show ip route 192.168.1.0/24
Routing entry for 192.168.1.0/24
Known via "ospf", distance 110, metric 20, best
Last update 01:57:08 ago
* 10.0.1.2, via eth-rt2, weight 1
OSPF path type : External-2
OSPF tag : 0
debian#
debian# show ip route 192.168.1.0/24 json
{
"192.168.1.0\/24":[
{
"prefix":"192.168.1.0\/24",
"prefixLen":24,
"protocol":"ospf",
"vrfId":0,
"vrfName":"default",
"selected":true,
[snip]
"ospfPathType":"External-2",
"ospfTag":"0"
}
]
}
```
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2021-09-21 03:15:55 +02:00
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
/* 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);
|
|
|
|
|
2021-05-06 12:39:58 +02:00
|
|
|
if (ospf6->write_oi_count
|
|
|
|
!= OSPF6_WRITE_INTERFACE_COUNT_DEFAULT)
|
|
|
|
vty_out(vty, " write-multiplier %d\n",
|
|
|
|
ospf6->write_oi_count);
|
|
|
|
|
2020-10-08 07:38:43 +02:00
|
|
|
/* 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);
|
2021-05-28 11:33:03 +02:00
|
|
|
ospf6_asbr_summary_config_write(vty, ospf6);
|
2021-07-02 18:01:32 +02:00
|
|
|
config_write_ospf6_gr(vty, ospf6);
|
2021-07-01 16:09:38 +02:00
|
|
|
config_write_ospf6_gr_helper(vty, ospf6);
|
2021-08-08 21:38:50 +02:00
|
|
|
|
|
|
|
vty_out(vty, "exit\n");
|
2020-10-08 07:38:43 +02:00
|
|
|
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
|
|
|
};
|
|
|
|
|
2021-05-03 13:46:41 +02:00
|
|
|
void install_element_ospf6_clear_process(void)
|
|
|
|
{
|
|
|
|
install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
|
|
|
|
}
|
|
|
|
|
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);
|
lib, ospfd, ospf6d, zebra: add OSPF opaque route attributes
Update ospfd and ospf6d to send opaque route attributes to
zebra. Those attributes are stored in the RIB and can be viewed
using the "show ip[v6] route" commands (other than that, they are
completely ignored by zebra).
Example:
```
debian# show ip route 192.168.1.0/24
Routing entry for 192.168.1.0/24
Known via "ospf", distance 110, metric 20, best
Last update 01:57:08 ago
* 10.0.1.2, via eth-rt2, weight 1
OSPF path type : External-2
OSPF tag : 0
debian#
debian# show ip route 192.168.1.0/24 json
{
"192.168.1.0\/24":[
{
"prefix":"192.168.1.0\/24",
"prefixLen":24,
"protocol":"ospf",
"vrfId":0,
"vrfName":"default",
"selected":true,
[snip]
"ospfPathType":"External-2",
"ospfTag":"0"
}
]
}
```
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2021-09-21 03:15:55 +02:00
|
|
|
install_element(OSPF6_NODE, &ospf6_send_extra_data_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);
|
|
|
|
|
2021-05-28 11:33:03 +02:00
|
|
|
/* ASBR Summarisation */
|
|
|
|
install_element(OSPF6_NODE, &ospf6_external_route_aggregation_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_external_route_aggregation_cmd);
|
|
|
|
install_element(OSPF6_NODE,
|
|
|
|
&ospf6_external_route_aggregation_no_advertise_cmd);
|
|
|
|
install_element(OSPF6_NODE,
|
|
|
|
&no_ospf6_external_route_aggregation_no_advertise_cmd);
|
|
|
|
install_element(OSPF6_NODE, &ospf6_route_aggregation_timer_cmd);
|
|
|
|
install_element(OSPF6_NODE, &no_ospf6_route_aggregation_timer_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ipv6_ospf6_external_aggregator_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
|
|
|
}
|