summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_abr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_abr.c')
-rw-r--r--ospf6d/ospf6_abr.c127
1 files changed, 80 insertions, 47 deletions
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 57165201bd..a9b4c7756c 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -53,6 +53,16 @@
unsigned char conf_debug_ospf6_abr;
+int ospf6_ls_origin_same(struct ospf6_path *o_path, struct ospf6_path *r_path)
+{
+ if (((o_path->origin.type == r_path->origin.type)
+ && (o_path->origin.id == r_path->origin.id)
+ && (o_path->origin.adv_router == r_path->origin.adv_router)))
+ return 1;
+ else
+ return 0;
+}
+
bool ospf6_check_and_set_router_abr(struct ospf6 *o)
{
struct listnode *node;
@@ -96,8 +106,7 @@ static int ospf6_abr_nexthops_belong_to_area(struct ospf6_route *route,
return 0;
}
-static void ospf6_abr_delete_route(struct ospf6_route *range,
- struct ospf6_route *summary,
+static void ospf6_abr_delete_route(struct ospf6_route *summary,
struct ospf6_route_table *summary_table,
struct ospf6_lsa *old)
{
@@ -375,8 +384,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
zlog_debug(
"The range is not active. withdraw");
- ospf6_abr_delete_route(route, summary,
- summary_table, old);
+ ospf6_abr_delete_route(summary, summary_table,
+ old);
}
} else if (old) {
ospf6_route_remove(summary, summary_table);
@@ -390,7 +399,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(route, summary, summary_table, old);
+ ospf6_abr_delete_route(summary, summary_table, old);
return 0;
}
@@ -399,7 +408,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(route, summary, summary_table, old);
+ ospf6_abr_delete_route(summary, summary_table, old);
return 0;
}
@@ -434,8 +443,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(route, summary, summary_table,
- old);
+ ospf6_abr_delete_route(summary, summary_table, old);
return 0;
}
@@ -465,8 +473,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
zlog_debug(
"Suppressed by range %pFX of area %s",
&range->prefix, route_area->name);
- ospf6_abr_delete_route(route, summary, summary_table,
- old);
+ ospf6_abr_delete_route(summary, summary_table, old);
return 0;
}
}
@@ -478,8 +485,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(route, summary, summary_table,
- old);
+ ospf6_abr_delete_route(summary, summary_table, old);
return 0;
}
@@ -487,8 +493,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(route, summary, summary_table,
- old);
+ ospf6_abr_delete_route(summary, summary_table, old);
return 0;
}
}
@@ -598,10 +603,14 @@ void ospf6_abr_range_reset_cost(struct ospf6 *ospf6)
struct ospf6_area *oa;
struct ospf6_route *range;
- for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
+ for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
for (range = ospf6_route_head(oa->range_table); range;
range = ospf6_route_next(range))
OSPF6_ABR_RANGE_CLEAR_COST(range);
+ for (range = ospf6_route_head(oa->nssa_range_table); range;
+ range = ospf6_route_next(range))
+ OSPF6_ABR_RANGE_CLEAR_COST(range);
+ }
}
static inline uint32_t ospf6_abr_range_compute_cost(struct ospf6_route *range,
@@ -612,10 +621,19 @@ static inline uint32_t ospf6_abr_range_compute_cost(struct ospf6_route *range,
for (ro = ospf6_route_match_head(&range->prefix, o->route_table); ro;
ro = ospf6_route_match_next(&range->prefix, ro)) {
- if (ro->path.area_id == range->path.area_id
- && (ro->path.type == OSPF6_PATH_TYPE_INTRA)
- && !CHECK_FLAG(ro->flag, OSPF6_ROUTE_REMOVE))
- cost = MAX(cost, ro->path.cost);
+ if (CHECK_FLAG(ro->flag, OSPF6_ROUTE_REMOVE))
+ continue;
+ if (ro->path.area_id != range->path.area_id)
+ continue;
+ if (CHECK_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE)
+ && ro->path.type != OSPF6_PATH_TYPE_EXTERNAL1
+ && ro->path.type != OSPF6_PATH_TYPE_EXTERNAL2)
+ continue;
+ if (!CHECK_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE)
+ && ro->path.type != OSPF6_PATH_TYPE_INTRA)
+ continue;
+
+ cost = MAX(cost, ro->path.cost);
}
return cost;
@@ -664,6 +682,8 @@ void ospf6_abr_range_update(struct ospf6_route *range, struct ospf6 *ospf6)
int summary_orig = 0;
assert(range->type == OSPF6_DEST_TYPE_RANGE);
+ oa = ospf6_area_lookup(range->path.area_id, ospf6);
+ assert(oa);
/* update range's cost and active flag */
cost = ospf6_abr_range_compute_cost(range, ospf6);
@@ -686,34 +706,49 @@ void ospf6_abr_range_update(struct ospf6_route *range, struct ospf6 *ospf6)
* if there
* were active ranges.
*/
+ if (!ospf6_abr_range_summary_needs_update(range, cost))
+ return;
- if (ospf6_abr_range_summary_needs_update(range, cost)) {
- if (IS_OSPF6_DEBUG_ABR)
- zlog_debug("%s: range %pFX update", __func__,
- &range->prefix);
- for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
+ if (IS_OSPF6_DEBUG_ABR)
+ zlog_debug("%s: range %pFX update", __func__, &range->prefix);
+
+ if (CHECK_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE)) {
+ if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)
+ && !CHECK_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE)) {
+ ospf6_nssa_lsa_originate(range, oa, true);
+ summary_orig = 1;
+ } else {
+ struct ospf6_lsa *lsa;
+
+ lsa = ospf6_lsdb_lookup(range->path.origin.type,
+ range->path.origin.id,
+ ospf6->router_id, oa->lsdb);
+ if (lsa)
+ ospf6_lsa_premature_aging(lsa);
+ }
+ } else {
+ for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
summary_orig +=
ospf6_abr_originate_summary_to_area(range, oa);
+ }
+ }
- if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)
- && summary_orig) {
- if (!CHECK_FLAG(range->flag,
- OSPF6_ROUTE_BLACKHOLE_ADDED)) {
- if (IS_OSPF6_DEBUG_ABR)
- zlog_debug("Add discard route");
+ if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)
+ && summary_orig) {
+ if (!CHECK_FLAG(range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
+ if (IS_OSPF6_DEBUG_ABR)
+ zlog_debug("Add discard route");
- ospf6_zebra_add_discard(range, ospf6);
- }
- } else {
- /* Summary removed or no summary generated as no
- * specifics exist */
- if (CHECK_FLAG(range->flag,
- OSPF6_ROUTE_BLACKHOLE_ADDED)) {
- if (IS_OSPF6_DEBUG_ABR)
- zlog_debug("Delete discard route");
+ ospf6_zebra_add_discard(range, ospf6);
+ }
+ } else {
+ /* Summary removed or no summary generated as no
+ * specifics exist */
+ if (CHECK_FLAG(range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
+ if (IS_OSPF6_DEBUG_ABR)
+ zlog_debug("Delete discard route");
- ospf6_zebra_delete_discard(range, ospf6);
- }
+ ospf6_zebra_delete_discard(range, ospf6);
}
}
}
@@ -815,9 +850,8 @@ void ospf6_abr_old_path_update(struct ospf6_route *old_route,
struct ospf6_nexthop *nh, *rnh;
for (ALL_LIST_ELEMENTS(old_route->paths, anode, anext, o_path)) {
- if (o_path->area_id != route->path.area_id ||
- (memcmp(&(o_path)->origin, &(route)->path.origin,
- sizeof(struct ospf6_ls_origin)) != 0))
+ if (o_path->area_id != route->path.area_id
+ || !ospf6_ls_origin_same(o_path, &route->path))
continue;
if ((o_path->cost == route->path.cost) &&
@@ -1232,9 +1266,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
for (ALL_LIST_ELEMENTS_RO(old_route->paths, anode,
o_path)) {
- if (o_path->area_id == route->path.area_id &&
- (memcmp(&(o_path)->origin, &(route)->path.origin,
- sizeof(struct ospf6_ls_origin)) == 0))
+ if (o_path->area_id == route->path.area_id
+ && ospf6_ls_origin_same(o_path, &route->path))
break;
}