From 3cb62bb387d0630e8b2e3fe053de155563bac077 Mon Sep 17 00:00:00 2001 From: Mobashshera Rasool Date: Fri, 3 Sep 2021 05:10:26 -0700 Subject: [PATCH] ospfd: RFC conformance test case 25.23 issue fix Problem Statement : =================== LSA with InitialSequenceNumber is not originated after MaxSequenceNumber. ANVL Test case 25.33 states: ============================ As soon as this flooding of a LSA with LS sequence number MaxSequenceNumber has been acknowledged by all adjacent neighbors, a new instance can be originated with sequence number of InitialSequenceNumber. RCA : ===== DUT did not originated LSA with INITIAL_SEQUENCE number even after receiving ACK for max sequence LSA. Code is not present to handle this situation in the lsa ack flow. Fix : ===== Add code to originate LSA with initial sequence number in the LSA ack flow in case of wrap around sequence number. Signed-off-by: Mobashshera Rasool --- ospfd/ospf_lsa.c | 26 ++++++++++++++++++++++++++ ospfd/ospf_lsa.h | 2 ++ ospfd/ospf_packet.c | 7 ++++--- 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); -- 2.39.5