summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospfd/ospf_abr.c324
-rw-r--r--ospfd/ospf_asbr.h25
-rw-r--r--ospfd/ospf_dump.c5
-rw-r--r--ospfd/ospf_flood.c10
-rw-r--r--ospfd/ospf_lsa.c373
-rw-r--r--ospfd/ospf_lsa.h12
-rw-r--r--ospfd/ospf_te.c18
-rw-r--r--ospfd/ospfd.c2
-rw-r--r--ospfd/ospfd.h13
9 files changed, 568 insertions, 214 deletions
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 8991bd71..92282514 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -50,7 +50,6 @@
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"
-
struct ospf_area_range *
ospf_area_range_new (struct prefix_ipv4 *p)
@@ -123,8 +122,9 @@ ospf_area_range_lookup (struct ospf_area *area, struct prefix_ipv4 *p)
}
struct ospf_area_range *
-ospf_area_range_lookup_next (struct ospf_area *area, struct in_addr *range_net,
- int first)
+ospf_area_range_lookup_next (struct ospf_area *area,
+ struct in_addr *range_net,
+ int first)
{
struct route_node *rn;
struct prefix_ipv4 p;
@@ -375,7 +375,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area)
if (IS_ROUTER_LSA_NT (rlsa))
{
if (IS_DEBUG_OSPF_NSSA)
- zlog_info ("ospf_abr_nssa_am_elected: ",
+ zlog_info ("ospf_abr_nssa_am_elected: "
"router %s asserts Nt",
inet_ntoa (lsa->data->id) );
return 0;
@@ -426,7 +426,7 @@ ospf_abr_nssa_check_status (struct ospf *ospf)
if (IS_DEBUG_OSPF (nssa, NSSA))
zlog_info ("ospf_abr_nssa_check_status: "
"not ABR");
- area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED;
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
continue;
}
@@ -438,7 +438,7 @@ ospf_abr_nssa_check_status (struct ospf *ospf)
if (IS_DEBUG_OSPF (nssa, NSSA))
zlog_info ("ospf_abr_nssa_check_status: "
"never translate");
- area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED;
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
continue;
case OSPF_NSSA_ROLE_ALWAYS:
@@ -449,21 +449,21 @@ ospf_abr_nssa_check_status (struct ospf *ospf)
if (IS_DEBUG_OSPF (nssa, NSSA))
zlog_info ("ospf_abr_nssa_check_status: "
"translate always");
- area->NSSATranslatorState = OSPF_NSSA_STATE_ENABLED;
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
continue;
case OSPF_NSSA_ROLE_CANDIDATE:
/* We are a candidate for Translation */
if (ospf_abr_nssa_am_elected (area) > 0 )
{
- area->NSSATranslatorState = OSPF_NSSA_STATE_ENABLED;
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
if (IS_DEBUG_OSPF (nssa, NSSA))
zlog_info ("ospf_abr_nssa_check_status: "
"elected translator");
}
else
{
- area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED;
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
if (IS_DEBUG_OSPF (nssa, NSSA))
zlog_info ("ospf_abr_nssa_check_status: "
"not elected");
@@ -619,52 +619,88 @@ int
ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
{
/* Incoming Type-7 or later aggregated Type-7
+ *
+ * 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
+ */
- 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 */
-
- struct ospf_lsa *dup;
+ struct ospf_lsa *old = NULL,
+ *new = NULL;
+ struct as_external_lsa *ext7;
+ struct prefix_ipv4 p;
if (! CHECK_FLAG (lsa->data->options, OSPF_OPTION_NP))
{
if (IS_DEBUG_OSPF_NSSA)
- zlog_info ("ospf_abr_nssa(): P-bit off, NO Translation");
- return 0;
+ zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation",
+ inet_ntoa (lsa->data->id));
+ return 1;
}
-
+
if (IS_DEBUG_OSPF_NSSA)
- zlog_info ("ospf_abr_nssa(): TRANSLATING 7 to 5");
+ zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5",
+ inet_ntoa (lsa->data->id));
- /* No more P-bit. */
- /* UNSET_FLAG (lsa->data->options, OSPF_OPTION_NP); */
+ ext7 = (struct as_external_lsa *)(lsa->data);
+ p.prefix = lsa->data->id;
+ p.prefixlen = ip_masklen (ext7->mask);
+
+ if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_abr_translate_nssa(): LSA Id %s, "
+ "Forward address is 0, NO Translation",
+ inet_ntoa (lsa->data->id));
+ return 1;
+ }
+
+ /* try find existing AS-External LSA for this prefix */
+
+ old = ospf_external_info_find_lsa (area->ospf, &p);
+
+ if (old)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_abr_translate_nssa(): "
+ "found old translated LSA Id %s, refreshing",
+ inet_ntoa (old->data->id));
+
+ /* refresh */
+ new = ospf_translated_nssa_refresh (area->ospf, lsa, old);
+ if (!new)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_abr_translate_nssa(): "
+ "could not refresh translated LSA Id %s",
+ inet_ntoa (old->data->id));
+ }
+ }
+ else
+ {
+ /* no existing external route for this LSA Id
+ * originate translated LSA
+ */
+
+ if ((new = ospf_translated_nssa_originate (area->ospf, lsa))
+ == NULL)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_abr_translate_nssa(): Could not translate "
+ "Type-7 for %s to Type-5",
+ inet_ntoa (lsa->data->id));
+ return 1;
+ }
+ }
/* Area where Aggregate testing will be inserted, just like summary
advertisements */
/* ospf_abr_check_nssa_range (p_arg, lsa-> cost, lsa -> area); */
- /* Follow thru here means no aggregation */
- dup = ospf_lsa_dup (lsa); /* keep LSDB intact, lock = 1 */
-
- SET_FLAG (dup->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
- SET_FLAG (dup->flags, OSPF_LSA_APPROVED); /* So, do not remove it */
-
- dup->data->type = OSPF_AS_EXTERNAL_LSA; /* make Type-5 */
-
- ospf_lsa_checksum (dup->data);
-
- ospf_lsa_install (area->ospf, NULL, dup); /* Install this Type-5 into LSDB, Lock = 2. */
-
- ospf_flood_through_as (area->ospf, NULL, dup); /* flood non-NSSA/STUB areas */
-
- /* This translated Type-5 will go to all non-NSSA areas connected to
- this ABR; The Type-5 could come from any of the NSSA's connected
- to this ABR. */
-
return 0;
}
@@ -686,51 +722,52 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_abr_announce_network_to_area(): Start");
- old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, p,
- area->ospf->router_id);
+ old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA,
+ (struct prefix_ipv4 *) p,
+ area->ospf->router_id);
if (old)
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network_to_area(): old summary found");
- sl = (struct summary_lsa *) old->data;
+ zlog_info ("ospf_abr_announce_network_to_area(): old summary found");
- if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network_to_area(): "
- "old metric: %d, new metric: %d",
- GET_METRIC (sl->metric), cost);
- }
+ sl = (struct summary_lsa *) old->data;
- if (old && (GET_METRIC (sl->metric) == cost))
- {
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network_to_area(): "
- "old summary approved");
- SET_FLAG (old->flags, OSPF_LSA_APPROVED);
+ zlog_info ("ospf_abr_announce_network_to_area(): "
+ "old metric: %d, new metric: %d",
+ GET_METRIC (sl->metric), cost);
+
+ if (GET_METRIC (sl->metric) == cost)
+ {
+ /* unchanged. simply reapprove it */
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_info ("ospf_abr_announce_network_to_area(): "
+ "old summary approved");
+ SET_FLAG (old->flags, OSPF_LSA_APPROVED);
+ }
+ else
+ {
+ /* LSA is changed, refresh it */
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_info ("ospf_abr_announce_network_to_area(): "
+ "refreshing summary");
+ set_metric (old, cost);
+ lsa = ospf_summary_lsa_refresh (area->ospf, old);
+ /* This will flood through area. */
+ }
}
else
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network_to_area(): "
- "creating new summary");
- if (old)
- {
-
- set_metric (old, cost);
- lsa = ospf_summary_lsa_refresh (area->ospf, old);
- /* This will flood through area. */
- }
- else
- {
- lsa = ospf_summary_lsa_originate (p, cost, area);
- /* This will flood through area. */
- }
+ zlog_info ("ospf_abr_announce_network_to_area(): "
+ "creating new summary");
+ lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area);
+ /* This will flood through area. */
-
SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network_to_area(): "
- "flooding new version of summary");
-
+ zlog_info ("ospf_abr_announce_network_to_area(): "
+ "flooding new version of summary");
}
if (IS_DEBUG_OSPF_EVENT)
@@ -757,7 +794,7 @@ ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
}
int
-ospf_abr_should_accept (struct prefix *p, struct ospf_area *area)
+ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area)
{
if (IMPORT_NAME (area))
{
@@ -774,7 +811,7 @@ ospf_abr_should_accept (struct prefix *p, struct ospf_area *area)
int
ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
- struct prefix *p)
+ struct prefix_ipv4 *p)
{
if (PREFIX_NAME_IN (area))
{
@@ -790,7 +827,7 @@ ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
int
ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
- struct prefix *p)
+ struct prefix_ipv4 *p)
{
if (PREFIX_NAME_OUT (area))
{
@@ -806,16 +843,14 @@ ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
void
ospf_abr_announce_network (struct ospf *ospf,
- struct route_node *n, struct ospf_route *or)
+ struct prefix_ipv4 *p, struct ospf_route *or)
{
struct ospf_area_range *range;
struct ospf_area *area, *or_area;
- struct prefix_ipv4 *p;
listnode node;
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_abr_announce_network(): Start");
- p = (struct prefix_ipv4 *) &n->p;
or_area = ospf_area_lookup_by_area_id (ospf, or->u.std.area_id);
assert (or_area);
@@ -834,7 +869,7 @@ ospf_abr_announce_network (struct ospf *ospf,
if (ospf_abr_nexthops_belong_to_area (or, area))
continue;
- if (!ospf_abr_should_accept (&n->p, area))
+ if (!ospf_abr_should_accept (p, area))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_abr_announce_network(): "
@@ -843,7 +878,7 @@ ospf_abr_announce_network (struct ospf *ospf,
continue;
}
- if (!ospf_abr_plist_in_check (area, or, &n->p))
+ if (!ospf_abr_plist_in_check (area, or, p))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_abr_announce_network(): "
@@ -873,23 +908,23 @@ ospf_abr_announce_network (struct ospf *ospf,
}
if (or->path_type == OSPF_PATH_INTRA_AREA)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network(): "
- "this is intra-area route to %s/%d",
- inet_ntoa (p->prefix), p->prefixlen);
- if ((range = ospf_area_range_match (or_area, p)) &&
- !ospf_area_is_transit (area))
- ospf_abr_update_aggregate (range, or);
- else
- ospf_abr_announce_network_to_area (p, or->cost, area);
- }
+ {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_info ("ospf_abr_announce_network(): "
+ "this is intra-area route to %s/%d",
+ inet_ntoa (p->prefix), p->prefixlen);
+ if ((range = ospf_area_range_match (or_area, p))
+ && !ospf_area_is_transit (area))
+ ospf_abr_update_aggregate (range, or);
+ else
+ ospf_abr_announce_network_to_area (p, or->cost, area);
+ }
}
}
int
ospf_abr_should_announce (struct ospf *ospf,
- struct prefix *p, struct ospf_route *or)
+ struct prefix_ipv4 *p, struct ospf_route *or)
{
struct ospf_area *area;
@@ -933,17 +968,17 @@ ospf_abr_process_nssa_translates (struct ospf *ospf)
area = getdata (node);
if (! area->NSSATranslatorState)
- continue; /* skip if not translator */
+ continue; /* skip if not translator */
if (area->external_routing != OSPF_AREA_NSSA)
- continue; /* skip if not Nssa Area */
+ continue; /* skip if not Nssa Area */
if (IS_DEBUG_OSPF_NSSA)
- zlog_info ("ospf_abr_process_nssa_translates(): "
- "looking at area %s", inet_ntoa (area->area_id));
+ zlog_info ("ospf_abr_process_nssa_translates(): "
+ "looking at area %s", inet_ntoa (area->area_id));
LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
- ospf_abr_translate_nssa (area, lsa);
+ ospf_abr_translate_nssa (area, lsa);
}
if (IS_DEBUG_OSPF_NSSA)
@@ -1004,7 +1039,7 @@ ospf_abr_process_network_rt (struct ospf *ospf,
}
if (or->path_type == OSPF_PATH_INTRA_AREA &&
- !ospf_abr_should_announce (ospf, &rn->p, or))
+ !ospf_abr_should_announce (ospf, (struct prefix_ipv4 *) &rn->p, or))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_info("ospf_abr_process_network_rt(): denied by export-list");
@@ -1012,7 +1047,7 @@ ospf_abr_process_network_rt (struct ospf *ospf,
}
if (or->path_type == OSPF_PATH_INTRA_AREA &&
- !ospf_abr_plist_out_check (area, or, &rn->p))
+ !ospf_abr_plist_out_check (area, or, (struct prefix_ipv4 *) &rn->p))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_info("ospf_abr_process_network_rt(): denied by prefix-list");
@@ -1043,7 +1078,7 @@ ospf_abr_process_network_rt (struct ospf *ospf,
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_abr_process_network_rt(): announcing");
- ospf_abr_announce_network (ospf, rn, or);
+ ospf_abr_announce_network (ospf, &rn->p, or);
}
if (IS_DEBUG_OSPF_EVENT)
@@ -1136,7 +1171,7 @@ ospf_abr_announce_rtr (struct ospf *ospf,
if (area->external_routing != OSPF_AREA_DEFAULT)
{
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_network(): "
+ zlog_info ("ospf_abr_announce_rtr(): "
"area %s doesn't support external routing",
inet_ntoa(area->area_id));
continue;
@@ -1283,7 +1318,13 @@ ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
- UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
+ {
+ UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_abr_unapprove_translates(): "
+ "approved unset on link id %s",
+ inet_ntoa (lsa->data->id));
+ }
if (IS_DEBUG_OSPF_NSSA)
zlog_info ("ospf_abr_unapprove_translates(): Stop");
@@ -1304,13 +1345,29 @@ ospf_abr_unapprove_summaries (struct ospf *ospf)
for (node = listhead (ospf->areas); node; nextnode (node))
{
area = getdata (node);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_info ("ospf_abr_unapprove_summaries(): "
+ "considering area %s",
+ inet_ntoa (area->area_id));
LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
- if (ospf_lsa_is_self_originated (ospf, lsa))
- UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
+ if (ospf_lsa_is_self_originated (ospf, lsa))
+ {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_info ("ospf_abr_unapprove_summaries(): "
+ "approved unset on summary link id %s",
+ inet_ntoa (lsa->data->id));
+ UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
+ }
LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
- if (ospf_lsa_is_self_originated (ospf, lsa))
- UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
+ if (ospf_lsa_is_self_originated (ospf, lsa))
+ {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_info ("ospf_abr_unapprove_summaries(): "
+ "approved unset on asbr-summary link id %s",
+ inet_ntoa (lsa->data->id));
+ UNSET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
+ }
}
if (IS_DEBUG_OSPF_EVENT)
@@ -1349,7 +1406,7 @@ ospf_abr_announce_aggregates (struct ospf *ospf)
struct ospf_area *area, *ar;
struct ospf_area_range *range;
struct route_node *rn;
- struct prefix_ipv4 p;
+ struct prefix p;
listnode node, n;
if (IS_DEBUG_OSPF_EVENT)
@@ -1375,18 +1432,18 @@ ospf_abr_announce_aggregates (struct ospf *ospf)
}
p.family = AF_INET;
- p.prefix = range->addr;
+ p.u.prefix4 = range->addr;
p.prefixlen = range->masklen;
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_abr_announce_aggregates():"
" this is range: %s/%d",
- inet_ntoa (p.prefix), p.prefixlen);
+ inet_ntoa (p.u.prefix4), p.prefixlen);
if (CHECK_FLAG (range->flags, OSPF_AREA_RANGE_SUBSTITUTE))
{
p.family = AF_INET;
- p.prefix = range->subst_addr;
+ p.u.prefix4 = range->subst_addr;
p.prefixlen = range->subst_masklen;
}
@@ -1504,7 +1561,6 @@ ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
{
listnode node;
struct ospf_area *area;
- struct prefix_ipv4 p;
if (! IS_OSPF_ABR (ospf))
return;
@@ -1512,10 +1568,6 @@ ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
if (IS_DEBUG_OSPF_NSSA)
zlog_info ("ospf_abr_announce_stub_defaults(): Start");
- p.family = AF_INET;
- p.prefix.s_addr = OSPF_DEFAULT_DESTINATION;
- p.prefixlen = 0;
-
for (node = listhead (ospf->areas); node; nextnode (node))
{
area = getdata (node);
@@ -1536,7 +1588,7 @@ ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
zlog_info ("ospf_abr_announce_nssa_defaults(): "
"announcing 0.0.0.0/0 to this nssa");
/* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
- ospf_abr_announce_network_to_area (&p, area->default_cost, area);
+ /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/
}
}
}
@@ -1563,22 +1615,26 @@ ospf_abr_announce_stub_defaults (struct ospf *ospf)
{
area = getdata (node);
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s",
- inet_ntoa (area->area_id));
+ zlog_info ("ospf_abr_announce_stub_defaults(): looking at area %s",
+ inet_ntoa (area->area_id));
+ if ( (area->external_routing != OSPF_AREA_STUB)
#ifdef HAVE_NSSA
- if (area->external_routing != OSPF_AREA_STUB)
-#else /* ! HAVE_NSSA */
- if (area->external_routing == OSPF_AREA_DEFAULT)
+ && (area->external_routing != OSPF_AREA_NSSA)
#endif /* HAVE_NSSA */
- continue;
+ )
+ continue;
if (OSPF_IS_AREA_BACKBONE (area))
- continue; /* Sanity Check */
+ continue; /* Sanity Check */
+
+ if (area->no_summary)
+ continue;
if (IS_DEBUG_OSPF_EVENT)
- zlog_info ("ospf_abr_announce_stub_defaults(): "
- "announcing 0.0.0.0/0 to this area");
+ zlog_info ("ospf_abr_announce_stub_defaults(): "
+ "announcing 0.0.0.0/0 to area %s",
+ inet_ntoa (area->area_id));
ospf_abr_announce_network_to_area (&p, area->default_cost, area);
}
@@ -1751,10 +1807,12 @@ ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */
zlog_info("ospf_abr_nssa_task(): send NSSA aggregates");
ospf_abr_send_nssa_aggregates (ospf); /*TURNED OFF FOR NOW */
- /* Send any NSSA defaults as Type-5 */
- if (IS_DEBUG_OSPF_NSSA)
- zlog_info ("ospf_abr_nssa_task(): announce nssa defaults");
- ospf_abr_announce_nssa_defaults (ospf);
+ /* Send any NSSA defaults as Type-5
+ *if (IS_DEBUG_OSPF_NSSA)
+ * zlog_info ("ospf_abr_nssa_task(): announce nssa defaults");
+ *ospf_abr_announce_nssa_defaults (ospf);
+ * havnt a clue what above is supposed to do.
+ */
/* Flush any unapproved previous translates from Global Data Base */
if (IS_DEBUG_OSPF_NSSA)
@@ -1832,10 +1890,12 @@ ospf_abr_task_timer (struct thread *thread)
zlog_info ("Running ABR task on timer");
ospf_check_abr_status (ospf);
+#ifdef HAVE_NSSA
+ ospf_abr_nssa_check_status (ospf);
+#endif /* HAVE_NSSA */
ospf_abr_task (ospf);
#ifdef HAVE_NSSA
- ospf_abr_nssa_check_status (ospf);
ospf_abr_nssa_task (ospf); /* if nssa-abr, then scan Type-7 LSDB */
#endif /* HAVE_NSSA */
diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h
index f368246d..34947747 100644
--- a/ospfd/ospf_asbr.h
+++ b/ospfd/ospf_asbr.h
@@ -54,22 +54,27 @@ struct external_info
#define OSPF_ASBR_CHECK_DELAY 30
-void ospf_external_route_remove (struct prefix_ipv4 *p);
+void ospf_external_route_remove (struct ospf *, struct prefix_ipv4 *);
struct external_info *ospf_external_info_new (u_char);
-void ospf_reset_route_map_set_values (struct route_map_set_values *values);
-int ospf_route_map_set_compare (struct route_map_set_values *values1,
- struct route_map_set_values *values2);
-struct external_info *ospf_external_info_add (u_char, struct prefix_ipv4,
- unsigned int, struct in_addr);
+void ospf_reset_route_map_set_values (struct route_map_set_values *);
+int ospf_route_map_set_compare (struct route_map_set_values *,
+ struct route_map_set_values *);
+struct external_info *ospf_external_info_add (u_char,
+ struct prefix_ipv4,
+ unsigned int,
+ struct in_addr);
void ospf_external_info_delete (u_char, struct prefix_ipv4);
-struct external_info *ospf_external_info_lookup (u_char, struct prefix_ipv4 *);
-
-void ospf_asbr_status_update (u_char);
+struct external_info *ospf_external_info_lookup (u_char,
+ struct prefix_ipv4 *);
+struct ospf_route *ospf_external_route_lookup (struct ospf *,
+ struct prefix_ipv4 *);
+void ospf_asbr_status_update (struct ospf *, u_char);
void ospf_redistribute_withdraw (u_char);
void ospf_asbr_check ();
void ospf_schedule_asbr_check ();
void ospf_asbr_route_install_lsa (struct ospf_lsa *);
-struct ospf_lsa *ospf_external_info_find_lsa (struct prefix_ipv4 *p);
+struct ospf_lsa *ospf_external_info_find_lsa (struct ospf *,
+ struct prefix_ipv4 *p);
#endif /* _ZEBRA_OSPF_ASBR_H */
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
index f563fb89..fe75a960 100644
--- a/ospfd/ospf_dump.c
+++ b/ospfd/ospf_dump.c
@@ -425,8 +425,7 @@ ospf_as_external_lsa_dump (struct stream *s, u_int16_t length)
int i;
al = (struct as_external_lsa *) STREAM_PNT (s);
-
- zlog_info (" AS-external-LSA");
+ zlog_info (" %s", ospf_lsa_type_msg[al->header.type].str);
zlog_info (" Network Mask %s", inet_ntoa (al->mask));
size = ntohs (al->header.length) - OSPF_LSA_HEADER_SIZE -4;
@@ -563,7 +562,7 @@ ospf_packet_ls_upd_dump (struct stream *s, u_int16_t length)
break;
#ifdef HAVE_NSSA
case OSPF_AS_NSSA_LSA:
- /* XXX */
+ ospf_as_external_lsa_dump (s, length);
break;
#endif /* HAVE_NSSA */
#ifdef HAVE_OPAQUE_LSA
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 1c8cbbf5..fc6ab137 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -185,12 +185,18 @@ ospf_process_self_originated_lsa (struct ospf *ospf,
case OSPF_AS_EXTERNAL_LSA :
#ifdef HAVE_NSSA
case OSPF_AS_NSSA_LSA:
+ if ( (new->data->type == OSPF_AS_EXTERNAL_LSA)
+ && CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT))
+ {
+ ospf_translated_nssa_refresh (ospf, NULL, new);
+ return;
+ }
#endif /* HAVE_NSSA */
ei = ospf_external_info_check (new);
if (ei)
- ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE);
+ ospf_external_lsa_refresh (ospf, new, ei, LSA_REFRESH_FORCE);
else
- ospf_lsa_flush_as (ospf, new);
+ ospf_lsa_flush_as (ospf, new);
break;
#ifdef HAVE_OPAQUE_LSA
case OSPF_OPAQUE_AREA_LSA:
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 915f0fa7..18ab140a 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -449,12 +449,13 @@ router_lsa_flags (struct ospf_area *area)
SET_FLAG (flags, ROUTER_LSA_BORDER);
#ifdef HAVE_NSSA
/* If Area is NSSA and we are both ABR and unconditional translator,
- * set Nt bit
+ * set Nt bit to inform other routers.
*/
- SET_FLAG (flags, ROUTER_LSA_NT);
+ if ( (area->external_routing == OSPF_AREA_NSSA)
+ && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
+ SET_FLAG (flags, ROUTER_LSA_NT);
#endif /* HAVE_NSSA */
}
-
return flags;
}
@@ -742,13 +743,12 @@ ospf_router_lsa_new (struct ospf_area *area)
#ifdef HAVE_NSSA
/* Set LSA common header fields. */
- lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_NSSA_GET (area),
- OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
+ lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
#else /* ! HAVE_NSSA */
/* Set LSA common header fields. */
lsa_header_set (s, LSA_OPTIONS_GET (area),
- OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
#endif /* HAVE_NSSA */
+ OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
/* Set router-LSA body fields. */
ospf_router_lsa_body_set (s, area);
@@ -1626,10 +1626,17 @@ void
ospf_install_flood_nssa (struct ospf *ospf,
struct ospf_lsa *lsa, struct external_info *ei)
{
- struct ospf_lsa *new2;
+ struct ospf_lsa *new;
struct as_external_lsa *extlsa;
listnode node;
+ /* LSA may be a Type-5 originated via translation of a Type-7 LSA
+ * which originated from an NSSA area. In which case it should not be
+ * flooded back to NSSA areas.
+ */
+ if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
+ return;
+
/* NSSA Originate or Refresh (If anyNSSA)
LSA is self-originated. And just installed as Type-5.
@@ -1654,14 +1661,14 @@ ospf_install_flood_nssa (struct ospf *ospf,
continue;
/* make lsa duplicate, lock=1 */
- new2 = ospf_lsa_dup (lsa);
- new2->area = area;
- new2->data->type = OSPF_AS_NSSA_LSA;
+ new = ospf_lsa_dup (lsa);
+ new->area = area;
+ new->data->type = OSPF_AS_NSSA_LSA;
/* set P-bit if not ABR */
if (! IS_OSPF_ABR (ospf))
{
- SET_FLAG(new2->data->options, OSPF_OPTION_NP);
+ SET_FLAG(new->data->options, OSPF_OPTION_NP);
/* set non-zero FWD ADDR
@@ -1678,8 +1685,8 @@ ospf_install_flood_nssa (struct ospf *ospf,
no type-7 LSA's with the P-bit set should originate from this
router. */
- /* kevinm: not updating lsa anymore, just new2 */
- extlsa = (struct as_external_lsa *)(new2->data);
+ /* kevinm: not updating lsa anymore, just new */
+ extlsa = (struct as_external_lsa *)(new->data);
if (extlsa->e[0].fwd_addr.s_addr == 0)
extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
@@ -1688,19 +1695,252 @@ ospf_install_flood_nssa (struct ospf *ospf,
{
if (IS_DEBUG_OSPF_NSSA)
zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
- ospf_lsa_discard(new2);
+ ospf_lsa_discard(new);
return;
}
}
/* Re-calculate checksum. */
- ospf_lsa_checksum (new2->data);
+ ospf_lsa_checksum (new->data);
/* install also as Type-7 */
- ospf_lsa_install (ospf, NULL, new2); /* Remove Old, Lock New = 2 */
+ ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
/* will send each copy, lock=2+n */
- ospf_flood_through_as (ospf, NULL, new2); /* all attached NSSA's, no AS/STUBs */
+ ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
+ }
+}
+
+struct ospf_lsa *
+ospf_lsa_translated_nssa_new (struct ospf *ospf,
+ struct ospf_lsa *type7)
+{
+
+ struct ospf_lsa *new;
+ struct as_external_lsa *ext, *extnew;
+ struct external_info ei;
+
+ ext = (struct as_external_lsa *)(type7->data);
+
+ /* need external_info struct, fill in bare minimum */
+ ei.p.family = AF_INET;
+ ei.p.prefix = type7->data->id;
+ ei.p.prefixlen = ip_masklen (ext->mask);
+ ei.type = ZEBRA_ROUTE_OSPF;
+ ei.nexthop = ext->header.adv_router;
+ ei.route_map_set.metric = -1;
+ ei.route_map_set.metric_type = -1;
+ ei.tag = 0;
+
+ if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_nssa_translate_originate(): Could not originate "
+ "Translated Type-5 for %s",
+ inet_ntoa (ei.p.prefix));
+ return NULL;
+ }
+
+ extnew = (struct as_external_lsa *)(new->data);
+
+ /* copy over Type-7 data to new */
+ extnew->e[0].tos = ext->e[0].tos;
+ extnew->e[0].route_tag = ext->e[0].route_tag;
+ extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
+ new->data->ls_seqnum = type7->data->ls_seqnum;
+
+ /* add translated flag, checksum and lock new lsa */
+ SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
+ ospf_lsa_checksum (new->data);
+ new = ospf_lsa_lock (new);
+
+ return new;
+}
+
+/* compare type-5 to type-7
+ * -1: err, 0: same, 1: different
+ */
+int
+ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
+{
+
+ struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
+ *e7 = (struct as_external_lsa *)t7;
+
+
+ /* sanity checks */
+ if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
+ && (t7->data->type == OSPF_AS_NSSA_LSA)))
+ return -1;
+
+ if (t5->data->id.s_addr != t7->data->id.s_addr)
+ return -1;
+
+ if (t5->data->ls_seqnum != t7->data->ls_seqnum)
+ return LSA_REFRESH_FORCE;
+
+ if (e5->mask.s_addr != e7->mask.s_addr)
+ return LSA_REFRESH_FORCE;
+
+ if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
+ return LSA_REFRESH_FORCE;
+
+ if (e5->e[0].route_tag != e7->e[0].route_tag)
+ return LSA_REFRESH_FORCE;
+
+ if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
+ return LSA_REFRESH_FORCE;
+
+ return LSA_REFRESH_IF_CHANGED;
+}
+
+/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
+struct ospf_lsa *
+ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
+{
+ struct ospf_lsa *new;
+ struct as_external_lsa *extnew;
+
+ /* we cant use ospf_external_lsa_originate() as we need to set
+ * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
+ */
+
+ if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_translated_nssa_originate(): Could not translate "
+ "Type-7, Id %s, to Type-5",
+ inet_ntoa (type7->data->id));
+ return NULL;
+ }
+
+ extnew = (struct as_external_lsa *)new;
+
+ if (IS_DEBUG_OSPF_NSSA)
+ {
+ zlog_info ("ospf_translated_nssa_originate(): "
+ "translated Type 7, installed:");
+ ospf_lsa_header_dump (new->data);
+ zlog_info (" Network mask: %d",ip_masklen (extnew->mask));
+ zlog_info (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
+ }
+
+ if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
+ {
+ if (IS_DEBUG_OSPF_NSSA);
+ zlog_warn ("ospf_lsa_translated_nssa_originate(): "
+ "Could not install LSA "
+ "id %s", inet_ntoa (type7->data->id));
+ return NULL;
+ }
+
+ ospf->lsa_originate_count++;
+ ospf_flood_through_as (ospf, NULL, new);
+
+ return new;
+}
+
+/* Refresh Translated from NSSA AS-external-LSA. */
+struct ospf_lsa *
+ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
+ struct ospf_lsa *type5)
+{
+ struct ospf_lsa *new = NULL;
+
+ /* Sanity checks. */
+ assert (type7 || type5);
+ if (type7)
+ assert (type7->data);
+ if (type5)
+ assert (type5->data);
+ assert (ospf->anyNSSA);
+
+ /* get required data according to what has been given */
+ if (type7 && type5 == NULL)
+ {
+ /* find the translated Type-5 for this Type-7 */
+ struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
+ struct prefix_ipv4 p =
+ {
+ .prefix = type7->data->id,
+ .prefixlen = ip_masklen (ext->mask),
+ .family = AF_INET,
+ };
+
+ type5 = ospf_external_info_find_lsa (ospf, &p);
+ }
+ else if (type5 && type7 == NULL)
+ {
+ /* find the type-7 from which supplied type-5 was translated,
+ * ie find first type-7 with same LSA Id.
+ */
+ listnode ln;
+ struct route_node *rn;
+ struct ospf_lsa *lsa;
+ struct ospf_area *area;
+
+ LIST_LOOP (ospf->areas, area, ln)
+ {
+ if (area->external_routing != OSPF_AREA_NSSA
+ && !type7)
+ continue;
+
+ LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
+ {
+ if (lsa->data->id.s_addr == type5->data->id.s_addr)
+ {
+ type7 = lsa;
+ break;
+ }
+ }
+ }
}
+
+ /* do we have type7? */
+ if (!type7)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_translated_nssa_refresh(): no Type-7 found for "
+ "Type-5 LSA Id %s",
+ inet_ntoa (type7->data->id));
+ return NULL;
+ }
+
+ /* do we have valid translated type5? */
+ if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_translated_nssa_refresh(): No translated Type-5 "
+ "found for Type-7 with Id %s",
+ inet_ntoa (type7->data->id));
+ return NULL;
+ }
+
+ /* Delete LSA from neighbor retransmit-list. */
+ ospf_ls_retransmit_delete_nbr_as (ospf, type5);
+
+ /* create new translated LSA */
+ if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_translated_nssa_refresh(): Could not translate "
+ "Type-7 for %s to Type-5",
+ inet_ntoa (type7->data->id));
+ return NULL;
+ }
+
+ if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
+ {
+ if (IS_DEBUG_OSPF_NSSA)
+ zlog_info ("ospf_translated_nssa_refresh(): Could not install "
+ "translated LSA, Id %s",
+ inet_ntoa (new->data->id));
+ return NULL;
+ }
+
+ /* Flood LSA through area. */
+ ospf_flood_through_as (ospf, NULL, new);
+
+ return new;
}
#endif /* HAVE_NSSA */
@@ -1781,7 +2021,9 @@ ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
#ifdef HAVE_NSSA
/* If there is any attached NSSA, do special handling */
- if (ospf->anyNSSA)
+ if (ospf->anyNSSA &&
+ /* stay away from translated LSAs! */
+ !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
#endif /* HAVE_NSSA */
@@ -1933,10 +2175,11 @@ ospf_external_lsa_flush (struct ospf *ospf,
return;
}
#ifdef HAVE_NSSA
- /* If LSA is selforiginated and there is NSSA area, flush
- * Type-7 LSA's at first. */
-
- if (IS_LSA_SELF(lsa) && (ospf->anyNSSA))
+ /* If LSA is selforiginated, not a translated LSA, and there is
+ * NSSA area, flush Type-7 LSA's at first.
+ */
+ if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
+ && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
ospf_nssa_lsa_flush (ospf, p);
#endif /* HAVE_NSSA */
@@ -2035,13 +2278,22 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
/* Check the AS-external-LSA should be originated. */
if (!ospf_redistribute_check (ospf, ei, &changed))
{
+ if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
+ zlog_warn ("LSA[Type%d:%s]: Could not be refreshed, "
+ "redist check fail",
+ lsa->data->type, inet_ntoa (lsa->data->id));
ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ei->ifindex, ei->nexthop);
return;
}
if (!changed && !force)
- return;
+ {
+ if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
+ zlog_info ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
+ lsa->data->type, inet_ntoa (lsa->data->id));
+ return;
+ }
/* Delete LSA from neighbor retransmit-list. */
ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
@@ -2074,18 +2326,22 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
#ifdef HAVE_NSSA
/* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
- if (ospf->anyNSSA)
+ if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
#endif /* HAVE_NSSA */
- /* Register slef-originated LSA to refresh queue. */
- ospf_refresher_register_lsa (ospf, new);
+ /* Register self-originated LSA to refresh queue.
+ * Translated LSAs should not be registered, but refreshed upon
+ * refresh of the Type-7
+ */
+ if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
+ ospf_refresher_register_lsa (ospf, new);
/* Debug logging. */
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
{
zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh",
- new->data->type, inet_ntoa (new->data->id));
+ new->data->type, inet_ntoa (new->data->id));
ospf_lsa_header_dump (new->data);
}
@@ -2115,15 +2371,15 @@ ospf_router_lsa_install (struct ospf *ospf,
/* Set router-LSA refresh timer. */
OSPF_TIMER_OFF (area->t_router_lsa_self);
OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
- ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
+ ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
/* Set self-originated router-LSA. */
ospf_lsa_unlock (area->router_lsa_self);
area->router_lsa_self = ospf_lsa_lock (new);
if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
- zlog_info("LSA[Type%d]: ID %s is self-originated",
- new->data->type, inet_ntoa (new->data->id));
+ zlog_info("LSA[Type%d]: ID %s is self-originated",
+ new->data->type, inet_ntoa (new->data->id));
}
return new;
@@ -2245,18 +2501,31 @@ ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
*/
if (!IS_LSA_SELF (new))
- ospf_ase_incremental_update (ospf, new);
+ ospf_ase_incremental_update (ospf, new);
}
#ifdef HAVE_NSSA
- /* There is no point to register selforiginate Type-7 LSA for
- * refreshing. We rely on refreshing Type-5 LSA's */
- if (IS_LSA_SELF (new) && (new->data->type == OSPF_AS_NSSA_LSA))
- return new;
+ if (new->data->type == OSPF_AS_NSSA_LSA)
+ {
+ /* There is no point to register selforiginate Type-7 LSA for
+ * refreshing. We rely on refreshing Type-5 LSA's
+ */
+ if (IS_LSA_SELF (new))
+ return new;
+ else
+ {
+ /* Try refresh type-5 translated LSA for this LSA, if one exists.
+ * New translations will be taken care of by the abr_task.
+ */
+ ospf_translated_nssa_refresh (ospf, new, NULL);
+ }
+ }
#endif /* HAVE_NSSA */
- /* Register self-originated LSA to refresh queue. */
- if (IS_LSA_SELF (new))
+ /* Register self-originated LSA to refresh queue.
+ * Leave Translated LSAs alone
+ */
+ if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
ospf_refresher_register_lsa (ospf, new);
return new;
@@ -2408,10 +2677,11 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
new = ospf_opaque_lsa_install (lsa, rt_recalc);
break;
#endif /* HAVE_OPAQUE_LSA */
- default: /* NSSA, or type-6,8,9....nothing special */
#ifdef HAVE_NSSA
+ case OSPF_AS_NSSA_LSA:
new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
#endif /* HAVE_NSSA */
+ default: /* type-6,8,9....nothing special */
break;
}
@@ -2813,6 +3083,7 @@ ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
break;
case OSPF_AS_EXTERNAL_LSA:
+ case OSPF_AS_NSSA_LSA:
#ifdef HAVE_OPAQUE_LSA
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
@@ -3287,11 +3558,18 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
ospf_summary_asbr_lsa_refresh (ospf, lsa);
break;
case OSPF_AS_EXTERNAL_LSA:
+#ifdef HAVE_NSSA
+ /* Translated from NSSA Type-5s are refreshed when
+ * from refresh of Type-7 - do not refresh these directly.
+ */
+ if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
+ break;
+#endif /* HAVE_NSSA */
ei = ospf_external_info_check (lsa);
if (ei)
- ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
+ ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
else
- ospf_lsa_flush_as (ospf, lsa);
+ ospf_lsa_flush_as (ospf, lsa);
break;
#ifdef HAVE_OPAQUE_LSA
case OSPF_OPAQUE_LINK_LSA:
@@ -3335,14 +3613,16 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
% (OSPF_LSA_REFRESHER_SLOTS);
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
- zlog_info ("LSA[Refresh]: lsa with age %d added to index %d",
- LS_AGE (lsa), index);
+ zlog_info ("LSA[Refresh]: lsa %s with age %d added to index %d",
+ inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
if (!ospf->lsa_refresh_queue.qs[index])
ospf->lsa_refresh_queue.qs[index] = list_new ();
listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
lsa->refresh_list = index;
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
- zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
+ zlog_info ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
+ "setting refresh_list on lsa %p (slod %d)",
+ inet_ntoa (lsa->data->id), lsa, index);
}
}
@@ -3392,7 +3672,8 @@ ospf_lsa_refresh_walker (struct thread *t)
i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
{
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
- zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i);
+ zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
+ "refresh index %d", i);
refresh_list = ospf->lsa_refresh_queue.qs [i];
@@ -3407,7 +3688,9 @@ ospf_lsa_refresh_walker (struct thread *t)
next = node->next;
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
- zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
+ zlog_info ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
+ "refresh lsa %p (slot %d)",
+ inet_ntoa (lsa->data->id), lsa, i);
list_delete_node (refresh_list, node);
ospf_lsa_unlock (lsa);
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index 54c88d46..c5541c85 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -277,7 +277,9 @@ struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_inf
int ospf_external_lsa_originate_timer (struct thread *);
struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t,
struct in_addr, struct in_addr);
-struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *,u_int32_t, struct in_addr);
+struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *,
+ u_int32_t,
+ struct in_addr);
struct ospf_lsa *ospf_lsa_lookup_by_header (struct ospf_area *,
struct lsa_header *);
int ospf_lsa_more_recent (struct ospf_lsa *, struct ospf_lsa *);
@@ -319,10 +321,10 @@ int metric_value (struct ospf *, u_char);
#ifdef HAVE_NSSA
struct in_addr ospf_get_nssa_ip (struct ospf_area *);
-#endif /* HAVE NSSA */
-
-#ifdef HAVE_NSSA
-struct in_addr ospf_get_nssa_ip (struct ospf_area *);
+int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *);
+struct ospf_lsa *ospf_translated_nssa_refresh (struct ospf *, struct ospf_lsa *,
+ struct ospf_lsa *);
+struct ospf_lsa *ospf_translated_nssa_originate (struct ospf *, struct ospf_lsa *);
#endif
#endif /* _ZEBRA_OSPF_LSA_H */
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index aedac32a..0d455ec7 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -414,8 +414,8 @@ set_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp)
{
case OSPF_IFTYPE_POINTOPOINT:
/* Take the router ID of the neighbor. */
- if (((nbr = ospf_nbr_lookup_ptop (oi->nbrs, oi->area->top->router_id)))
- && (nbr->state == NSM_Full))
+ if ((nbr = ospf_nbr_lookup_ptop (oi))
+ && nbr->state == NSM_Full)
{
lp->link_id.value = nbr->router_id;
done = 1;
@@ -429,7 +429,7 @@ set_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp)
if (nbr->state == NSM_Full
|| (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))
- && ospf_nbr_count (oi->nbrs, NSM_Full) > 0))
+ && ospf_nbr_count (oi, NSM_Full) > 0))
{
lp->link_id.value = DR (oi);
done = 1;
@@ -628,7 +628,7 @@ ospf_mpls_te_ism_change (struct ospf_interface *oi, int old_state)
zlog_warn ("ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?", IF_NAME (oi));
goto out;
}
- if (oi->area == NULL || oi->area->top == NULL)
+ if (oi->area == NULL || oi->area->ospf == NULL)
{
zlog_warn ("ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
IF_NAME (oi));
@@ -879,7 +879,7 @@ ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp)
options = LSA_OPTIONS_GET (area);
#ifdef HAVE_NSSA
- options |= LSA_NSSA_GET (area);
+ options |= LSA_OPTIONS_NSSA_GET (area);
#endif /* HAVE_NSSA */
options |= OSPF_OPTION_O; /* Don't forget this :-) */
@@ -891,7 +891,7 @@ ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp)
zlog_info ("LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", lsa_type, inet_ntoa (lsa_id));
/* Set opaque-LSA header fields. */
- lsa_header_set (s, options, lsa_type, lsa_id);
+ lsa_header_set (s, options, lsa_type, lsa_id, area->ospf->router_id);
/* Set opaque-LSA body fields. */
ospf_mpls_te_lsa_body_set (s, lp);
@@ -939,7 +939,7 @@ ospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp)
}
/* Install this LSA into LSDB. */
- if (ospf_lsa_install (NULL/*oi*/, new) == NULL)
+ if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL)
{
zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
ospf_lsa_free (new);
@@ -950,7 +950,7 @@ ospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp)
lp->flags |= LPFLG_LSA_ENGAGED;
/* Update new LSA origination count. */
- area->top->lsa_originate_count++;
+ area->ospf->lsa_originate_count++;
/* Flood new LSA through area. */
ospf_flood_through_area (area, NULL/*nbr*/, new);
@@ -1059,7 +1059,7 @@ ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)
/* Install this LSA into LSDB. */
/* Given "lsa" will be freed in the next function. */
- if (ospf_lsa_install (NULL/*oi*/, new) == NULL)
+ if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL)
{
zlog_warn ("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
ospf_lsa_free (new);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index cec8903c..4418c777 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -1122,7 +1122,7 @@ ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
/* set NSSA area defaults */
area->no_summary = 0;
area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
- area->NSSATranslatorState = OSPF_NSSA_STATE_DISABLED;
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
return 1;
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index ca9d9a9f..23a83ff7 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -344,11 +344,11 @@ struct ospf_area
u_char NSSATranslatorRole; /* NSSA configured role */
#define OSPF_NSSA_ROLE_NEVER 0
-#define OSPF_NSSA_ROLE_ALWAYS 1
-#define OSPF_NSSA_ROLE_CANDIDATE 2
+#define OSPF_NSSA_ROLE_CANDIDATE 1
+#define OSPF_NSSA_ROLE_ALWAYS 2
u_char NSSATranslatorState; /* NSSA operational role */
-#define OSPF_NSSA_STATE_DISABLED 0
-#define OSPF_NSSA_STATE_ENABLED 2
+#define OSPF_NSSA_TRANSLATE_DISABLED 0
+#define OSPF_NSSA_TRANSLATE_ENABLED 1
int NSSATranslatorStabilityInterval;
u_char transit; /* TransitCapability. */
@@ -474,9 +474,8 @@ struct ospf_nbr_nbma
#define LSA_OPTIONS_GET(area) \
(((area)->external_routing == OSPF_AREA_DEFAULT) ? OSPF_OPTION_E : 0)
#ifdef HAVE_NSSA
-#define LSA_NSSA_GET(area) \
- (((area)->external_routing == OSPF_AREA_NSSA) ? \
- (area)->NSSATranslatorState : 0)
+#define LSA_OPTIONS_NSSA_GET(area) \
+ (((area)->external_routing == OSPF_AREA_NSSA) ? OSPF_OPTION_NP : 0)
#endif /* HAVE_NSSA */
#define OSPF_TIMER_ON(T,F,V) \