ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self);
lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
- LS_REFRESH_TIME);
+ OSPF_LS_REFRESH_TIME);
if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
ospf6_lsa_header_print (lsa);
}
- if (old)
- ospf6_flood_clear (old);
- ospf6_flood (NULL, lsa);
ospf6_install_lsa (lsa);
+ ospf6_flood (NULL, lsa);
}
void
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))
if (old)
{
THREAD_OFF (old->expire);
+ THREAD_OFF (old->refresh);
ospf6_flood_clear (old);
}
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
if (! OSPF6_LSA_IS_MAXAGE (lsa))
lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
- MAXAGE + lsa->birth.tv_sec - now.tv_sec);
+ OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec);
else
lsa->expire = NULL;
+ if (OSPF6_LSA_IS_SEQWRAP(lsa) &&
+ ! (CHECK_FLAG(lsa->flag,OSPF6_LSA_SEQWRAPPED) &&
+ lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)))
+ {
+ if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
+ zlog_debug("lsa install wrapping: sequence 0x%x",
+ ntohl(lsa->header->seqnum));
+ SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
+ /* in lieu of premature_aging, since we do not want to recreate this lsa
+ * and/or mess with timers etc, we just want to wrap the sequence number
+ * and reflood the lsa before continuing.
+ * NOTE: Flood needs to be called right after this function call, by the
+ * caller
+ */
+ lsa->header->seqnum = htonl (OSPF_MAX_SEQUENCE_NUMBER);
+ lsa->header->age = htons (OSPF_LSA_MAXAGE);
+ ospf6_lsa_checksum (lsa->header);
+ }
+
/* actually install */
lsa->installed = now;
ospf6_lsdb_add (lsa, lsa->lsdb);
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;
}
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 */
}
}
/* (4) If the new LSA was received on this interface,
and the interface state is BDR, examin next interface */
- if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
+ if (from && from->ospf6_if == oi)
{
- if (is_debug)
- zlog_debug ("Received is from the I/F, itself BDR, next interface");
- return;
+ if (oi->state == OSPF6_INTERFACE_BDR)
+ {
+ if (is_debug)
+ zlog_debug ("Received is from the I/F, itself BDR, next interface");
+ return;
+ }
+ SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
}
/* (5) flood the LSA out the interface. */
if (is_debug)
zlog_debug ("Schedule flooding for the interface");
- if (if_is_broadcast (oi->interface))
+ if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
+ (oi->type == OSPF_IFTYPE_POINTOPOINT))
{
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
if (oi->thread_send_lsupdate == NULL)
}
}
-static void
+void
ospf6_flood_area (struct ospf6_neighbor *from,
struct ospf6_lsa *lsa, struct ospf6_area *oa)
{
assert (from && from->ospf6_if);
oi = from->ospf6_if;
- /* LSA has been flood back out receiving interface.
- No acknowledgement sent. */
- if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
- {
- if (is_debug)
- zlog_debug ("No acknowledgement (BDR & FloodBack)");
- return;
- }
-
/* LSA is more recent than database copy, but was not flooded
back out receiving interface. Delayed acknowledgement sent
if advertisement received from Designated Router,
struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
int ismore_recent;
int is_debug = 0;
+ unsigned int time_delta_ms;
ismore_recent = 1;
assert (from);
{
/* 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);
if (old)
{
struct timeval now, res;
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
+ monotime(&now);
timersub (&now, &old->installed, &res);
- if (res.tv_sec < MIN_LS_ARRIVAL)
+ time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec/1000);
+ if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival)
{
if (is_debug)
- zlog_debug ("LSA can't be updated within MinLSArrival, discard");
+ zlog_debug ("LSA can't be updated within MinLSArrival, %dms < %dms, discard",
+ time_delta_ms, from->ospf6_if->area->ospf6->lsa_minarrival);
ospf6_lsa_delete (new);
return; /* examin next lsa */
}
}
- quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
+ monotime(&new->received);
if (is_debug)
- zlog_debug ("Flood, Install, Possibly acknowledge the received LSA");
+ zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
+
+ /* Remove older copies of this LSA from retx lists */
+ if (old)
+ ospf6_flood_clear (old);
/* (b) immediately flood and (c) remove from all retrans-list */
/* Prevent self-originated LSA to be flooded. this is to make
if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
ospf6_flood (from, new);
- /* (c) Remove the current database copy from all neighbors' Link
- state retransmission lists. */
- /* XXX, flood_clear ? */
-
/* (d), installing lsdb, which may cause routing
table calculation (replacing database copy) */
ospf6_install_lsa (new);
+ if (OSPF6_LSA_IS_MAXAGE (new))
+ ospf6_maxage_remove (from->ospf6_if->area->ospf6);
+
/* (e) possibly acknowledge */
ospf6_acknowledge_lsa (new, ismore_recent, from);
/* If database copy is in 'Seqnumber Wrapping',
simply discard the received LSA */
if (OSPF6_LSA_IS_MAXAGE (old) &&
- old->header->seqnum == htonl (MAX_SEQUENCE_NUMBER))
+ old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
{
if (is_debug)
{
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 */
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;
}