summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_lsdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_lsdb.c')
-rw-r--r--ospf6d/ospf6_lsdb.c209
1 files changed, 106 insertions, 103 deletions
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index 280bdf95..707afc67 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -54,9 +54,12 @@ ospf6_lsdb_create (void *data)
void
ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
{
- ospf6_lsdb_remove_all (lsdb);
- route_table_finish (lsdb->table);
- XFREE (MTYPE_OSPF6_LSDB, lsdb);
+ if (lsdb != NULL)
+ {
+ ospf6_lsdb_remove_all (lsdb);
+ route_table_finish (lsdb->table);
+ XFREE (MTYPE_OSPF6_LSDB, lsdb);
+ }
}
static void
@@ -70,7 +73,7 @@ ospf6_lsdb_set_key (struct prefix_ipv6 *key, void *value, int len)
key->prefixlen += len * 8;
}
-#ifndef NDEBUG
+#ifdef DEBUG
static void
_lsdb_count_assert (struct ospf6_lsdb *lsdb)
{
@@ -94,16 +97,16 @@ _lsdb_count_assert (struct ospf6_lsdb *lsdb)
assert (num == lsdb->count);
}
#define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
-#else /*NDEBUG*/
+#else /*DEBUG*/
#define ospf6_lsdb_count_assert(t) ((void) 0)
-#endif /*NDEBUG*/
+#endif /*DEBUG*/
void
ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
{
struct prefix_ipv6 key;
- struct route_node *current, *nextnode, *prevnode;
- struct ospf6_lsa *next, *prev, *old = NULL;
+ struct route_node *current;
+ struct ospf6_lsa *old = NULL;
memset (&key, 0, sizeof (key));
ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
@@ -114,55 +117,25 @@ ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
current = route_node_get (lsdb->table, (struct prefix *) &key);
old = current->info;
current->info = lsa;
+ lsa->rn = current;
ospf6_lsa_lock (lsa);
- if (old)
- {
- if (old->prev)
- old->prev->next = lsa;
- if (old->next)
- old->next->prev = lsa;
- lsa->next = old->next;
- lsa->prev = old->prev;
- }
- else
+ if (!old)
{
- /* next link */
- nextnode = current;
- route_lock_node (nextnode);
- do {
- nextnode = route_next (nextnode);
- } while (nextnode && nextnode->info == NULL);
- if (nextnode == NULL)
- lsa->next = NULL;
- else
- {
- next = nextnode->info;
- lsa->next = next;
- next->prev = lsa;
- route_unlock_node (nextnode);
- }
+ lsdb->count++;
- /* prev link */
- prevnode = current;
- route_lock_node (prevnode);
- do {
- prevnode = route_prev (prevnode);
- } while (prevnode && prevnode->info == NULL);
- if (prevnode == NULL)
- lsa->prev = NULL;
+ if (OSPF6_LSA_IS_MAXAGE (lsa))
+ {
+ if (lsdb->hook_remove)
+ (*lsdb->hook_remove) (lsa);
+ }
else
- {
- prev = prevnode->info;
- lsa->prev = prev;
- prev->next = lsa;
- route_unlock_node (prevnode);
- }
-
- lsdb->count++;
+ {
+ if (lsdb->hook_add)
+ (*lsdb->hook_add) (lsa);
+ }
}
-
- if (old)
+ else
{
if (OSPF6_LSA_IS_CHANGED (old, lsa))
{
@@ -187,21 +160,9 @@ ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
(*lsdb->hook_add) (lsa);
}
}
- }
- else if (OSPF6_LSA_IS_MAXAGE (lsa))
- {
- if (lsdb->hook_remove)
- (*lsdb->hook_remove) (lsa);
- }
- else
- {
- if (lsdb->hook_add)
- (*lsdb->hook_add) (lsa);
+ ospf6_lsa_unlock (old);
}
- if (old)
- ospf6_lsa_unlock (old);
-
ospf6_lsdb_count_assert (lsdb);
}
@@ -220,19 +181,15 @@ ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
node = route_node_lookup (lsdb->table, (struct prefix *) &key);
assert (node && node->info == lsa);
- if (lsa->prev)
- lsa->prev->next = lsa->next;
- if (lsa->next)
- lsa->next->prev = lsa->prev;
-
node->info = NULL;
lsdb->count--;
if (lsdb->hook_remove)
(*lsdb->hook_remove) (lsa);
+ route_unlock_node (node); /* to free the lookup lock */
+ route_unlock_node (node); /* to free the original lock */
ospf6_lsa_unlock (lsa);
- route_unlock_node (node);
ospf6_lsdb_count_assert (lsdb);
}
@@ -255,6 +212,8 @@ ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
node = route_node_lookup (lsdb->table, (struct prefix *) &key);
if (node == NULL || node->info == NULL)
return NULL;
+
+ route_unlock_node (node);
return (struct ospf6_lsa *) node->info;
}
@@ -306,21 +265,9 @@ ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
if (prefix_same (&node->p, p))
{
- struct route_node *prev = node;
- struct ospf6_lsa *lsa_prev;
- struct ospf6_lsa *lsa_next;
-
node = route_next (node);
while (node && node->info == NULL)
node = route_next (node);
-
- lsa_prev = prev->info;
- lsa_next = (node ? node->info : NULL);
- assert (lsa_prev);
- assert (lsa_prev->next == lsa_next);
- if (lsa_next)
- assert (lsa_next->prev == lsa_prev);
- zlog_debug ("lsdb_lookup_next: assert OK with previous LSA");
}
if (! node)
@@ -346,7 +293,6 @@ ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
if (node == NULL)
return NULL;
- route_unlock_node (node);
if (node->info)
ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
return (struct ospf6_lsa *) node->info;
@@ -355,12 +301,20 @@ ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
struct ospf6_lsa *
ospf6_lsdb_next (struct ospf6_lsa *lsa)
{
- struct ospf6_lsa *next = lsa->next;
+ struct route_node *node = lsa->rn;
+ struct ospf6_lsa *next = NULL;
- ospf6_lsa_unlock (lsa);
- if (next)
- ospf6_lsa_lock (next);
+ do {
+ node = route_next (node);
+ } while (node && node->info == NULL);
+ if ((node != NULL) && (node->info != NULL))
+ {
+ next = node->info;
+ ospf6_lsa_lock (next);
+ }
+
+ ospf6_lsa_unlock (lsa);
return next;
}
@@ -390,8 +344,6 @@ ospf6_lsdb_type_router_head (u_int16_t type, u_int32_t adv_router,
if (node == NULL)
return NULL;
- else
- route_unlock_node (node);
if (! prefix_match ((struct prefix *) &key, &node->p))
return NULL;
@@ -406,18 +358,19 @@ struct ospf6_lsa *
ospf6_lsdb_type_router_next (u_int16_t type, u_int32_t adv_router,
struct ospf6_lsa *lsa)
{
- struct ospf6_lsa *next = lsa->next;
+ struct ospf6_lsa *next = ospf6_lsdb_next(lsa);
if (next)
{
if (next->header->type != type ||
next->header->adv_router != adv_router)
- next = NULL;
+ {
+ route_unlock_node (next->rn);
+ ospf6_lsa_unlock (next);
+ next = NULL;
+ }
}
- if (next)
- ospf6_lsa_lock (next);
- ospf6_lsa_unlock (lsa);
return next;
}
@@ -444,8 +397,6 @@ ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
if (node == NULL)
return NULL;
- else
- route_unlock_node (node);
if (! prefix_match ((struct prefix *) &key, &node->p))
return NULL;
@@ -459,17 +410,18 @@ ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
struct ospf6_lsa *
ospf6_lsdb_type_next (u_int16_t type, struct ospf6_lsa *lsa)
{
- struct ospf6_lsa *next = lsa->next;
+ struct ospf6_lsa *next = ospf6_lsdb_next (lsa);
if (next)
{
if (next->header->type != type)
- next = NULL;
+ {
+ route_unlock_node (next->rn);
+ ospf6_lsa_unlock (next);
+ next = NULL;
+ }
}
- if (next)
- ospf6_lsa_lock (next);
- ospf6_lsa_unlock (lsa);
return next;
}
@@ -477,11 +429,62 @@ void
ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
{
struct ospf6_lsa *lsa;
+
+ if (lsdb == NULL)
+ return;
+
for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
ospf6_lsdb_remove (lsa, lsdb);
}
void
+ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa)
+{
+ if (lsa != NULL)
+ {
+ if (lsa->rn != NULL)
+ route_unlock_node (lsa->rn);
+ ospf6_lsa_unlock (lsa);
+ }
+}
+
+int
+ospf6_lsdb_maxage_remover (struct ospf6_lsdb *lsdb)
+{
+ int reschedule = 0;
+ struct ospf6_lsa *lsa;
+
+ for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
+ {
+ if (! OSPF6_LSA_IS_MAXAGE (lsa))
+ continue;
+ if (lsa->retrans_count != 0)
+ {
+ reschedule = 1;
+ continue;
+ }
+ if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))
+ zlog_debug ("Remove MaxAge %s", lsa->name);
+ if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED))
+ {
+ UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
+ /*
+ * lsa->header->age = 0;
+ */
+ lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER + 1);
+ ospf6_lsa_checksum (lsa->header);
+
+ THREAD_OFF(lsa->refresh);
+ thread_execute (master, ospf6_lsa_refresh, lsa, 0);
+ } else {
+ ospf6_lsdb_remove (lsa, lsdb);
+ }
+ }
+
+ return (reschedule);
+}
+
+void
ospf6_lsdb_show (struct vty *vty, int level,
u_int16_t *type, u_int32_t *id, u_int32_t *adv_router,
struct ospf6_lsdb *lsdb)
@@ -551,7 +554,7 @@ ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
continue;
if (ntohl (lsa->header->id) > id)
{
- ospf6_lsa_unlock (lsa);
+ ospf6_lsdb_lsa_unlock (lsa);
break;
}
id++;
@@ -572,7 +575,7 @@ ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
/* if current database copy not found, return InitialSequenceNumber */
lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
if (lsa == NULL)
- seqnum = INITIAL_SEQUENCE_NUMBER;
+ seqnum = OSPF_INITIAL_SEQUENCE_NUMBER;
else
seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;