ospf6d: fix neighbor state machine (faster lsdb sync, RFC compliance)
The OSPFv3 code doesn't do the following things right as part of an adjacency
bringup:
- Transmit DbDesc frames appropriately to ensure faster state transition to
Loading state
- Transmit LsReq frames when switching to exchange state and on receipt of
an LS update in Loading state
- Requesting LSAs multiple times in LsReq.
It currently uses retransmit timer expiry to send the LsReq and DbDesc frames
which significantly slows down large lsdb syncs.
Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma at cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index beae699..e02a432 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -206,8 +206,8 @@
void
ospf6_install_lsa (struct ospf6_lsa *lsa)
{
- struct ospf6_lsa *old;
struct timeval now;
+ struct ospf6_lsa *old;
if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
@@ -290,7 +290,7 @@
if (ospf6_lsa_compare (lsa, req) > 0)
{
if (is_debug)
- zlog_debug ("Requesting is newer, next neighbor");
+ zlog_debug ("Requesting is older, next neighbor");
continue;
}
@@ -298,18 +298,30 @@
examin next neighbor */
if (ospf6_lsa_compare (lsa, req) == 0)
{
- if (is_debug)
- zlog_debug ("Requesting the same, remove it, next neighbor");
+ if (is_debug)
+ zlog_debug ("Requesting the same, remove it, next neighbor");
+ if (req == on->last_ls_req)
+ {
+ ospf6_lsa_unlock (req);
+ on->last_ls_req = NULL;
+ }
ospf6_lsdb_remove (req, on->request_list);
+ ospf6_check_nbr_loading (on);
continue;
}
/* If the new LSA is more recent, delete from request-list */
if (ospf6_lsa_compare (lsa, req) < 0)
{
- if (is_debug)
- zlog_debug ("Received is newer, remove requesting");
+ if (is_debug)
+ zlog_debug ("Received is newer, remove requesting");
+ if (req == on->last_ls_req)
+ {
+ ospf6_lsa_unlock (req);
+ on->last_ls_req = NULL;
+ }
ospf6_lsdb_remove (req, on->request_list);
+ ospf6_check_nbr_loading (on);
/* fall through */
}
}
@@ -796,7 +808,7 @@
{
/* log */
if (is_debug)
- zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
+ zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
/* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
@@ -950,8 +962,8 @@
zlog_debug ("The LSA is in Seqnumber Wrapping");
zlog_debug ("MaxAge & MaxSeqNum, discard");
}
- ospf6_lsa_delete (new);
- return;
+ ospf6_lsa_delete (new);
+ return;
}
/* Otherwise, Send database copy of this LSA to this neighbor */
@@ -968,8 +980,8 @@
if (from->thread_send_lsupdate == NULL)
from->thread_send_lsupdate =
thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
- ospf6_lsa_delete (new);
- return;
+ ospf6_lsa_delete (new);
+ return;
}
return;
}