This commit is contained in:
Martin Buck 2025-04-29 16:22:43 +00:00 committed by GitHub
commit d770efbbb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 272 additions and 373 deletions

View file

@ -91,16 +91,11 @@ static int ospf6_abr_nexthops_belong_to_area(struct ospf6_route *route,
return 0;
}
static void ospf6_abr_delete_route(struct ospf6_route *summary,
struct ospf6_route_table *summary_table,
struct ospf6_lsa *old)
static void ospf6_abr_summary_remove(struct ospf6_route *summary,
struct ospf6_route_table *summary_table)
{
if (summary) {
if (summary)
ospf6_route_remove(summary, summary_table);
}
if (old && !OSPF6_LSA_IS_MAXAGE(old))
ospf6_lsa_purge(old);
}
void ospf6_abr_enable_area(struct ospf6_area *area)
@ -180,21 +175,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
buf);
}
if (route->type == OSPF6_DEST_TYPE_ROUTER)
summary_table = area->summary_router;
else
summary_table = area->summary_prefix;
summary = ospf6_route_lookup(&route->prefix, summary_table);
if (summary) {
old = ospf6_lsdb_lookup(summary->path.origin.type,
summary->path.origin.id,
area->ospf6->router_id, area->lsdb);
/* Reset the OSPF6_LSA_UNAPPROVED flag */
if (old)
UNSET_FLAG(old->flag, OSPF6_LSA_UNAPPROVED);
}
/* Only destination type network, range or ASBR are considered */
if (route->type != OSPF6_DEST_TYPE_NETWORK
&& route->type != OSPF6_DEST_TYPE_RANGE
@ -225,6 +205,34 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
return 0;
}
if (route->type == OSPF6_DEST_TYPE_ROUTER)
summary_table = area->summary_router;
else
summary_table = area->summary_prefix;
/* Search for a possible previous summary LSA for this route with
* matching prefix *and* path
*/
summary = ospf6_route_lookup(&route->prefix, summary_table);
for (; summary; summary = summary->next) {
if (!ospf6_route_is_same(route, summary)) {
/* reached different prefix, no match */
summary = NULL;
break;
}
/* Don't compare path.origin.id as we use that to store the
* ID of the originated LSA
*/
if (route->type == summary->type && route->path.type == summary->path.type &&
route->path.origin.adv_router == summary->path.origin.adv_router)
/* match */
break;
}
if (summary) {
old = ospf6_lsdb_lookup(summary->path.origin.type, summary->path.origin.id,
area->ospf6->router_id, area->lsdb);
}
if (route->type == OSPF6_DEST_TYPE_NETWORK) {
bool filter = false;
@ -279,11 +287,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
}
if (filter) {
if (summary) {
ospf6_route_remove(summary, summary_table);
if (old)
ospf6_lsa_purge(old);
}
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
}
@ -369,13 +373,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
zlog_debug(
"The range is not active. withdraw");
ospf6_abr_delete_route(summary, summary_table,
old);
ospf6_abr_summary_remove(summary, summary_table);
}
} else if (old) {
ospf6_route_remove(summary, summary_table);
ospf6_lsa_purge(old);
}
} else
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
@ -385,7 +386,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
zlog_debug(
"Area has been stubbed, purge Inter-Router LSA");
ospf6_abr_delete_route(summary, summary_table, old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
@ -394,7 +395,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
if (is_debug)
zlog_debug("Area has been stubbed, purge prefix LSA");
ospf6_abr_delete_route(summary, summary_table, old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
@ -416,8 +417,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
if (is_debug)
zlog_debug(
"The cost exceeds LSInfinity, withdraw");
if (old)
ospf6_lsa_purge(old);
return 0;
}
}
@ -429,7 +428,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
if (is_debug)
zlog_debug(
"This is the secondary path to the ASBR, ignore");
ospf6_abr_delete_route(summary, summary_table, old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
@ -443,7 +442,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
zlog_debug(
"%s: The route comes from NSSA area, skip",
__func__);
ospf6_abr_delete_route(summary, summary_table, old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
@ -477,8 +476,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
* remove it in this case
*/
if (summary && summary->type != OSPF6_DEST_TYPE_RANGE)
ospf6_abr_delete_route(summary, summary_table,
old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
}
@ -490,7 +488,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
if (is_debug)
zlog_debug(
"This is the range with DoNotAdvertise set. ignore");
ospf6_abr_delete_route(summary, summary_table, old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
@ -498,7 +496,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) {
if (is_debug)
zlog_debug("The range is not active. withdraw");
ospf6_abr_delete_route(summary, summary_table, old);
ospf6_abr_summary_remove(summary, summary_table);
return 0;
}
}
@ -507,7 +505,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
*/
if (summary == NULL) {
summary = ospf6_route_copy(route);
summary->path.origin.adv_router = area->ospf6->router_id;
if (route->type == OSPF6_DEST_TYPE_ROUTER) {
summary->path.origin.type =
@ -524,27 +521,20 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
if (old)
summary->path.origin.id = old->header->id;
else
summary->path.origin.id = ospf6_new_ls_id(
summary->path.origin.type,
summary->path.origin.adv_router,
area->lsdb);
summary->path.origin.id =
ospf6_new_ls_id(htons(OSPF6_LSTYPE_INTER_PREFIX),
area->ospf6->router_id, area->lsdb);
}
summary = ospf6_route_add(summary, summary_table);
} else {
summary->type = route->type;
monotime(&summary->changed);
}
summary->prefix_options = route->prefix_options;
summary->path.router_bits = route->path.router_bits;
summary->path.options[0] = route->path.options[0];
summary->path.options[1] = route->path.options[1];
summary->path.options[2] = route->path.options[2];
summary->path.area_id = area->area_id;
summary->path.type = OSPF6_PATH_TYPE_INTER;
summary->path.subtype = route->path.subtype;
summary->path.cost = route->path.cost;
/* summary->nexthop[0] = route->nexthop[0]; */
/* Reset the unapproved flag on the existing LSA (that one will be
* retained instead of the new LSA if they're identical)
*/
if (old)
UNSET_FLAG(old->flag, OSPF6_LSA_UNAPPROVED);
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
@ -594,9 +584,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
/* create LSA */
lsa = ospf6_lsa_create(lsa_header);
/* Reset the unapproved flag */
UNSET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
/* Originate */
ospf6_lsa_originate_area(lsa, area);
@ -1397,7 +1384,7 @@ void ospf6_abr_examin_brouter(uint32_t router_id, struct ospf6_route *route,
ospf6_abr_examin_summary(lsa, oa);
}
void ospf6_abr_prefix_resummarize(struct ospf6 *o)
static void ospf6_abr_prefix_resummarize(struct ospf6 *o)
{
struct ospf6_route *route;
@ -1412,6 +1399,184 @@ void ospf6_abr_prefix_resummarize(struct ospf6 *o)
zlog_debug("Finished re-examining Inter-Prefix Summaries");
}
/* Mark the summary LSA's as unapproved, when ABR status changes.*/
static void ospf6_abr_unapprove_summaries(struct ospf6 *ospf6)
{
struct listnode *node, *nnode;
struct ospf6_area *area;
struct ospf6_lsa *lsa;
uint16_t type;
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : considering area %pI4", __func__, &area->area_id);
/* Inter area router LSA */
type = htons(OSPF6_LSTYPE_INTER_ROUTER);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id, lsa)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : approved unset on summary link id %pI4", __func__,
&lsa->header->id);
SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
}
/* Inter area prefix LSA */
type = htons(OSPF6_LSTYPE_INTER_PREFIX);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id, lsa)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : approved unset on asbr-summary link id %pI4",
__func__, &lsa->header->id);
SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
}
}
}
/* Re-advertise inter-area router LSA's */
static void ospf6_asbr_prefix_readvertise(struct ospf6 *ospf6)
{
struct ospf6_route *brouter;
struct listnode *node, *nnode;
struct ospf6_area *oa;
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
for (brouter = ospf6_route_head(oa->ospf6->brouter_table); brouter;
brouter = ospf6_route_next(brouter))
ospf6_abr_originate_summary_to_area(brouter, oa);
}
}
/* Advertise prefixes configured using area <area-id> range command */
static void ospf6_abr_announce_aggregates(struct ospf6 *ospf6)
{
struct ospf6_area *area;
struct ospf6_route *range;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, area)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("ospf_abr_announce_aggregates(): looking at area %pI4",
&area->area_id);
for (range = ospf6_route_head(area->range_table); range;
range = ospf6_route_next(range))
ospf6_abr_range_update(range, ospf6);
}
}
/* Flush the summary LSA's which are not approved.*/
static void ospf6_abr_remove_unapproved_summaries(struct ospf6 *ospf6)
{
struct listnode *node, *nnode;
struct ospf6_area *area;
struct ospf6_lsa *lsa;
uint16_t type;
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : looking at area %pI4", __func__, &area->area_id);
/* Inter area router LSA */
type = htons(OSPF6_LSTYPE_INTER_ROUTER);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id, lsa)) {
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED))
ospf6_lsa_premature_aging(lsa);
}
/* Inter area prefix LSA */
type = htons(OSPF6_LSTYPE_INTER_PREFIX);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id, lsa)) {
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED))
ospf6_lsa_premature_aging(lsa);
}
}
}
/*
* This is the function taking care about ABR stuff, i.e.
* summary-LSA origination and flooding.
*/
void ospf6_abr_task(struct ospf6 *ospf6)
{
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Start", __func__);
if (ospf6->route_table == NULL || ospf6->brouter_table == NULL) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Routing tables are not yet ready", __func__);
return;
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : unapproving summaries", __func__);
ospf6_abr_unapprove_summaries(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : prepare aggregates", __func__);
ospf6_abr_range_reset_cost(ospf6);
if (IS_OSPF6_ABR(ospf6)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : process network RT", __func__);
ospf6_abr_prefix_resummarize(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : process router RT", __func__);
ospf6_asbr_prefix_readvertise(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : announce aggregates", __func__);
ospf6_abr_announce_aggregates(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : announce stub defaults", __func__);
ospf6_abr_defaults_to_stub(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : announce NSSA Type-7 defaults", __func__);
ospf6_abr_nssa_type_7_defaults(ospf6);
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : remove unapproved summaries", __func__);
ospf6_abr_remove_unapproved_summaries(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Stop", __func__);
}
/* This function performs ABR related processing */
static void ospf6_abr_task_timer(struct event *thread)
{
struct ospf6 *ospf6 = EVENT_ARG(thread);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Running ABR task on timer");
(void)ospf6_check_and_set_router_abr(ospf6);
ospf6_abr_nssa_check_status(ospf6);
ospf6_abr_task(ospf6);
/* if nssa-abr, then scan Type-7 LSDB */
ospf6_abr_nssa_task(ospf6);
}
void ospf6_schedule_abr_task(struct ospf6 *ospf6)
{
if (event_is_scheduled(ospf6->t_abr_task)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("ABR task already scheduled");
return;
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Scheduling ABR task");
event_add_timer(master, ospf6_abr_task_timer, ospf6, OSPF6_ABR_TASK_DELAY,
&ospf6->t_abr_task);
}
void ospf6_execute_abr_task(struct ospf6 *ospf6)
{
event_execute(master, ospf6_abr_task_timer, ospf6, 0, NULL);
}
/* Display functions */
static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,

View file

@ -11,6 +11,8 @@
/* for struct ospf6_prefix */
#include "ospf6_proto.h"
#define OSPF6_ABR_TASK_DELAY 5
/* Debug option */
extern unsigned char conf_debug_ospf6_abr;
#define OSPF6_DEBUG_ABR_ON() (conf_debug_ospf6_abr = 1)
@ -44,7 +46,10 @@ extern void ospf6_abr_examin_brouter(uint32_t router_id,
struct ospf6_route *route,
struct ospf6 *ospf6);
extern void ospf6_abr_range_reset_cost(struct ospf6 *ospf6);
extern void ospf6_abr_prefix_resummarize(struct ospf6 *ospf6);
extern void ospf6_abr_task(struct ospf6 *ospf6);
extern void ospf6_schedule_abr_task(struct ospf6 *ospf6);
extern void ospf6_execute_abr_task(struct ospf6 *ospf6);
extern int config_write_ospf6_debug_abr(struct vty *vty);
extern void install_element_ospf6_debug_abr(void);
@ -58,7 +63,6 @@ extern void ospf6_abr_old_path_update(struct ospf6_route *old_route,
extern void ospf6_abr_init(void);
extern void ospf6_abr_range_update(struct ospf6_route *range,
struct ospf6 *ospf6);
extern void ospf6_abr_remove_unapproved_summaries(struct ospf6 *ospf6);
extern int ospf6_ls_origin_same(struct ospf6_path *o_path,
struct ospf6_path *r_path);

View file

@ -173,6 +173,10 @@ static void ospf6_area_stub_update(struct ospf6_area *area)
}
OSPF6_ROUTER_LSA_SCHEDULE(area);
/* Happens implicitly via OSPF6_ROUTER_LSA_SCHEDULE(), but
* let's make it explicit
*/
ospf6_schedule_abr_task(area->ospf6);
}
static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area)
@ -203,7 +207,7 @@ static void ospf6_area_no_summary_set(struct ospf6 *ospf6,
if (!area->no_summary) {
area->no_summary = 1;
ospf6_abr_range_reset_cost(ospf6);
ospf6_abr_prefix_resummarize(ospf6);
ospf6_schedule_abr_task(ospf6);
}
}
}
@ -215,7 +219,7 @@ static void ospf6_area_no_summary_unset(struct ospf6 *ospf6,
if (area->no_summary) {
area->no_summary = 0;
ospf6_abr_range_reset_cost(ospf6);
ospf6_abr_prefix_resummarize(ospf6);
ospf6_schedule_abr_task(ospf6);
}
}
}
@ -602,7 +606,7 @@ DEFUN (area_range,
if (ospf6_check_and_set_router_abr(ospf6)) {
/* Redo summaries if required */
ospf6_abr_prefix_resummarize(ospf6);
ospf6_schedule_abr_task(ospf6);
}
return CMD_SUCCESS;
@ -627,7 +631,7 @@ DEFUN (no_area_range,
int ret;
struct ospf6_area *oa;
struct prefix prefix;
struct ospf6_route *range, *route;
struct ospf6_route *range;
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
@ -649,14 +653,7 @@ DEFUN (no_area_range,
if (ospf6_check_and_set_router_abr(oa->ospf6)) {
/* Blow away the aggregated LSA and route */
SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE);
/* Redo summaries if required */
for (route = ospf6_route_head(oa->ospf6->route_table); route;
route = ospf6_route_next(route))
ospf6_abr_originate_summary(route, oa->ospf6);
/* purge the old aggregated summary LSA */
ospf6_abr_originate_summary(range, oa->ospf6);
ospf6_schedule_abr_task(oa->ospf6);
}
ospf6_route_remove(range, oa->range_table);
@ -1412,10 +1409,8 @@ DEFPY(ospf6_area_nssa, ospf6_area_nssa_cmd,
else
ospf6_area_no_summary_unset(ospf6, area);
if (ospf6_check_and_set_router_abr(ospf6)) {
ospf6_abr_defaults_to_stub(ospf6);
ospf6_abr_nssa_type_7_defaults(ospf6);
}
if (ospf6_check_and_set_router_abr(ospf6))
ospf6_schedule_abr_task(ospf6);
return CMD_SUCCESS;
}

View file

@ -23,6 +23,7 @@
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
#include "ospf6_abr.h"
#include "ospf6_flood.h"
#include "ospf6_nssa.h"

View file

@ -23,7 +23,6 @@
#include "ospf6_route.h"
#include "ospf6_area.h"
#include "ospf6_abr.h"
#include "ospf6_nssa.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
#include "ospf6_intra.h"

View file

@ -1965,11 +1965,15 @@ void ospf6_intra_route_calculation(struct ospf6_area *oa)
(*hook_add)(route);
route->flag = 0;
} else {
/* Redo the summaries as things might have changed */
/* Redo the summaries as things might have changed.
* Note: Not strictly needed since we're called by
* ospf6_spf_calculation_thread() which calls
* ospf6_abr_task() anyway, but make it explicit.
*/
if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
zlog_debug("%s: Originate summary for route %s",
zlog_debug("%s: Schedule summary origination for route %s",
__func__, buf);
ospf6_abr_originate_summary(route, oa->ospf6);
ospf6_schedule_abr_task(oa->ospf6);
route->flag = 0;
}
}
@ -2211,8 +2215,12 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
zlog_debug(
"brouter %s still exists via area %s",
brouter_name, oa->name);
/* But re-originate summaries */
ospf6_abr_originate_summary(brouter, oa->ospf6);
/* But re-originate summaries via ospf6_abr_task().
* Note: Not strictly needed since we're called by
* ospf6_spf_calculation_thread() which calls
* ospf6_abr_task() anyway, but make it explicit.
*/
ospf6_schedule_abr_task(oa->ospf6);
}
if (brouter) {

View file

@ -248,6 +248,7 @@ struct ospf6_lsa {
#define OSPF6_LSA_UNAPPROVED 0x10
#define OSPF6_LSA_SEQWRAPPED 0x20
#define OSPF6_LSA_FLUSH 0x40
#define OSPF6_LSA_LOCAL_XLT 0x80
struct ospf6_lsa_handler {
uint16_t lh_type; /* host byte order */

View file

@ -183,184 +183,6 @@ void ospf6_abr_nssa_check_status(struct ospf6 *ospf6)
}
}
/* Mark the summary LSA's as unapproved, when ABR status changes.*/
static void ospf6_abr_unapprove_summaries(struct ospf6 *ospf6)
{
struct listnode *node, *nnode;
struct ospf6_area *area;
struct ospf6_lsa *lsa;
uint16_t type;
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Start", __func__);
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : considering area %pI4", __func__,
&area->area_id);
/* Inter area router LSA */
type = htons(OSPF6_LSTYPE_INTER_ROUTER);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id,
lsa)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug(
"%s : approved unset on summary link id %pI4",
__func__, &lsa->header->id);
SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
}
/* Inter area prefix LSA */
type = htons(OSPF6_LSTYPE_INTER_PREFIX);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id,
lsa)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug(
"%s : approved unset on asbr-summary link id %pI4",
__func__, &lsa->header->id);
SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
}
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Stop", __func__);
}
/* Re-advertise inter-area router LSA's */
void ospf6_asbr_prefix_readvertise(struct ospf6 *ospf6)
{
struct ospf6_route *brouter;
struct listnode *node, *nnode;
struct ospf6_area *oa;
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Re-examining Inter-Router prefixes");
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
for (brouter = ospf6_route_head(oa->ospf6->brouter_table);
brouter; brouter = ospf6_route_next(brouter))
ospf6_abr_originate_summary_to_area(brouter, oa);
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Finished re-examining Inter-Router prefixes");
}
/* Advertise prefixes configured using area <area-id> range command */
static void ospf6_abr_announce_aggregates(struct ospf6 *ospf6)
{
struct ospf6_area *area;
struct ospf6_route *range;
struct listnode *node;
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s: Start", __func__);
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, area)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug(
"ospf_abr_announce_aggregates(): looking at area %pI4",
&area->area_id);
for (range = ospf6_route_head(area->range_table); range;
range = ospf6_route_next(range))
ospf6_abr_range_update(range, ospf6);
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s: Stop", __func__);
}
/* Flush the summary LSA's which are not approved.*/
void ospf6_abr_remove_unapproved_summaries(struct ospf6 *ospf6)
{
struct listnode *node, *nnode;
struct ospf6_area *area;
struct ospf6_lsa *lsa;
uint16_t type;
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Start", __func__);
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : looking at area %pI4", __func__,
&area->area_id);
/* Inter area router LSA */
type = htons(OSPF6_LSTYPE_INTER_ROUTER);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id,
lsa)) {
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED))
ospf6_lsa_premature_aging(lsa);
}
/* Inter area prefix LSA */
type = htons(OSPF6_LSTYPE_INTER_PREFIX);
for (ALL_LSDB_TYPED_ADVRTR(area->lsdb, type, ospf6->router_id,
lsa)) {
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED))
ospf6_lsa_premature_aging(lsa);
}
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Stop", __func__);
}
/*
* This is the function taking care about ABR stuff, i.e.
* summary-LSA origination and flooding.
*/
static void ospf6_abr_task(struct ospf6 *ospf6)
{
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Start", __func__);
if (ospf6->route_table == NULL || ospf6->brouter_table == NULL) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Routing tables are not yet ready",
__func__);
return;
}
ospf6_abr_unapprove_summaries(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : prepare aggregates", __func__);
ospf6_abr_range_reset_cost(ospf6);
if (IS_OSPF6_ABR(ospf6)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : process network RT", __func__);
ospf6_abr_prefix_resummarize(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : process router RT", __func__);
ospf6_asbr_prefix_readvertise(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : announce aggregates", __func__);
ospf6_abr_announce_aggregates(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : announce stub defaults", __func__);
ospf6_abr_defaults_to_stub(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : announce NSSA Type-7 defaults",
__func__);
ospf6_abr_nssa_type_7_defaults(ospf6);
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : remove unapproved summaries", __func__);
ospf6_abr_remove_unapproved_summaries(ospf6);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("%s : Stop", __func__);
}
/* For NSSA Translations
* Mark the translated LSA's as unapproved. */
static void ospf6_abr_unapprove_translates(struct ospf6 *ospf6)
@ -874,7 +696,7 @@ void ospf6_abr_nssa_type_7_defaults(struct ospf6 *ospf6)
}
}
static void ospf6_abr_nssa_task(struct ospf6 *ospf6)
void ospf6_abr_nssa_task(struct ospf6 *ospf6)
{
if (IS_OSPF6_DEBUG_NSSA)
zlog_debug("Check for NSSA-ABR Tasks():");
@ -923,78 +745,6 @@ static void ospf6_abr_nssa_task(struct ospf6 *ospf6)
zlog_debug("%s: Stop", __func__);
}
int ospf6_redistribute_check(struct ospf6 *ospf6, struct ospf6_route *route,
int type)
{
route_map_result_t ret;
struct prefix *prefix;
struct ospf6_redist *red;
if (!ospf6_zebra_is_redistribute(type, ospf6->vrf_id))
return 0;
prefix = &route->prefix;
red = ospf6_redist_lookup(ospf6, type, 0);
if (!red)
return 0;
/* Change to new redist structure */
if (ROUTEMAP_NAME(red)) {
if (ROUTEMAP(red) == NULL)
ospf6_asbr_routemap_update(NULL);
if (ROUTEMAP(red) == NULL) {
zlog_warn(
"route-map \"%s\" not found, suppress redistributing",
ROUTEMAP_NAME(red));
return 0;
}
}
/* Change to new redist structure */
if (ROUTEMAP(red)) {
ret = route_map_apply(ROUTEMAP(red), prefix, route);
if (ret == RMAP_DENYMATCH) {
if (IS_OSPF6_DEBUG_ASBR)
zlog_debug("Denied by route-map \"%s\"",
ROUTEMAP_NAME(red));
return 0;
}
}
return 1;
}
/* This function performs ABR related processing */
static void ospf6_abr_task_timer(struct event *thread)
{
struct ospf6 *ospf6 = EVENT_ARG(thread);
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Running ABR task on timer");
(void)ospf6_check_and_set_router_abr(ospf6);
ospf6_abr_nssa_check_status(ospf6);
ospf6_abr_task(ospf6);
/* if nssa-abr, then scan Type-7 LSDB */
ospf6_abr_nssa_task(ospf6);
}
void ospf6_schedule_abr_task(struct ospf6 *ospf6)
{
if (event_is_scheduled(ospf6->t_abr_task)) {
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("ABR task already scheduled");
return;
}
if (IS_OSPF6_DEBUG_ABR)
zlog_debug("Scheduling ABR task");
event_add_timer(master, ospf6_abr_task_timer, ospf6,
OSPF6_ABR_TASK_DELAY, &ospf6->t_abr_task);
}
/* Flush the NSSA LSAs from the area */
static void ospf6_nssa_flush_area(struct ospf6_area *area)
{
@ -1424,7 +1174,7 @@ DEFPY (no_area_nssa_range,
SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE);
/* Redo summaries if required */
event_execute(master, ospf6_abr_task_timer, ospf6, 0, NULL);
ospf6_execute_abr_task(ospf6);
}
ospf6_route_remove(range, oa->nssa_range_table);

View file

@ -9,12 +9,6 @@
#ifndef OSPF6_NSSA_H
#define OSPF6_NSSA_H
#define OSPF6_OPTION_NP 0x08
#define OSPF6_LS_INFINITY 0xffffff
#define OSPF6_OPT_N (1 << 3) /* Handling Type-7 LSA Capability */
#define OSPF6_DEBUG_NSSA 0x09
/* Debug option */
extern unsigned char config_debug_ospf6_nssa;
@ -22,18 +16,6 @@ extern unsigned char config_debug_ospf6_nssa;
#define OSPF6_DEBUG_NSSA_OFF() (config_debug_ospf6_nssa = 0)
#define IS_OSPF6_DEBUG_NSSA config_debug_ospf6_nssa
#define CHECK_LSA_TYPE_1_TO_5_OR_7(type) \
((type == OSPF6_ROUTER_LSA_MIN_SIZE) \
|| (type == OSPF6_NETWORK_LSA_MIN_SIZE) \
|| (type == OSPF6_LINK_LSA_MIN_SIZE) \
|| (type == OSPF6_INTRA_PREFIX_LSA_MIN_SIZE) \
|| (type == OSPF6_AS_NSSA_LSA))
#define OSPF6_LSA_APPROVED 0x08
#define OSPF6_LSA_LOCAL_XLT 0x40
#define OSPF6_ABR_TASK_DELAY 5
int ospf6_area_nssa_no_summary_set(struct ospf6 *ospf6, struct in_addr area_id);
int ospf6_area_nssa_unset(struct ospf6 *ospf6, struct ospf6_area *area);
int ospf6_area_nssa_set(struct ospf6 *ospf6, struct ospf6_area *area);
@ -45,15 +27,12 @@ extern struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *oa,
extern void ospf6_asbr_nssa_redist_task(struct ospf6 *ospf6);
extern void ospf6_schedule_abr_task(struct ospf6 *ospf6);
extern void ospf6_area_nssa_update(struct ospf6_area *area);
void ospf6_asbr_prefix_readvertise(struct ospf6 *ospf6);
extern void ospf6_nssa_lsa_originate(struct ospf6_route *route,
struct ospf6_area *area, bool p_bit);
extern void install_element_ospf6_debug_nssa(void);
extern void ospf6_abr_nssa_type_7_defaults(struct ospf6 *osof6);
int ospf6_redistribute_check(struct ospf6 *ospf6, struct ospf6_route *route,
int type);
extern void ospf6_abr_nssa_task(struct ospf6 *ospf6);
extern void ospf6_abr_check_translate_nssa(struct ospf6_area *area,
struct ospf6_lsa *lsa);
extern void ospf6_abr_nssa_check_status(struct ospf6 *ospf6);

View file

@ -643,10 +643,8 @@ static void ospf6_spf_calculation_thread(struct event *t)
/* External LSA calculation */
ospf6_ase_calculate_timer_add(ospf6);
if (ospf6_check_and_set_router_abr(ospf6)) {
ospf6_abr_defaults_to_stub(ospf6);
ospf6_abr_nssa_type_7_defaults(ospf6);
}
if (ospf6_check_and_set_router_abr(ospf6))
ospf6_abr_task(ospf6);
monotime(&end);
timersub(&end, &start, &runtime);

View file

@ -40,7 +40,6 @@
#include "ospf6_tlv.h"
#include "ospf6_gr.h"
#include "lib/json.h"
#include "ospf6_nssa.h"
#include "ospf6_auth_trailer.h"
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_TOP, "OSPF6 top");
@ -270,7 +269,7 @@ static void ospf6_top_route_hook_add(struct ospf6_route *route)
return;
}
ospf6_abr_originate_summary(route, ospf6);
ospf6_schedule_abr_task(ospf6);
ospf6_zebra_route_update_add(route, ospf6);
}
@ -294,7 +293,7 @@ static void ospf6_top_route_hook_remove(struct ospf6_route *route)
}
route->flag |= OSPF6_ROUTE_REMOVE;
ospf6_abr_originate_summary(route, ospf6);
ospf6_schedule_abr_task(ospf6);
ospf6_zebra_route_update_remove(route, ospf6);
}
@ -318,7 +317,7 @@ static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
ospf6);
ospf6_asbr_lsentry_add(route, ospf6);
ospf6_abr_originate_summary(route, ospf6);
ospf6_schedule_abr_task(ospf6);
}
static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
@ -342,7 +341,7 @@ static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
ospf6);
ospf6_asbr_lsentry_remove(route, ospf6);
ospf6_abr_originate_summary(route, ospf6);
ospf6_schedule_abr_task(ospf6);
}
static struct ospf6 *ospf6_create(const char *name)

View file

@ -22,8 +22,8 @@
#include "ospf6_route.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_abr.h"
#include "ospf6_asbr.h"
#include "ospf6_nssa.h"
#include "ospf6_zebra.h"
#include "ospf6d.h"
#include "ospf6_area.h"
@ -163,7 +163,7 @@ static void ospf6_zebra_import_check_update(struct vrf *vrf,
return;
ospf6->nssa_default_import_check.status = !!nhr->nexthop_num;
ospf6_abr_nssa_type_7_defaults(ospf6);
ospf6_schedule_abr_task(ospf6);
}
static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)