2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* OSPF ABR functions.
|
|
|
|
* Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
|
|
|
|
*
|
|
|
|
* 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.
|
2017-05-13 10:25:29 +02:00
|
|
|
*
|
2002-12-13 21:15:29 +01:00
|
|
|
* 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 "thread.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "vty.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "plist.h"
|
|
|
|
#include "log.h"
|
|
|
|
|
|
|
|
#include "ospfd/ospfd.h"
|
|
|
|
#include "ospfd/ospf_interface.h"
|
|
|
|
#include "ospfd/ospf_ism.h"
|
|
|
|
#include "ospfd/ospf_asbr.h"
|
|
|
|
#include "ospfd/ospf_lsa.h"
|
|
|
|
#include "ospfd/ospf_lsdb.h"
|
|
|
|
#include "ospfd/ospf_neighbor.h"
|
|
|
|
#include "ospfd/ospf_nsm.h"
|
|
|
|
#include "ospfd/ospf_spf.h"
|
|
|
|
#include "ospfd/ospf_route.h"
|
|
|
|
#include "ospfd/ospf_ia.h"
|
|
|
|
#include "ospfd/ospf_flood.h"
|
|
|
|
#include "ospfd/ospf_abr.h"
|
|
|
|
#include "ospfd/ospf_ase.h"
|
|
|
|
#include "ospfd/ospf_zebra.h"
|
|
|
|
#include "ospfd/ospf_dump.h"
|
2018-08-21 14:14:32 +02:00
|
|
|
#include "ospfd/ospf_errors.h"
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
static struct ospf_area_range *ospf_area_range_new(struct prefix_ipv4 *p)
|
|
|
|
{
|
|
|
|
struct ospf_area_range *range;
|
|
|
|
|
|
|
|
range = XCALLOC(MTYPE_OSPF_AREA_RANGE, sizeof(struct ospf_area_range));
|
|
|
|
range->addr = p->prefix;
|
|
|
|
range->masklen = p->prefixlen;
|
|
|
|
range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
|
|
|
|
|
|
|
|
return range;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_area_range_free(struct ospf_area_range *range)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_OSPF_AREA_RANGE, range);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_area_range_add(struct ospf_area *area,
|
|
|
|
struct ospf_area_range *range)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct prefix_ipv4 p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefixlen = range->masklen;
|
|
|
|
p.prefix = range->addr;
|
2017-08-23 19:29:27 +02:00
|
|
|
apply_mask_ipv4(&p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
rn = route_node_get(area->ranges, (struct prefix *)&p);
|
|
|
|
if (rn->info)
|
|
|
|
route_unlock_node(rn);
|
|
|
|
else
|
|
|
|
rn->info = range;
|
|
|
|
}
|
|
|
|
|
2012-09-24 19:26:46 +02:00
|
|
|
static void ospf_area_range_delete(struct ospf_area *area,
|
|
|
|
struct route_node *rn)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2012-09-24 19:26:46 +02:00
|
|
|
struct ospf_area_range *range = rn->info;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2012-09-24 19:26:46 +02:00
|
|
|
if (range->specifics != 0)
|
2017-08-25 22:51:12 +02:00
|
|
|
ospf_delete_discard_route(area->ospf, area->ospf->new_table,
|
2012-09-24 19:26:46 +02:00
|
|
|
(struct prefix_ipv4 *)&rn->p);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2012-09-24 19:26:46 +02:00
|
|
|
ospf_area_range_free(range);
|
|
|
|
rn->info = NULL;
|
|
|
|
route_unlock_node(rn);
|
|
|
|
route_unlock_node(rn);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct ospf_area_range *ospf_area_range_lookup(struct ospf_area *area,
|
|
|
|
struct prefix_ipv4 *p)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
rn = route_node_lookup(area->ranges, (struct prefix *)p);
|
|
|
|
if (rn) {
|
|
|
|
route_unlock_node(rn);
|
|
|
|
return rn->info;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
struct ospf_area_range *ospf_area_range_lookup_next(struct ospf_area *area,
|
|
|
|
struct in_addr *range_net,
|
|
|
|
int first)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
struct ospf_area_range *find;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefixlen = IPV4_MAX_BITLEN;
|
|
|
|
p.prefix = *range_net;
|
2017-08-23 19:29:27 +02:00
|
|
|
apply_mask_ipv4(&p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (first)
|
|
|
|
rn = route_top(area->ranges);
|
|
|
|
else {
|
|
|
|
rn = route_node_get(area->ranges, (struct prefix *)&p);
|
|
|
|
rn = route_next(rn);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (; rn; rn = route_next(rn))
|
|
|
|
if (rn->info)
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (rn && rn->info) {
|
|
|
|
find = rn->info;
|
|
|
|
*range_net = rn->p.u.prefix4;
|
|
|
|
route_unlock_node(rn);
|
|
|
|
return find;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_area_range *ospf_area_range_match(struct ospf_area *area,
|
|
|
|
struct prefix_ipv4 *p)
|
|
|
|
{
|
|
|
|
struct route_node *node;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
node = route_node_match(area->ranges, (struct prefix *)p);
|
|
|
|
if (node) {
|
|
|
|
route_unlock_node(node);
|
|
|
|
return node->info;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ospf_area_range *ospf_area_range_match_any(struct ospf *ospf,
|
|
|
|
struct prefix_ipv4 *p)
|
|
|
|
{
|
|
|
|
struct ospf_area_range *range;
|
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 ospf_area *area;
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
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
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
|
|
|
if ((range = ospf_area_range_match(area, p)))
|
2002-12-13 21:15:29 +01:00
|
|
|
return range;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_area_range_active(struct ospf_area_range *range)
|
|
|
|
{
|
|
|
|
return range->specifics;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ospf_area_actively_attached(struct ospf_area *area)
|
|
|
|
{
|
|
|
|
return area->act_ints;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_area_range_set(struct ospf *ospf, struct in_addr area_id,
|
|
|
|
struct prefix_ipv4 *p, int advertise)
|
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_area_range *range;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-19 20:38:02 +02:00
|
|
|
area = ospf_area_get(ospf, area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area == NULL)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
range = ospf_area_range_lookup(area, p);
|
|
|
|
if (range != NULL) {
|
2018-09-25 06:44:23 +02:00
|
|
|
if (!CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
|
|
|
|
range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)
|
|
|
|
&& !CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
|
|
|
|
|| (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)
|
|
|
|
&& CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE)))
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
} else {
|
|
|
|
range = ospf_area_range_new(p);
|
|
|
|
ospf_area_range_add(area, range);
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (CHECK_FLAG(advertise, OSPF_AREA_RANGE_ADVERTISE))
|
|
|
|
SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
|
2018-09-25 06:44:23 +02:00
|
|
|
else {
|
2002-12-13 21:15:29 +01:00
|
|
|
UNSET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
|
2018-09-25 06:44:23 +02:00
|
|
|
range->cost_config = OSPF_AREA_RANGE_COST_UNSPEC;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_area_range_cost_set(struct ospf *ospf, struct in_addr area_id,
|
2018-03-27 21:13:34 +02:00
|
|
|
struct prefix_ipv4 *p, uint32_t cost)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_area_range *range;
|
|
|
|
|
2017-05-19 20:38:02 +02:00
|
|
|
area = ospf_area_get(ospf, area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area == NULL)
|
|
|
|
return 0;
|
|
|
|
|
2006-05-13 00:51:49 +02:00
|
|
|
range = ospf_area_range_lookup(area, p);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (range == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (range->cost_config != cost) {
|
|
|
|
range->cost_config = cost;
|
|
|
|
if (ospf_area_range_active(range))
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_area_range_unset(struct ospf *ospf, struct in_addr area_id,
|
|
|
|
struct prefix_ipv4 *p)
|
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
2012-09-24 19:26:46 +02:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area == NULL)
|
|
|
|
return 0;
|
|
|
|
|
2012-09-24 19:26:46 +02:00
|
|
|
rn = route_node_lookup(area->ranges, (struct prefix *)p);
|
|
|
|
if (rn == NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
|
2012-09-24 19:26:46 +02:00
|
|
|
if (ospf_area_range_active(rn->info))
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2012-09-24 19:26:46 +02:00
|
|
|
ospf_area_range_delete(area, rn);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_area_range_substitute_set(struct ospf *ospf, struct in_addr area_id,
|
|
|
|
struct prefix_ipv4 *p, struct prefix_ipv4 *s)
|
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_area_range *range;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-19 20:38:02 +02:00
|
|
|
area = ospf_area_get(ospf, area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
range = ospf_area_range_lookup(area, p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (range != NULL) {
|
|
|
|
if (!CHECK_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE)
|
|
|
|
|| !CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
} else {
|
|
|
|
range = ospf_area_range_new(p);
|
|
|
|
ospf_area_range_add(area, range);
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
SET_FLAG(range->flags, OSPF_AREA_RANGE_ADVERTISE);
|
|
|
|
SET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
|
|
|
|
range->subst_addr = s->prefix;
|
|
|
|
range->subst_masklen = s->prefixlen;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_area_range_substitute_unset(struct ospf *ospf, struct in_addr area_id,
|
|
|
|
struct prefix_ipv4 *p)
|
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_area_range *range;
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
range = ospf_area_range_lookup(area, p);
|
|
|
|
if (range == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (CHECK_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
|
|
|
|
if (ospf_area_range_active(range))
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
UNSET_FLAG(range->flags, OSPF_AREA_RANGE_SUBSTITUTE);
|
2020-02-06 07:49:02 +01:00
|
|
|
range->subst_addr.s_addr = INADDR_ANY;
|
2002-12-13 21:15:29 +01:00
|
|
|
range->subst_masklen = 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
int ospf_act_bb_connection(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-11-24 16:46:12 +01:00
|
|
|
struct ospf_interface *oi;
|
|
|
|
struct listnode *node;
|
|
|
|
int full_nbrs = 0;
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (ospf->backbone == NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
|
2021-11-24 16:46:12 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->backbone->oiflist, node, oi)) {
|
|
|
|
struct ospf_neighbor *nbr;
|
|
|
|
struct route_node *rn;
|
|
|
|
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
|
|
|
|
nbr = rn->info;
|
|
|
|
if (!nbr)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (nbr->state == NSM_Full
|
|
|
|
|| OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
|
|
|
full_nbrs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return full_nbrs;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
/* Determine whether this router is elected translator or not for area */
|
|
|
|
static int ospf_abr_nssa_am_elected(struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
struct router_lsa *rlsa;
|
|
|
|
struct in_addr *best = NULL;
|
2020-10-21 19:56:26 +02:00
|
|
|
char buf[PREFIX_STRLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-01-17 19:28:17 +01:00
|
|
|
LSDB_LOOP (ROUTER_LSDB(area), rn, lsa) {
|
2003-06-22 10:49:25 +02:00
|
|
|
/* sanity checks */
|
|
|
|
if (!lsa || (lsa->data->type != OSPF_ROUTER_LSA)
|
|
|
|
|| IS_LSA_SELF(lsa))
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
rlsa = (struct router_lsa *)lsa->data;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
/* ignore non-ABR routers */
|
|
|
|
if (!IS_ROUTER_LSA_BORDER(rlsa))
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
/* Router has Nt flag - always translate */
|
|
|
|
if (IS_ROUTER_LSA_NT(rlsa)) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_nssa_am_elected: router %pI4 asserts Nt",
|
|
|
|
&lsa->data->id);
|
2003-06-22 10:49:25 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
if (best == NULL)
|
|
|
|
best = &lsa->data->id;
|
2011-12-18 13:27:02 +01:00
|
|
|
else if (IPV4_ADDR_CMP(&best->s_addr, &lsa->data->id.s_addr)
|
|
|
|
< 0)
|
2003-06-22 10:49:25 +02:00
|
|
|
best = &lsa->data->id;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_nssa_am_elected: best electable ABR is: %s",
|
2020-10-21 19:56:26 +02:00
|
|
|
(best) ? inet_ntop(AF_INET, best, buf, sizeof(buf)) :
|
|
|
|
"<none>");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
if (best == NULL)
|
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2011-12-18 13:27:02 +01:00
|
|
|
if (IPV4_ADDR_CMP(&best->s_addr, &area->ospf->router_id.s_addr) < 0)
|
2003-06-22 10:49:25 +02:00
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check NSSA ABR status
|
|
|
|
* assumes there are nssa areas
|
|
|
|
*/
|
2020-11-19 08:23:14 +01:00
|
|
|
void ospf_abr_nssa_check_status(struct ospf *ospf)
|
2003-06-22 10:49:25 +02:00
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
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 *lnode, *nnode;
|
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(ospf->areas, lnode, nnode, area)) {
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t old_state = area->NSSATranslatorState;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
if (area->external_routing != OSPF_AREA_NSSA)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
if (IS_DEBUG_OSPF(nssa, NSSA))
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_nssa_check_status: checking area %pI4",
|
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:49:25 +02:00
|
|
|
if (!IS_OSPF_ABR(area->ospf)) {
|
|
|
|
if (IS_DEBUG_OSPF(nssa, NSSA))
|
2006-06-26 14:50:06 +02:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_nssa_check_status: not ABR");
|
2003-07-12 23:30:57 +02:00
|
|
|
area->NSSATranslatorState =
|
|
|
|
OSPF_NSSA_TRANSLATE_DISABLED;
|
2006-06-26 14:50:06 +02:00
|
|
|
} else {
|
|
|
|
switch (area->NSSATranslatorRole) {
|
|
|
|
case OSPF_NSSA_ROLE_NEVER:
|
|
|
|
/* We never Translate Type-7 LSA. */
|
|
|
|
/* TODO: check previous state and flush? */
|
|
|
|
if (IS_DEBUG_OSPF(nssa, NSSA))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_nssa_check_status: never translate");
|
2006-06-26 14:50:06 +02:00
|
|
|
area->NSSATranslatorState =
|
|
|
|
OSPF_NSSA_TRANSLATE_DISABLED;
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-06-26 14:50:06 +02:00
|
|
|
case OSPF_NSSA_ROLE_ALWAYS:
|
|
|
|
/* We always translate if we are an ABR
|
|
|
|
* TODO: originate new LSAs if state change?
|
|
|
|
* or let the nssa abr task take care of it?
|
|
|
|
*/
|
|
|
|
if (IS_DEBUG_OSPF(nssa, NSSA))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_nssa_check_status: translate always");
|
2006-06-26 14:50:06 +02:00
|
|
|
area->NSSATranslatorState =
|
|
|
|
OSPF_NSSA_TRANSLATE_ENABLED;
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-06-26 14:50:06 +02:00
|
|
|
case OSPF_NSSA_ROLE_CANDIDATE:
|
|
|
|
/* We are a candidate for Translation */
|
|
|
|
if (ospf_abr_nssa_am_elected(area) > 0) {
|
|
|
|
area->NSSATranslatorState =
|
|
|
|
OSPF_NSSA_TRANSLATE_ENABLED;
|
|
|
|
if (IS_DEBUG_OSPF(nssa, NSSA))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_nssa_check_status: elected translator");
|
2006-06-26 14:50:06 +02:00
|
|
|
} else {
|
|
|
|
area->NSSATranslatorState =
|
|
|
|
OSPF_NSSA_TRANSLATE_DISABLED;
|
|
|
|
if (IS_DEBUG_OSPF(nssa, NSSA))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_nssa_check_status: not elected");
|
2006-06-26 14:50:06 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2006-06-26 14:50:06 +02:00
|
|
|
}
|
|
|
|
/* RFC3101, 3.1:
|
|
|
|
* All NSSA border routers must set the E-bit in the Type-1
|
|
|
|
* router-LSAs
|
|
|
|
* of their directly attached non-stub areas, even when they are
|
|
|
|
* not
|
|
|
|
* translating.
|
|
|
|
*/
|
|
|
|
if (old_state != area->NSSATranslatorState) {
|
|
|
|
if (old_state == OSPF_NSSA_TRANSLATE_DISABLED)
|
|
|
|
ospf_asbr_status_update(ospf,
|
|
|
|
++ospf->redistribute);
|
|
|
|
else if (area->NSSATranslatorState
|
|
|
|
== OSPF_NSSA_TRANSLATE_DISABLED)
|
|
|
|
ospf_asbr_status_update(ospf,
|
|
|
|
--ospf->redistribute);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2006-06-26 14:50:06 +02:00
|
|
|
}
|
2003-06-22 10:49:25 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check area border router status. */
|
2003-04-19 02:31:59 +02:00
|
|
|
void ospf_check_abr_status(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
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;
|
2002-12-13 21:15:29 +01:00
|
|
|
int bb_configured = 0;
|
|
|
|
int bb_act_attached = 0;
|
|
|
|
int areas_configured = 0;
|
|
|
|
int areas_act_attached = 0;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t new_flags = ospf->flags;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_check_abr_status(): Start");
|
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(ospf->areas, node, nnode, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (listcount(area->oiflist)) {
|
|
|
|
areas_configured++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (OSPF_IS_AREA_BACKBONE(area))
|
|
|
|
bb_configured = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ospf_area_actively_attached(area)) {
|
|
|
|
areas_act_attached++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (OSPF_IS_AREA_BACKBONE(area))
|
|
|
|
bb_act_attached = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT) {
|
|
|
|
zlog_debug("ospf_check_abr_status(): looked through areas");
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_check_abr_status(): bb_configured: %d",
|
|
|
|
bb_configured);
|
|
|
|
zlog_debug("ospf_check_abr_status(): bb_act_attached: %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
bb_act_attached);
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_check_abr_status(): areas_configured: %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
areas_configured);
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_check_abr_status(): areas_act_attached: %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
areas_act_attached);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (ospf->abr_type) {
|
|
|
|
case OSPF_ABR_SHORTCUT:
|
|
|
|
case OSPF_ABR_STAND:
|
|
|
|
if (areas_act_attached > 1)
|
|
|
|
SET_FLAG(new_flags, OSPF_FLAG_ABR);
|
|
|
|
else
|
|
|
|
UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_ABR_IBM:
|
|
|
|
if ((areas_act_attached > 1) && bb_configured)
|
|
|
|
SET_FLAG(new_flags, OSPF_FLAG_ABR);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2002-12-13 21:15:29 +01:00
|
|
|
UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_ABR_CISCO:
|
|
|
|
if ((areas_configured > 1) && bb_act_attached)
|
|
|
|
SET_FLAG(new_flags, OSPF_FLAG_ABR);
|
|
|
|
else
|
|
|
|
UNSET_FLAG(new_flags, OSPF_FLAG_ABR);
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
default:
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (new_flags != ospf->flags) {
|
|
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_ABR_STATUS_CHANGE);
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2002-12-13 21:15:29 +01:00
|
|
|
"ospf_check_abr_status(): new router flags: %x",
|
2004-12-08 18:28:56 +01:00
|
|
|
new_flags);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf->flags = new_flags;
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_router_lsa_update(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_abr_update_aggregate(struct ospf_area_range *range,
|
2012-09-24 19:26:53 +02:00
|
|
|
struct ospf_route * or,
|
|
|
|
struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2012-09-24 19:26:53 +02:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_update_aggregate(): Start");
|
2012-09-24 19:26:53 +02:00
|
|
|
|
|
|
|
if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)
|
|
|
|
&& (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) {
|
|
|
|
range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2012-09-24 19:26:53 +02:00
|
|
|
"ospf_abr_update_aggregate(): use summary max-metric 0x%08x",
|
|
|
|
range->cost);
|
|
|
|
} else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2012-09-24 19:26:53 +02:00
|
|
|
"ospf_abr_update_aggregate(): use configured cost %d",
|
2004-02-19 20:37:47 +01:00
|
|
|
range->cost_config);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-02-19 20:37:47 +01:00
|
|
|
range->cost = range->cost_config;
|
2017-07-17 14:03:14 +02:00
|
|
|
} else {
|
2004-02-19 20:37:47 +01:00
|
|
|
if (range->specifics == 0) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2012-09-24 19:26:53 +02:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_update_aggregate(): use or->cost %d",
|
|
|
|
or->cost);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-09-24 19:26:53 +02:00
|
|
|
range->cost = or->cost; /* 1st time get 1st cost */
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-02-19 20:37:47 +01:00
|
|
|
if (or->cost > range->cost) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2012-09-24 19:26:53 +02:00
|
|
|
"ospf_abr_update_aggregate(): update to %d",
|
2004-02-19 20:37:47 +01:00
|
|
|
or->cost);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
range->cost = or->cost;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
range->specifics++;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void set_metric(struct ospf_lsa *lsa, uint32_t metric)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct summary_lsa *header;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *mp;
|
2002-12-13 21:15:29 +01:00
|
|
|
metric = htonl(metric);
|
2018-03-27 21:13:34 +02:00
|
|
|
mp = (uint8_t *)&metric;
|
2002-12-13 21:15:29 +01:00
|
|
|
mp++;
|
|
|
|
header = (struct summary_lsa *)lsa->data;
|
|
|
|
memcpy(header->metric, mp, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ospf_abr_translate_nssa */
|
2003-04-19 02:31:59 +02:00
|
|
|
static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* Incoming Type-7 or later aggregated Type-7
|
2003-07-12 23:30:57 +02:00
|
|
|
*
|
|
|
|
* LSA is skipped if P-bit is off.
|
|
|
|
* LSA is aggregated if within range.
|
|
|
|
*
|
|
|
|
* The Type-7 is translated, Installed/Approved as a Type-5 into
|
|
|
|
* global LSDB, then Flooded through AS
|
|
|
|
*
|
|
|
|
* Later, any Unapproved Translated Type-5's are flushed/discarded
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
struct ospf_lsa *old = NULL, *new = NULL;
|
|
|
|
struct as_external_lsa *ext7;
|
|
|
|
struct prefix_ipv4 p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): LSA Id %pI4, P-bit off, NO Translation",
|
|
|
|
&lsa->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): LSA Id %pI4, TRANSLATING 7 to 5",
|
|
|
|
&lsa->data->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
ext7 = (struct as_external_lsa *)(lsa->data);
|
|
|
|
p.prefix = lsa->data->id;
|
|
|
|
p.prefixlen = ip_masklen(ext7->mask);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): LSA Id %pI4, Forward address is 0, NO Translation",
|
|
|
|
&lsa->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* try find existing AS-External LSA for this prefix */
|
|
|
|
old = ospf_external_info_find_lsa(area->ospf, &p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-28 23:26:18 +02:00
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
|
|
|
|
/* if type-7 is removed, remove old translated type-5 lsa */
|
|
|
|
if (old) {
|
|
|
|
UNSET_FLAG(old->flags, OSPF_LSA_APPROVED);
|
2020-09-11 16:20:29 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): remove old translated LSA id %pI4",
|
|
|
|
&old->data->id);
|
2020-09-11 16:20:29 +02:00
|
|
|
}
|
2020-09-28 23:26:18 +02:00
|
|
|
/* if type-7 is removed and type-5 does not exist, do not
|
|
|
|
* originate */
|
|
|
|
return 1;
|
|
|
|
}
|
2020-09-11 16:20:29 +02:00
|
|
|
|
2020-09-28 23:26:18 +02:00
|
|
|
if (old && CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) {
|
2003-07-12 23:30:57 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): found old translated LSA Id %pI4, refreshing",
|
|
|
|
&old->data->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* refresh */
|
|
|
|
new = ospf_translated_nssa_refresh(area->ospf, lsa, old);
|
|
|
|
if (!new) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): could not refresh translated LSA Id %pI4",
|
|
|
|
&old->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* no existing external route for this LSA Id
|
|
|
|
* originate translated LSA
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-02 15:28:52 +01:00
|
|
|
if (ospf_translated_nssa_originate(area->ospf, lsa, old)
|
|
|
|
== NULL) {
|
2003-07-12 23:30:57 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5",
|
|
|
|
&lsa->data->id);
|
2017-02-03 14:22:15 +01:00
|
|
|
return 1;
|
2003-07-12 23:30:57 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Area where Aggregate testing will be inserted, just like summary
|
|
|
|
advertisements */
|
|
|
|
/* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void ospf_abr_translate_nssa_range(struct prefix_ipv4 *p, uint32_t cost)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* The Type-7 is created from the aggregated prefix and forwarded
|
|
|
|
for lsa installation and flooding... to be added... */
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost,
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa, *old = NULL;
|
|
|
|
struct summary_lsa *sl = NULL;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t full_cost;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_network_to_area(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-09-24 19:26:53 +02:00
|
|
|
if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
|
|
|
|
full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST;
|
|
|
|
else
|
|
|
|
full_cost = cost;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-04-08 07:57:15 +02:00
|
|
|
old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_SUMMARY_LSA, p,
|
2003-07-12 23:30:57 +02:00
|
|
|
area->ospf->router_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (old) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_announce_network_to_area(): old summary found");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
sl = (struct summary_lsa *)old->data;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_network_to_area(): old metric: %d, new metric: %d",
|
2003-07-12 23:30:57 +02:00
|
|
|
GET_METRIC(sl->metric), cost);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-09-24 19:26:53 +02:00
|
|
|
if ((GET_METRIC(sl->metric) == full_cost)
|
2012-09-24 19:26:50 +02:00
|
|
|
&& ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) {
|
2003-07-12 23:30:57 +02:00
|
|
|
/* unchanged. simply reapprove it */
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_network_to_area(): old summary approved");
|
2003-07-12 23:30:57 +02:00
|
|
|
SET_FLAG(old->flags, OSPF_LSA_APPROVED);
|
|
|
|
} else {
|
|
|
|
/* LSA is changed, refresh it */
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_network_to_area(): refreshing summary");
|
2012-09-24 19:26:53 +02:00
|
|
|
set_metric(old, full_cost);
|
2010-01-24 23:42:13 +01:00
|
|
|
lsa = ospf_lsa_refresh(area->ospf, old);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!lsa) {
|
2018-09-13 20:56:04 +02:00
|
|
|
flog_warn(EC_OSPF_LSA_MISSING,
|
2020-10-21 19:56:26 +02:00
|
|
|
"%s: Could not refresh %pFX to %pI4",
|
2020-10-18 13:33:54 +02:00
|
|
|
__func__, (struct prefix *)p,
|
2020-10-21 19:56:26 +02:00
|
|
|
&area->area_id);
|
2005-11-20 15:54:12 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-07-26 08:07:22 +02:00
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
|
2003-07-12 23:30:57 +02:00
|
|
|
/* This will flood through area. */
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
} else {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_network_to_area(): creating new summary");
|
2020-04-08 07:57:15 +02:00
|
|
|
lsa = ospf_summary_lsa_originate(p, full_cost, area);
|
2003-07-12 23:30:57 +02:00
|
|
|
/* This will flood through area. */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!lsa) {
|
2018-09-13 20:56:04 +02:00
|
|
|
flog_warn(EC_OSPF_LSA_MISSING,
|
2020-10-21 19:56:26 +02:00
|
|
|
"%s: Could not originate %pFX to %pi4",
|
2020-10-18 13:33:54 +02:00
|
|
|
__func__, (struct prefix *)p,
|
2020-10-21 19:56:26 +02:00
|
|
|
&area->area_id);
|
2005-11-20 15:54:12 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_network_to_area(): flooding new version of summary");
|
2005-11-20 15:54:12 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_network_to_area(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int ospf_abr_nexthops_belong_to_area(struct ospf_route * or,
|
|
|
|
struct ospf_area *area)
|
|
|
|
{
|
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;
|
2003-08-10 04:51:22 +02:00
|
|
|
struct ospf_path *path;
|
2009-07-27 12:42:34 +02:00
|
|
|
struct ospf_interface *oi;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2009-07-27 12:42:34 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(or->paths, node, path))
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(area->oiflist, nnode, oi))
|
|
|
|
if (oi->ifp && oi->ifp->ifindex == path->ifindex)
|
|
|
|
return 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
static int ospf_abr_should_accept(struct prefix_ipv4 *p, struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (IMPORT_NAME(area)) {
|
|
|
|
if (IMPORT_LIST(area) == NULL)
|
|
|
|
IMPORT_LIST(area) =
|
|
|
|
access_list_lookup(AFI_IP, IMPORT_NAME(area));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IMPORT_LIST(area))
|
|
|
|
if (access_list_apply(IMPORT_LIST(area), p)
|
|
|
|
== FILTER_DENY)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ospf_abr_plist_in_check(struct ospf_area *area,
|
|
|
|
struct ospf_route * or,
|
2003-07-12 23:30:57 +02:00
|
|
|
struct prefix_ipv4 *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (PREFIX_NAME_IN(area)) {
|
|
|
|
if (PREFIX_LIST_IN(area) == NULL)
|
|
|
|
PREFIX_LIST_IN(area) = prefix_list_lookup(
|
|
|
|
AFI_IP, PREFIX_NAME_IN(area));
|
|
|
|
if (PREFIX_LIST_IN(area))
|
|
|
|
if (prefix_list_apply(PREFIX_LIST_IN(area), p)
|
|
|
|
!= PREFIX_PERMIT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ospf_abr_plist_out_check(struct ospf_area *area,
|
|
|
|
struct ospf_route * or,
|
2003-07-12 23:30:57 +02:00
|
|
|
struct prefix_ipv4 *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (PREFIX_NAME_OUT(area)) {
|
|
|
|
if (PREFIX_LIST_OUT(area) == NULL)
|
|
|
|
PREFIX_LIST_OUT(area) = prefix_list_lookup(
|
|
|
|
AFI_IP, PREFIX_NAME_OUT(area));
|
|
|
|
if (PREFIX_LIST_OUT(area))
|
|
|
|
if (prefix_list_apply(PREFIX_LIST_OUT(area), p)
|
|
|
|
!= PREFIX_PERMIT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p,
|
2003-07-12 23:30:57 +02:00
|
|
|
struct ospf_route * or)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_area_range *range;
|
|
|
|
struct ospf_area *area, *or_area;
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_network(): Start");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
or_area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
assert(or_area);
|
|
|
|
|
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(ospf->areas, node, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_network(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (ospf_abr_nexthops_belong_to_area(or, area))
|
|
|
|
continue;
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (!ospf_abr_should_accept(p, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-14 19:17:14 +02:00
|
|
|
"ospf_abr_announce_network(): prefix %pFX was denied by import-list",
|
|
|
|
p);
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!ospf_abr_plist_in_check(area, or, p)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-14 19:17:14 +02:00
|
|
|
"ospf_abr_announce_network(): prefix %pFX was denied by prefix-list",
|
|
|
|
p);
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area->external_routing != OSPF_AREA_DEFAULT
|
|
|
|
&& area->no_summary) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_network(): area %pI4 is stub and no_summary",
|
|
|
|
&area->area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (or->path_type == OSPF_PATH_INTER_AREA) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-14 19:17:14 +02:00
|
|
|
"ospf_abr_announce_network(): this is inter-area route to %pFX",
|
|
|
|
p);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (!OSPF_IS_AREA_BACKBONE(area))
|
|
|
|
ospf_abr_announce_network_to_area(p, or->cost,
|
2017-07-17 14:03:14 +02:00
|
|
|
area);
|
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (or->path_type == OSPF_PATH_INTRA_AREA) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-14 19:17:14 +02:00
|
|
|
"ospf_abr_announce_network(): this is intra-area route to %pFX",
|
|
|
|
p);
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((range = ospf_area_range_match(or_area, p))
|
2017-02-03 14:22:15 +01:00
|
|
|
&& !ospf_area_is_transit(area))
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_abr_update_aggregate(range, or, area);
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_abr_announce_network_to_area(p, or->cost,
|
2017-07-17 14:03:14 +02:00
|
|
|
area);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
static int ospf_abr_should_announce(struct ospf *ospf, struct prefix_ipv4 *p,
|
|
|
|
struct ospf_route * or)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf_area *area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
area = ospf_area_lookup_by_area_id(ospf, or->u.std.area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
assert(area);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (EXPORT_NAME(area)) {
|
|
|
|
if (EXPORT_LIST(area) == NULL)
|
|
|
|
EXPORT_LIST(area) =
|
|
|
|
access_list_lookup(AFI_IP, EXPORT_NAME(area));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (EXPORT_LIST(area))
|
|
|
|
if (access_list_apply(EXPORT_LIST(area), p)
|
|
|
|
== FILTER_DENY)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_process_nssa_translates(struct ospf *ospf)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Scan through all NSSA_LSDB records for all areas;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
If P-bit is on, translate all Type-7's to 5's and aggregate or
|
|
|
|
flood install as approved in Type-5 LSDB with XLATE Flag on
|
|
|
|
later, do same for all aggregates... At end, DISCARD all
|
|
|
|
remaining UNAPPROVED Type-5's (Aggregate is for future ) */
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf_area *area;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_process_nssa_translates(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
|
|
if (!area->NSSATranslatorState)
|
2003-07-12 23:30:57 +02:00
|
|
|
continue; /* skip if not translator */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area->external_routing != OSPF_AREA_NSSA)
|
|
|
|
continue; /* skip if not Nssa Area */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_process_nssa_translates(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_abr_translate_nssa(area, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_process_nssa_translates(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_process_network_rt(struct ospf *ospf,
|
2003-07-12 23:30:57 +02:00
|
|
|
struct route_table *rt)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_route * or ;
|
|
|
|
struct route_node *rn;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("ospf_abr_process_network_rt(): Start");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
|
|
|
if ((or = rn->info) == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!(area = ospf_area_lookup_by_area_id(ospf,
|
|
|
|
or->u.std.area_id))) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_process_network_rt(): area %pI4 no longer exists",
|
|
|
|
&or->u.std.area_id);
|
2003-07-12 23:30:57 +02:00
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_process_network_rt(): this is a route to %pFX",
|
|
|
|
&rn->p);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_network_rt(): this is an External router, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (or->cost >= OSPF_LS_INFINITY) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_network_rt(): this route's cost is infinity, skipping");
|
2003-07-12 23:30:57 +02:00
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (or->type == OSPF_DESTINATION_DISCARD) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_network_rt(): this is a discard entry, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-22 14:52:33 +02:00
|
|
|
if (
|
|
|
|
or->path_type == OSPF_PATH_INTRA_AREA
|
|
|
|
&& !ospf_abr_should_announce(
|
|
|
|
ospf, (struct prefix_ipv4 *)&rn->p,
|
|
|
|
or)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_process_network_rt(): denied by export-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2017-07-22 14:52:33 +02:00
|
|
|
if (
|
|
|
|
or->path_type == OSPF_PATH_INTRA_AREA
|
|
|
|
&& !ospf_abr_plist_out_check(
|
|
|
|
area, or,
|
|
|
|
(struct prefix_ipv4 *)&rn->p)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_process_network_rt(): denied by prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if ((or->path_type == OSPF_PATH_INTER_AREA)
|
|
|
|
&& !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_network_rt(): this is route is not backbone one, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
|
|
if ((ospf->abr_type == OSPF_ABR_CISCO)
|
|
|
|
|| (ospf->abr_type == OSPF_ABR_IBM))
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (!ospf_act_bb_connection(ospf) &&
|
|
|
|
or->path_type != OSPF_PATH_INTRA_AREA) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_network_rt(): ALT ABR: No BB connection, skip not intra-area routes");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_process_network_rt(): announcing");
|
|
|
|
ospf_abr_announce_network(ospf, (struct prefix_ipv4 *)&rn->p,
|
2002-12-13 21:15:29 +01:00
|
|
|
or);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_process_network_rt(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, uint32_t cost,
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area *area)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *lsa, *old = NULL;
|
|
|
|
struct summary_lsa *slsa = NULL;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_rtr_to_area(): Start");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
old = ospf_lsa_lookup_by_prefix(area->lsdb, OSPF_ASBR_SUMMARY_LSA, p,
|
|
|
|
area->ospf->router_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (old) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_announce_rtr_to_area(): old summary found");
|
2002-12-13 21:15:29 +01:00
|
|
|
slsa = (struct summary_lsa *)old->data;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_network_to_area(): old metric: %d, new metric: %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
GET_METRIC(slsa->metric), cost);
|
|
|
|
}
|
|
|
|
|
2012-12-07 23:47:58 +01:00
|
|
|
if (old && (GET_METRIC(slsa->metric) == cost)
|
|
|
|
&& ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_announce_rtr_to_area(): old summary approved");
|
2002-12-13 21:15:29 +01:00
|
|
|
SET_FLAG(old->flags, OSPF_LSA_APPROVED);
|
2017-07-17 14:03:14 +02:00
|
|
|
} else {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_rtr_to_area(): 2.2");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
if (old) {
|
2002-12-13 21:15:29 +01:00
|
|
|
set_metric(old, cost);
|
2010-01-24 23:42:13 +01:00
|
|
|
lsa = ospf_lsa_refresh(area->ospf, old);
|
2017-07-17 14:03:14 +02:00
|
|
|
} else
|
2002-12-13 21:15:29 +01:00
|
|
|
lsa = ospf_summary_asbr_lsa_originate(p, cost, area);
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!lsa) {
|
2018-09-13 20:56:04 +02:00
|
|
|
flog_warn(EC_OSPF_LSA_MISSING,
|
2020-10-21 19:56:26 +02:00
|
|
|
"%s: Could not refresh/originate %pFX to %pI4",
|
2020-10-18 13:33:54 +02:00
|
|
|
__func__, (struct prefix *)p,
|
2020-10-21 19:56:26 +02:00
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_rtr_to_area(): flooding new version of summary");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_info ("ospf_abr_announce_rtr_to_area(): creating new
|
2002-12-13 21:15:29 +01:00
|
|
|
summary");
|
|
|
|
lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
|
|
|
|
|
2004-03-04 18:45:00 +01:00
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
|
|
|
|
/* ospf_flood_through_area (area, NULL, lsa);*/
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_rtr_to_area(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p,
|
|
|
|
struct ospf_route * or)
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct ospf_area *area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_rtr(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_rtr(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-12-08 18:28:56 +01:00
|
|
|
if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-12-08 18:28:56 +01:00
|
|
|
if (ospf_abr_nexthops_belong_to_area(or, area))
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-17 11:51:26 +02:00
|
|
|
/* RFC3101: Do not generate ASBR type 4 LSA if NSSA ABR */
|
|
|
|
if (or->u.std.external_routing == OSPF_AREA_NSSA) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_rtr(): do not generate LSA Type-4 %pI4 from NSSA",
|
|
|
|
&p->prefix);
|
2020-09-17 11:51:26 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (area->external_routing != OSPF_AREA_DEFAULT) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_rtr(): area %pI4 doesn't support external routing",
|
|
|
|
&area->area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2004-12-08 18:28:56 +01:00
|
|
|
if (or->path_type == OSPF_PATH_INTER_AREA) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_rtr(): this is inter-area route to %pI4",
|
|
|
|
&p->prefix);
|
2012-12-07 23:47:58 +01:00
|
|
|
if (!OSPF_IS_AREA_BACKBONE(area))
|
|
|
|
ospf_abr_announce_rtr_to_area(p, or->cost,
|
2017-07-17 14:03:14 +02:00
|
|
|
area);
|
|
|
|
}
|
|
|
|
|
2012-12-07 23:47:58 +01:00
|
|
|
if (or->path_type == OSPF_PATH_INTRA_AREA) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_rtr(): this is intra-area route to %pI4",
|
|
|
|
&p->prefix);
|
2004-12-08 18:28:56 +01:00
|
|
|
ospf_abr_announce_rtr_to_area(p, or->cost, area);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_rtr(): Stop");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_process_router_rt(struct ospf *ospf,
|
|
|
|
struct route_table *rt)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_route * or ;
|
2003-04-19 02:31:59 +02:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct list *l;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_process_router_rt(): Start");
|
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
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
|
|
|
struct listnode *node, *nnode;
|
2004-12-08 18:28:56 +01:00
|
|
|
char flag = 0;
|
|
|
|
struct ospf_route *best = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (rn->info == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
l = rn->info;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_process_router_rt(): this is a route to %pI4",
|
|
|
|
&rn->p.u.prefix4);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (ALL_LIST_ELEMENTS(l, node, nnode, or)) {
|
|
|
|
if (!ospf_area_lookup_by_area_id(ospf,
|
2003-04-19 02:31:59 +02:00
|
|
|
or->u.std.area_id)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_process_router_rt(): area %pI4 no longer exists",
|
|
|
|
&or->u.std.area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!CHECK_FLAG(or->u.std.flags, ROUTER_LSA_EXTERNAL)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_router_rt(): This is not an ASBR, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!flag) {
|
2003-04-19 02:31:59 +02:00
|
|
|
best = ospf_find_asbr_route(
|
|
|
|
ospf, rt, (struct prefix_ipv4 *)&rn->p);
|
2002-12-13 21:15:29 +01:00
|
|
|
flag = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (best == NULL)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (or != best) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_router_rt(): This route is not the best among possible, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2017-07-22 14:52:33 +02:00
|
|
|
if (
|
|
|
|
or->path_type == OSPF_PATH_INTER_AREA
|
|
|
|
&& !OSPF_IS_AREA_ID_BACKBONE(
|
|
|
|
or->u.std.area_id)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_router_rt(): This route is not a backbone one, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (or->cost >= OSPF_LS_INFINITY) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_router_rt(): This route has LS_INFINITY metric, skipping");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (ospf->abr_type == OSPF_ABR_CISCO
|
|
|
|
|| ospf->abr_type == OSPF_ABR_IBM)
|
|
|
|
if (!ospf_act_bb_connection(ospf) &&
|
|
|
|
or->path_type != OSPF_PATH_INTRA_AREA) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_process_network_rt(): ALT ABR: No BB connection, skip not intra-area routes");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2004-12-08 18:28:56 +01:00
|
|
|
ospf_abr_announce_rtr(ospf,
|
2002-12-13 21:15:29 +01:00
|
|
|
(struct prefix_ipv4 *)&rn->p, or);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_process_router_rt(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */
|
|
|
|
{
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
struct route_node *rn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_unapprove_translates(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* NSSA Translator is not checked, because it may have gone away,
|
|
|
|
and we would want to flush any residuals anyway */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) {
|
|
|
|
UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_unapprove_translates(): approved unset on link id %pI4",
|
|
|
|
&lsa->data->id);
|
2018-01-17 19:28:17 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_unapprove_translates(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_unapprove_summaries(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct ospf_area *area;
|
2003-04-19 02:31:59 +02:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_unapprove_summaries(): Start");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_unapprove_summaries(): considering area %pI4",
|
|
|
|
&area->area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
if (ospf_lsa_is_self_originated(ospf, lsa)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_unapprove_summaries(): approved unset on summary link id %pI4",
|
|
|
|
&lsa->data->id);
|
2018-01-17 19:28:17 +01:00
|
|
|
UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
if (ospf_lsa_is_self_originated(ospf, lsa)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_unapprove_summaries(): approved unset on asbr-summary link id %pI4",
|
|
|
|
&lsa->data->id);
|
2018-01-17 19:28:17 +01:00
|
|
|
UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("ospf_abr_unapprove_summaries(): Stop");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_prepare_aggregates(struct ospf *ospf)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
struct listnode *node;
|
2003-04-19 02:31:59 +02:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area_range *range;
|
|
|
|
struct ospf_area *area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_prepare_aggregates(): Start");
|
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(ospf->areas, node, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
for (rn = route_top(area->ranges); rn; rn = route_next(rn))
|
|
|
|
if ((range = rn->info) != NULL) {
|
|
|
|
range->cost = 0;
|
|
|
|
range->specifics = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_prepare_aggregates(): Stop");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_announce_aggregates(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf_area *area, *ar;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area_range *range;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct prefix p;
|
2003-04-19 02:31:59 +02:00
|
|
|
struct listnode *node, *n;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_aggregates(): Start");
|
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
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_aggregates(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (rn = route_top(area->ranges); rn; rn = route_next(rn))
|
|
|
|
if ((range = rn->info)) {
|
|
|
|
if (!CHECK_FLAG(range->flags,
|
|
|
|
OSPF_AREA_RANGE_ADVERTISE)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_aggregates(): discarding suppress-ranges");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
2003-07-12 23:30:57 +02:00
|
|
|
p.u.prefix4 = range->addr;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = range->masklen;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_aggregates(): this is range: %pFX",
|
|
|
|
&p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (CHECK_FLAG(range->flags,
|
|
|
|
OSPF_AREA_RANGE_SUBSTITUTE)) {
|
|
|
|
p.family = AF_INET;
|
2003-07-12 23:30:57 +02:00
|
|
|
p.u.prefix4 = range->subst_addr;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = range->subst_masklen;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (range->specifics) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_announce_aggregates(): active range");
|
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(ospf->areas,
|
2017-07-17 14:03:14 +02:00
|
|
|
n, ar)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ar == area)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* We do not check nexthops
|
|
|
|
here, because
|
|
|
|
intra-area routes can be
|
|
|
|
associated with
|
|
|
|
one area only */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* backbone routes are not
|
|
|
|
summarized
|
|
|
|
when announced into transit
|
2017-07-17 14:03:14 +02:00
|
|
|
areas */
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ospf_area_is_transit(ar)
|
|
|
|
&& OSPF_IS_AREA_BACKBONE(
|
2017-07-17 14:03:14 +02:00
|
|
|
area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_announce_aggregates(): Skipping announcement of BB aggregate into a transit area");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2004-03-04 18:45:00 +01:00
|
|
|
ospf_abr_announce_network_to_area(
|
|
|
|
(struct prefix_ipv4
|
2017-07-17 14:03:14 +02:00
|
|
|
*)&p,
|
2004-03-04 18:45:00 +01:00
|
|
|
range->cost, ar);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_aggregates(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
static void
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node; /*, n; */
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf_area *area; /*, *ar; */
|
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area_range *range;
|
|
|
|
struct prefix_ipv4 p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_send_nssa_aggregates(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
|
|
if (!area->NSSATranslatorState)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_send_nssa_aggregates(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
for (rn = route_top(area->ranges); rn; rn = route_next(rn)) {
|
|
|
|
if (rn->info == NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
range = rn->info;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (!CHECK_FLAG(range->flags,
|
2003-07-12 23:30:57 +02:00
|
|
|
OSPF_AREA_RANGE_ADVERTISE)) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"ospf_abr_send_nssa_aggregates(): discarding suppress-ranges");
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefix = range->addr;
|
|
|
|
p.prefixlen = range->masklen;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-12-08 18:28:56 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_send_nssa_aggregates(): this is range: %pFX",
|
|
|
|
&p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-12-08 18:28:56 +01:00
|
|
|
if (CHECK_FLAG(range->flags,
|
|
|
|
OSPF_AREA_RANGE_SUBSTITUTE)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefix = range->subst_addr;
|
|
|
|
p.prefixlen = range->subst_masklen;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (range->specifics) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_send_nssa_aggregates(): active range");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Fetch LSA-Type-7 from aggregate prefix, and
|
|
|
|
* then
|
|
|
|
* translate, Install (as Type-5), Approve, and
|
2017-07-17 14:03:14 +02:00
|
|
|
* Flood
|
|
|
|
*/
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf_abr_translate_nssa_range(&p, range->cost);
|
|
|
|
}
|
2003-06-22 10:49:25 +02:00
|
|
|
} /* all area ranges*/
|
2002-12-13 21:15:29 +01:00
|
|
|
} /* all areas */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_send_nssa_aggregates(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_announce_stub_defaults(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2003-07-12 23:30:57 +02:00
|
|
|
struct ospf_area *area;
|
2004-12-08 18:28:56 +01:00
|
|
|
struct prefix_ipv4 p;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (!IS_OSPF_ABR(ospf))
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_stub_defaults(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
2003-07-12 23:30:57 +02:00
|
|
|
p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_stub_defaults(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
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
|
|
|
if ((area->external_routing != OSPF_AREA_STUB)
|
|
|
|
&& (area->external_routing != OSPF_AREA_NSSA))
|
2002-12-13 21:15:29 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (OSPF_IS_AREA_BACKBONE(area))
|
|
|
|
continue; /* Sanity Check */
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4",
|
|
|
|
&area->area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_abr_announce_network_to_area(&p, area->default_cost, area);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_announce_stub_defaults(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)
|
2002-12-13 21:15:29 +01:00
|
|
|
&& !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) {
|
2017-07-17 14:03:14 +02:00
|
|
|
zlog_info(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_remove_unapproved_translates(): removing unapproved translates, ID: %pI4",
|
|
|
|
&lsa->data->id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* FLUSH THROUGHOUT AS */
|
2004-12-08 18:28:56 +01:00
|
|
|
ospf_lsa_flush_as(ospf, lsa);
|
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
|
|
|
/* DISCARD from LSDB */
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_remove_unapproved_translates(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
/* All AREA PROCESS should have APPROVED necessary LSAs */
|
|
|
|
/* Remove any left over and not APPROVED */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
|
|
|
zlog_debug("ospf_abr_remove_unapproved_translates(): Start");
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_abr_remove_unapproved_translates_apply(ospf, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_remove_unapproved_translates(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area *area;
|
2003-04-19 02:31:59 +02:00
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_remove_unapproved_summaries(): Start");
|
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(ospf->areas, node, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"ospf_abr_remove_unapproved_summaries(): looking at area %pI4",
|
|
|
|
&area->area_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
if (ospf_lsa_is_self_originated(ospf, lsa))
|
|
|
|
if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED))
|
|
|
|
ospf_lsa_flush_area(lsa, area);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
if (ospf_lsa_is_self_originated(ospf, lsa))
|
|
|
|
if (!CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED))
|
|
|
|
ospf_lsa_flush_area(lsa, area);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_remove_unapproved_summaries(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_manage_discard_routes(struct ospf *ospf)
|
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;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_area_range *range;
|
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(ospf->areas, node, nnode, area))
|
|
|
|
for (rn = route_top(area->ranges); rn; rn = route_next(rn))
|
|
|
|
if ((range = rn->info) != NULL)
|
|
|
|
if (CHECK_FLAG(range->flags,
|
|
|
|
OSPF_AREA_RANGE_ADVERTISE)) {
|
|
|
|
if (range->specifics)
|
2017-08-25 22:51:12 +02:00
|
|
|
ospf_add_discard_route(
|
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
|
|
|
ospf, ospf->new_table,
|
|
|
|
area,
|
|
|
|
(struct prefix_ipv4
|
|
|
|
*)&rn->p);
|
|
|
|
else
|
2017-08-25 22:51:12 +02:00
|
|
|
ospf_delete_discard_route(
|
2012-09-24 19:26:46 +02:00
|
|
|
ospf, ospf->new_table,
|
|
|
|
(struct prefix_ipv4
|
|
|
|
*)&rn->p);
|
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
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This is the function taking care about ABR NSSA, i.e. NSSA
|
|
|
|
Translator, -LSA aggregation and flooding. For all NSSAs
|
|
|
|
|
|
|
|
Any SELF-AS-LSA is in the Type-5 LSDB and Type-7 LSDB. These LSA's
|
|
|
|
are refreshed from the Type-5 LSDB, installed into the Type-7 LSDB
|
|
|
|
with the P-bit set.
|
|
|
|
|
|
|
|
Any received Type-5s are legal for an ABR, else illegal for IR.
|
|
|
|
Received Type-7s are installed, by area, with incoming P-bit. They
|
|
|
|
are flooded; if the Elected NSSA Translator, then P-bit off.
|
|
|
|
|
|
|
|
Additionally, this ABR will place "translated type-7's" into the
|
|
|
|
Type-5 LSDB in order to keep track of APPROVAL or not.
|
|
|
|
|
|
|
|
It will scan through every area, looking for Type-7 LSAs with P-Bit
|
|
|
|
SET. The Type-7's are either AS-FLOODED & 5-INSTALLED or
|
|
|
|
AGGREGATED. Later, the AGGREGATED LSAs are AS-FLOODED &
|
|
|
|
5-INSTALLED.
|
|
|
|
|
|
|
|
5-INSTALLED is into the Type-5 LSDB; Any UNAPPROVED Type-5 LSAs
|
|
|
|
left over are FLUSHED and DISCARDED.
|
|
|
|
|
|
|
|
For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
|
|
|
|
any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-05-31 15:27:51 +02:00
|
|
|
if (ospf->gr_info.restart_in_progress)
|
|
|
|
return;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("Check for NSSA-ABR Tasks():");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (!IS_OSPF_ABR(ospf))
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (!ospf->anyNSSA)
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Each area must confirm TranslatorRole */
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_nssa_task(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* For all Global Entries flagged "local-translate", unset APPROVED */
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_nssa_task(): unapprove translates");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_unapprove_translates(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* RESET all Ranges in every Area, same as summaries */
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_nssa_task(): NSSA initialize aggregates");
|
2003-06-22 10:49:25 +02:00
|
|
|
ospf_abr_prepare_aggregates(ospf); /*TURNED OFF just for now */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
|
2003-06-22 10:49:25 +02:00
|
|
|
* Aggregate as Type-7
|
|
|
|
* Install or Approve in Type-5 Global LSDB
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_nssa_task(): process translates");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_process_nssa_translates(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Translate/Send any "ranged" aggregates, and also 5-Install and
|
2003-06-22 10:49:25 +02:00
|
|
|
* Approve
|
|
|
|
* Scan Type-7's for aggregates, translate to Type-5's,
|
|
|
|
* Install/Flood/Approve
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_nssa_task(): send NSSA aggregates");
|
2003-06-22 10:49:25 +02:00
|
|
|
ospf_abr_send_nssa_aggregates(ospf); /*TURNED OFF FOR NOW */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Send any NSSA defaults as Type-5
|
|
|
|
*if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
* zlog_debug ("ospf_abr_nssa_task(): announce nssa defaults");
|
2003-07-12 23:30:57 +02:00
|
|
|
*ospf_abr_announce_nssa_defaults (ospf);
|
|
|
|
* havnt a clue what above is supposed to do.
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flush any unapproved previous translates from Global Data Base */
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_nssa_task(): remove unapproved translates");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_remove_unapproved_translates(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_manage_discard_routes(ospf); /* same as normal...discard */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_nssa_task(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This is the function taking care about ABR stuff, i.e.
|
|
|
|
summary-LSA origination and flooding. */
|
2003-04-19 02:31:59 +02:00
|
|
|
void ospf_abr_task(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-05-31 15:27:51 +02:00
|
|
|
if (ospf->gr_info.restart_in_progress)
|
|
|
|
return;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (ospf->new_table == NULL || ospf->new_rtrs == NULL) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug(
|
|
|
|
"ospf_abr_task(): Routing tables are not yet ready");
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): unapprove summaries");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_unapprove_summaries(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): prepare aggregates");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_prepare_aggregates(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
if (IS_OSPF_ABR(ospf)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): process network RT");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_process_network_rt(ospf, ospf->new_table);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): process router RT");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_process_router_rt(ospf, ospf->new_rtrs);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): announce aggregates");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_announce_aggregates(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): announce stub defaults");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_announce_stub_defaults(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): remove unapproved summaries");
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_remove_unapproved_summaries(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_manage_discard_routes(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("ospf_abr_task(): Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
static int ospf_abr_task_timer(struct thread *thread)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-04-19 02:31:59 +02:00
|
|
|
struct ospf *ospf = THREAD_ARG(thread);
|
|
|
|
|
|
|
|
ospf->t_abr_task = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("Running ABR task on timer");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_check_abr_status(ospf);
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf_abr_nssa_check_status(ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
ospf_abr_task(ospf);
|
2003-06-22 10:49:25 +02:00
|
|
|
ospf_abr_nssa_task(ospf); /* if nssa-abr, then scan Type-7 LSDB */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-19 02:31:59 +02:00
|
|
|
void ospf_schedule_abr_task(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 18:28:56 +01:00
|
|
|
zlog_debug("Scheduling ABR task");
|
2003-04-19 02:31:59 +02:00
|
|
|
|
2017-04-25 00:33:25 +02:00
|
|
|
thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY,
|
|
|
|
&ospf->t_abr_task);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|