summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospf6d/ospf6_area.h1
-rw-r--r--ospf6d/ospf6_flood.c22
-rw-r--r--ospf6d/ospf6_flood.h3
-rw-r--r--ospf6d/ospf6_intra.c14
-rw-r--r--ospf6d/ospf6_neighbor.c3
5 files changed, 43 insertions, 0 deletions
diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h
index e162d21cd2..a44a432a0a 100644
--- a/ospf6d/ospf6_area.h
+++ b/ospf6d/ospf6_area.h
@@ -101,6 +101,7 @@ struct ospf6_area {
struct timeval ts_spf; /* SPF calculation time stamp. */
uint32_t full_nbrs; /* Fully adjacent neighbors. */
+ uint8_t intra_prefix_originate; /* Force intra_prefix lsa originate */
};
#define OSPF6_AREA_ENABLE 0x01
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index dae10dce0d..6040c53dce 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -156,6 +156,28 @@ void ospf6_lsa_purge(struct ospf6_lsa *lsa)
ospf6_lsa_premature_aging(lsa);
}
+/* Puring Multi Link-State IDs LSAs:
+ * Same Advertising Router with Multiple Link-State IDs
+ * LSAs, purging require to traverse all Link-State IDs
+ */
+void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa, struct ospf6_lsa *lsa)
+{
+ int ls_id = 0;
+ struct ospf6_lsa *lsa_next;
+ uint16_t type;
+
+ type = lsa->header->type;
+
+ ospf6_lsa_purge(lsa);
+
+ lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+ while (lsa_next) {
+ ospf6_lsa_purge(lsa_next);
+ lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+ }
+}
void ospf6_increment_retrans_count(struct ospf6_lsa *lsa)
{
diff --git a/ospf6d/ospf6_flood.h b/ospf6d/ospf6_flood.h
index f5d33e2843..6931024fff 100644
--- a/ospf6d/ospf6_flood.h
+++ b/ospf6d/ospf6_flood.h
@@ -41,6 +41,9 @@ extern void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa,
struct ospf6_interface *oi);
extern void ospf6_lsa_purge(struct ospf6_lsa *lsa);
+extern void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa,
+ struct ospf6_lsa *lsa);
+
/* access method to retrans_count */
extern void ospf6_increment_retrans_count(struct ospf6_lsa *lsa);
extern void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa);
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 14f12d6b6a..c9e2ff9eb5 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -1015,6 +1015,20 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
return 0;
}
+ /* Neighbor change to FULL, if INTRA-AREA-PREFIX LSA
+ * has not change, Flush old LSA and Re-Originate INP,
+ * as ospf6_flood() checks if LSA is same as DB,
+ * it won't be updated to neighbor's DB.
+ */
+ if (oa->intra_prefix_originate) {
+ if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
+ zlog_debug("%s: Re-originate intra prefix LSA, Current full nbrs %u",
+ __PRETTY_FUNCTION__, oa->full_nbrs);
+ if (old)
+ ospf6_lsa_purge_multi_ls_id(oa, old);
+ oa->intra_prefix_originate = 0;
+ }
+
/* put prefixes to advertise */
prefix_num = 0;
op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index 542a24bfc9..16bf2fd8e7 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -188,6 +188,9 @@ static void ospf6_neighbor_state_change(u_char next_state,
OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if);
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if);
}
+ if (next_state == OSPF6_NEIGHBOR_FULL)
+ on->ospf6_if->area->intra_prefix_originate = 1;
+
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area);
if (prev_state == OSPF6_NEIGHBOR_LOADING