summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospfd/ospf_lsa.c26
-rw-r--r--ospfd/ospf_lsa.h2
-rw-r--r--ospfd/ospf_packet.c7
3 files changed, 32 insertions, 3 deletions
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index d209ae053c..cc1b2919c0 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -2954,6 +2954,32 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
return 0;
}
+/* This function checks whether an LSA with initial sequence number should be
+ * originated after a wrap in sequence number
+ */
+void ospf_check_and_gen_init_seq_lsa(struct ospf_interface *oi,
+ struct ospf_lsa *recv_lsa)
+{
+ struct ospf_lsa *lsa = NULL;
+ struct ospf *ospf = oi->ospf;
+
+ lsa = ospf_lsa_lookup_by_header(oi->area, recv_lsa->data);
+
+ if ((lsa == NULL) || (!CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE))
+ || (lsa->retransmit_counter != 0)) {
+ if (IS_DEBUG_OSPF(lsa, LSA))
+ zlog_debug(
+ "Do not generate LSA with initial seqence number.");
+ return;
+ }
+
+ ospf_lsa_maxage_delete(ospf, lsa);
+
+ lsa->data->ls_seqnum = lsa_seqnum_increment(lsa);
+
+ ospf_lsa_refresh(ospf, lsa);
+}
+
void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
{
struct route_node *rn;
diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h
index f536c311f9..5dcd072774 100644
--- a/ospfd/ospf_lsa.h
+++ b/ospfd/ospf_lsa.h
@@ -349,6 +349,8 @@ extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
struct ospf_lsa *type7,
struct ospf_lsa *type5);
+extern void ospf_check_and_gen_init_seq_lsa(struct ospf_interface *oi,
+ struct ospf_lsa *lsa);
extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
int type);
#endif /* _ZEBRA_OSPF_LSA_H */
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 8a76e265bc..000bbadc54 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -2090,8 +2090,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|| (ret = ospf_lsa_more_recent(current, lsa)) < 0) {
/* CVE-2017-3224 */
if (current && (IS_LSA_MAX_SEQ(current))
- && (IS_LSA_MAX_SEQ(lsa))
- && !IS_LSA_MAXAGE(lsa)) {
+ && (IS_LSA_MAX_SEQ(lsa)) && !IS_LSA_MAXAGE(lsa)) {
zlog_debug(
"Link State Update[%s]: has Max Seq and higher checksum but not MaxAge. Dropping it",
dump_lsa_key(lsa));
@@ -2271,8 +2270,10 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
lsr = ospf_ls_retransmit_lookup(nbr, lsa);
- if (lsr != NULL && ospf_lsa_more_recent(lsr, lsa) == 0)
+ if (lsr != NULL && ospf_lsa_more_recent(lsr, lsa) == 0) {
ospf_ls_retransmit_delete(nbr, lsr);
+ ospf_check_and_gen_init_seq_lsa(oi, lsa);
+ }
lsa->data = NULL;
ospf_lsa_discard(lsa);