[ospfd] NSSA translate-enabled ABR should declare itself as ASBR
2006-06-26 Paul Jakma <paul.jakma@sun.com>
* ospf_abr.c: (general) NSSA translate-candidate ABRs need to
be ASBRs, or other routers may rightfully refuse to install
translated type-5s LSAs. reported by dendroot@gmail.com.
(ospf_abr_nssa_check_status) Detect change in translator
state when ABR, and inc/dec redistribute count as when we
leave/enter the disabled state - so that translate-enabled
ABR properly sets ASBR bit on non-NSSA areas.
Run the resulting function through indent to clean it up.
* ospf_lsa.c: (router_lsa_flags) For purposes of ASBR bit,
NSSA area is same as stub area.
diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog
index f2cdae7..27fa804 100644
--- a/ospfd/ChangeLog
+++ b/ospfd/ChangeLog
@@ -1,3 +1,16 @@
+2006-06-26 Paul Jakma <paul.jakma@sun.com>
+
+ * ospf_abr.c: (general) NSSA translate-candidate ABRs need to
+ be ASBRs, or other routers may rightfully refuse to install
+ translated type-5s LSAs. reported by dendroot@gmail.com.
+ (ospf_abr_nssa_check_status) Detect change in translator
+ state when ABR, and inc/dec redistribute count as when we
+ leave/enter the disabled state - so that translate-enabled
+ ABR properly sets ASBR bit on non-NSSA areas.
+ Run the resulting function through indent to clean it up.
+ * ospf_lsa.c: (router_lsa_flags) For purposes of ASBR bit,
+ NSSA area is same as stub area.
+
2006-06-24 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* ospf_snmp.c: (ospfTrapNbrStateChange, ospfTrapIfStateChange) Improve
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 225cf6e..88636f1 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -409,67 +409,80 @@
{
struct ospf_area *area;
struct listnode *lnode, *nnode;
-
+
for (ALL_LIST_ELEMENTS (ospf->areas, lnode, nnode, area))
{
-
+ u_char old_state = area->NSSATranslatorState;
+
if (area->external_routing != OSPF_AREA_NSSA)
continue;
-
+
if (IS_DEBUG_OSPF (nssa, NSSA))
zlog_debug ("ospf_abr_nssa_check_status: "
"checking area %s",
inet_ntoa (area->area_id));
-
+
if (!IS_OSPF_ABR (area->ospf))
{
if (IS_DEBUG_OSPF (nssa, NSSA))
- zlog_debug ("ospf_abr_nssa_check_status: "
- "not ABR");
+ zlog_debug ("ospf_abr_nssa_check_status: "
+ "not ABR");
area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
- continue;
}
-
- 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 ("ospf_abr_nssa_check_status: "
- "never translate");
- area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
- continue;
-
- 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 ("ospf_abr_nssa_check_status: "
- "translate always");
- 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_TRANSLATE_ENABLED;
- if (IS_DEBUG_OSPF (nssa, NSSA))
- zlog_debug ("ospf_abr_nssa_check_status: "
- "elected translator");
- }
- else
- {
- area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
- if (IS_DEBUG_OSPF (nssa, NSSA))
- zlog_debug ("ospf_abr_nssa_check_status: "
- "not elected");
- }
- continue;
- }
+ 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 ("ospf_abr_nssa_check_status: "
+ "never translate");
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
+ break;
+
+ 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 ("ospf_abr_nssa_check_status: "
+ "translate always");
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
+ break;
+
+ 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 ("ospf_abr_nssa_check_status: "
+ "elected translator");
+ }
+ else
+ {
+ area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
+ if (IS_DEBUG_OSPF (nssa, NSSA))
+ zlog_debug ("ospf_abr_nssa_check_status: " "not elected");
+ }
+ break;
+ }
+ }
+ /* 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);
+ }
}
}
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index a0afbad..509afc8 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -437,7 +437,8 @@
SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
/* ASBR can't exit in stub area. */
- if (area->external_routing == OSPF_AREA_STUB)
+ if (area->external_routing == OSPF_AREA_STUB
+ || area->external_routing == OSPF_AREA_NSSA)
UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
/* If ASBR set External flag */
else if (IS_OSPF_ASBR (area->ospf))