]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: check the LS-Ack's recentness instead of only comparing the #seq
authorLu Feng <lu.feng@6wind.com>
Fri, 21 Feb 2014 08:11:15 +0000 (08:11 +0000)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 14 May 2014 14:46:28 +0000 (16:46 +0200)
ISSUE:

RTA(DR)-----(BackupDR)RTB

RTA advertises a new LSA to RTB, and then flushes the LSA (with setting
the age of the LSA to MaxAge) within 1 second. Then the LSA is deleted
from RTA, while it still exists on RTB with non-MaxAge and can not be
flushed any more.

FIX:

The reason can be explained in below:

a) RTA -- new LSA, #seq=1 --> RTB (RTB will send the delayed Ack in 1s)
b) RTA -- MaxAge LSA, #seq=1 --> RTB (RTB discards it for the MIN_LS_ARRIVAL)
c) RTA <-- Ack for the new LSA, #seq=1 -- RTB (RTA accepts it)

In the step c), ospf_ls_ack() compares the #seq of the entry in the LS-Ack
with that of local MaxAge LSA. The #seq of the two entries are same. So
the Ack is accepted and the LSA is removed from the retransmit-list (while
it should not).

In RFC2328, section  13.7.  Receiving link state acknowledgments:

o   If the acknowledgment is for the same instance that is  <==
    contained on the list, remove the item from the list and
    examine the next acknowledgment.  Otherwise:

where "same instance" does not mean the same #seq. We must call
ospf_lsa_more_recent() to check whether the two instances are same.

Signed-off-by: Feng Lu <lu.feng@6wind.com>
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
ospfd/ospf_packet.c

index ab68bf0b7c3825598348a5221d1c400409523663..cce56fc625be09ae9dedab5a261226112fd9ebdf 100644 (file)
@@ -2120,7 +2120,7 @@ ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
 
       lsr = ospf_ls_retransmit_lookup (nbr, lsa);
 
-      if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
+      if (lsr != NULL && ospf_lsa_more_recent (lsr, lsa) == 0)
         {
 #ifdef HAVE_OPAQUE_LSA
           if (IS_OPAQUE_LSA (lsr->data->type))