struct timeval delta, now;
int delay = 0;
- gettimeofday (&now, NULL);
+ quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
delta = tv_sub (now, lsa->tv_orig);
if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
get_age (struct ospf_lsa *lsa)
{
int age;
- struct timeval now;
- gettimeofday (&now, NULL);
- age = ntohs (lsa->data->ls_age) + tv_floor (tv_sub (now, lsa->tv_recv));
+ age = ntohs (lsa->data->ls_age)
+ + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
return age;
}
new->flags = 0;
new->lock = 1;
new->retransmit_counter = 0;
- gettimeofday (&new->tv_recv, NULL);
+ new->tv_recv = recent_relative_time ();
new->tv_orig = new->tv_recv;
new->refresh_list = -1;
/* Unlock LSA. */
void
-ospf_lsa_unlock (struct ospf_lsa *lsa)
+ospf_lsa_unlock (struct ospf_lsa **lsa)
{
/* This is sanity check. */
- if (!lsa)
+ if (!lsa || !*lsa)
return;
- lsa->lock--;
+ (*lsa)->lock--;
- assert (lsa->lock >= 0);
+ assert ((*lsa)->lock >= 0);
- if (lsa->lock == 0)
+ if ((*lsa)->lock == 0)
{
- assert (CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD));
- ospf_lsa_free (lsa);
+ assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
+ ospf_lsa_free (*lsa);
+ *lsa = NULL;
}
}
if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
{
SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
- ospf_lsa_unlock (lsa);
+ ospf_lsa_unlock (&lsa);
}
}
SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
/* ASBR can't exit in stub area. */
- if (area->external_routing == OSPF_AREA_STUB)
+ if (area->external_routing == OSPF_AREA_STUB
+ || area->external_routing == OSPF_AREA_NSSA)
UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
/* If ASBR set External flag */
else if (IS_OSPF_ASBR (area->ospf))
return 1;
}
-/* Describe Point-to-Point link. */
+/* Describe Point-to-Point link (Section 12.4.1.1). */
static int
lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
{
LSA_LINK_TYPE_POINTOPOINT, 0, cost);
}
- if (CONNECTED_DEST_HOST(oi->connected))
- {
- /* Option 1:
- link_type = LSA_LINK_TYPE_STUB;
- link_id = nbr->address.u.prefix4;
- link_data.s_addr = 0xffffffff;
- link_cost = o->output_cost; */
-
- id.s_addr = oi->connected->destination->u.prefix4.s_addr;
- mask.s_addr = 0xffffffff;
- links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
- oi->output_cost);
- }
- else
- {
- /* Option 2: We need to include link to a stub
- network regardless of the state of the neighbor */
- masklen2ip (oi->address->prefixlen, &mask);
- id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
- links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
- oi->output_cost);
- }
+ /* Regardless of the state of the neighboring router, we must
+ add a Type 3 link (stub network).
+ N.B. Options 1 & 2 share basically the same logic. */
+ masklen2ip (oi->address->prefixlen, &mask);
+ id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
+ links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
+ oi->output_cost);
return links;
}
zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
lsa->data->type, inet_ntoa (lsa->data->id), area_str);
ospf_lsa_flush_area (lsa, area);
- ospf_lsa_unlock (area->router_lsa_self);
+ ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = NULL;
/* Refresh router-LSA, (not install) and flood through area. */
{
if (IS_DEBUG_OSPF_NSSA)
zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
- ospf_lsa_discard(new);
+ ospf_lsa_discard (new);
return;
}
}
if (IS_DEBUG_OSPF_NSSA)
zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
"translated LSA, Id %s",
- inet_ntoa (new->data->id));
+ inet_ntoa (type7->data->id));
return NULL;
}
new->data->ls_seqnum = lsa_seqnum_increment (lsa);
- /* Record timestamp. */
- gettimeofday (&new->tv_orig, NULL);
-
/* Re-calculate checksum. */
ospf_lsa_checksum (new->data);
ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
/* Set self-originated router-LSA. */
- ospf_lsa_unlock (area->router_lsa_self);
+ ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = ospf_lsa_lock (new);
if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ospf_network_lsa_refresh_timer,
OSPF_LS_REFRESH_TIME);
- ospf_lsa_unlock (oi->network_lsa_self);
+ ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = ospf_lsa_lock (new);
}
{
struct ospf_lsa *old;
+ if (!lsdb)
+ {
+ zlog_warn ("%s: Called with NULL lsdb!", __func__);
+ if (!lsa)
+ zlog_warn ("%s: and NULL LSA!", __func__);
+ else
+ zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
+ lsa->data->type, inet_ntoa (lsa->data->id));
+ return;
+ }
+
old = ospf_lsdb_lookup (lsdb, lsa);
if (!old)
}
/* Remove from lsdb. */
- ospf_discard_from_db (ospf, lsa->lsdb, lsa);
- ospf_lsdb_delete (lsa->lsdb, lsa);
+ if (lsa->lsdb)
+ {
+ ospf_discard_from_db (ospf, lsa->lsdb, lsa);
+ ospf_lsdb_delete (lsa->lsdb, lsa);
+ }
+ else
+ zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
+ lsa->data->type, inet_ntoa (lsa->data->id));
}
/* A MaxAge LSA must be removed immediately from the router's link
if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
{
list_delete_node (ospf->maxage_lsa, n);
- ospf_lsa_unlock (lsa);
+ ospf_lsa_unlock (&lsa); /* maxage_lsa */
}
}
zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
ospf_lsa_flush_area (lsa, area);
- ospf_lsa_unlock (area->router_lsa_self);
+ ospf_lsa_unlock (&area->router_lsa_self);
area->router_lsa_self = NULL;
OSPF_TIMER_OFF (area->t_router_lsa_self);
}
zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
ospf_lsa_flush_area (oi->network_lsa_self, area);
- ospf_lsa_unlock (oi->network_lsa_self);
+ ospf_lsa_unlock (&oi->network_lsa_self);
oi->network_lsa_self = NULL;
OSPF_TIMER_OFF (oi->t_network_lsa_self);
}
break;
}
- ospf_lsa_unlock (data->lsa);
+ ospf_lsa_unlock (&data->lsa); /* Message */
XFREE (MTYPE_OSPF_MESSAGE, data);
return 0;
}
data->action = LSA_ACTION_FLOOD_AREA;
data->area = area;
- data->lsa = ospf_lsa_lock (lsa);
+ data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
thread_add_event (master, ospf_lsa_action, data, 0);
}
data->action = LSA_ACTION_FLUSH_AREA;
data->area = area;
- data->lsa = ospf_lsa_lock (lsa);
+ data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
thread_add_event (master, ospf_lsa_action, data, 0);
}
delay = 0;
current_index = ospf->lsa_refresh_queue.index +
- (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
+ (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
% (OSPF_LSA_REFRESHER_SLOTS);
inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
if (!ospf->lsa_refresh_queue.qs[index])
ospf->lsa_refresh_queue.qs[index] = list_new ();
- listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
+ listnode_add (ospf->lsa_refresh_queue.qs[index],
+ ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
lsa->refresh_list = index;
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
list_free (refresh_list);
ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
}
- ospf_lsa_unlock (lsa);
+ ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
lsa->refresh_list = -1;
}
}
modulus. */
ospf->lsa_refresh_queue.index =
((unsigned long)(ospf->lsa_refresh_queue.index +
- (time (NULL) - ospf->lsa_refresher_started) /
+ (quagga_time (NULL) - ospf->lsa_refresher_started) /
OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
inet_ntoa (lsa->data->id), lsa, i);
list_delete_node (refresh_list, node);
- ospf_lsa_unlock (lsa);
+ ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
lsa->refresh_list = -1;
listnode_add (lsa_to_refresh, lsa);
}
ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
ospf, ospf->lsa_refresh_interval);
- ospf->lsa_refresher_started = time (NULL);
+ ospf->lsa_refresher_started = quagga_time (NULL);
for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
ospf_lsa_refresh (ospf, lsa);