ospf6d: rewrite LSDB iteration

rip out this pile of open-coded goo and replace it with uses of the API
that table.h provides.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2017-07-06 15:02:31 +02:00
parent f1c73d1495
commit 954306f70c
2 changed files with 81 additions and 161 deletions

View File

@ -64,7 +64,7 @@ ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
}
static void
ospf6_lsdb_set_key (struct prefix_ipv6 *key, void *value, int len)
ospf6_lsdb_set_key (struct prefix_ipv6 *key, const void *value, int len)
{
assert (key->prefixlen % 8 == 0);
@ -279,152 +279,77 @@ ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
return (struct ospf6_lsa *) node->info;
}
/* Iteration function */
struct ospf6_lsa *
ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
const struct route_node *
ospf6_lsdb_head (struct ospf6_lsdb *lsdb,
int argmode, uint16_t type, uint32_t adv_router,
struct ospf6_lsa **lsa)
{
struct route_node *node;
struct route_node *node, *end;
node = route_top (lsdb->table);
if (node == NULL)
return NULL;
*lsa = NULL;
/* skip to the existing lsdb entry */
while (node && node->info == NULL)
node = route_next (node);
if (node == NULL)
return NULL;
if (node->info)
ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
return (struct ospf6_lsa *) node->info;
}
struct ospf6_lsa *
ospf6_lsdb_next (struct ospf6_lsa *lsa)
{
struct route_node *node = lsa->rn;
struct ospf6_lsa *next = NULL;
do {
node = route_next (node);
} while (node && node->info == NULL);
if ((node != NULL) && (node->info != NULL))
if (argmode > 0)
{
next = node->info;
ospf6_lsa_lock (next);
}
struct prefix_ipv6 key = { .family = AF_INET6, .prefixlen = 0 };
ospf6_lsa_unlock (lsa);
return next;
}
struct ospf6_lsa *
ospf6_lsdb_type_router_head (u_int16_t type, u_int32_t adv_router,
struct ospf6_lsdb *lsdb)
{
struct route_node *node;
struct prefix_ipv6 key;
struct ospf6_lsa *lsa;
memset (&key, 0, sizeof (key));
ospf6_lsdb_set_key (&key, &type, sizeof (type));
if (argmode > 1)
ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
node = lsdb->table->top;
/* Walk down tree. */
while (node && node->p.prefixlen <= key.prefixlen &&
prefix_match (&node->p, (struct prefix *) &key))
node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)];
if (node)
route_lock_node (node);
while (node && node->info == NULL)
node = route_next (node);
if (node == NULL)
node = route_table_get_next (lsdb->table, &key);
if (!node || !prefix_match((struct prefix *)&key, &node->p))
return NULL;
if (! prefix_match ((struct prefix *) &key, &node->p))
for (end = node;
end && end->parent && end->parent->p.prefixlen >= key.prefixlen;
end = end->parent)
;
}
else
{
node = route_top (lsdb->table);
end = NULL;
}
while (node && !node->info)
node = route_next_until(node, end);
if (!node)
return NULL;
if (!node->info)
{
route_unlock_node(node);
return NULL;
}
lsa = node->info;
ospf6_lsa_lock (lsa);
*lsa = node->info;
ospf6_lsa_lock (*lsa);
return lsa;
return end;
}
struct ospf6_lsa *
ospf6_lsdb_type_router_next (u_int16_t type, u_int32_t adv_router,
ospf6_lsdb_next (const struct route_node *iterend,
struct ospf6_lsa *lsa)
{
struct ospf6_lsa *next = ospf6_lsdb_next(lsa);
struct route_node *node = lsa->rn;
if (next)
{
if (next->header->type != type ||
next->header->adv_router != adv_router)
{
route_unlock_node (next->rn);
ospf6_lsa_unlock (next);
next = NULL;
}
}
ospf6_lsa_unlock(lsa);
do
node = route_next_until(node, iterend);
while (node && !node->info);
if (node && node->info)
{
struct ospf6_lsa *next = node->info;
ospf6_lsa_lock (next);
return next;
}
struct ospf6_lsa *
ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
{
struct route_node *node;
struct prefix_ipv6 key;
struct ospf6_lsa *lsa;
memset (&key, 0, sizeof (key));
ospf6_lsdb_set_key (&key, &type, sizeof (type));
/* Walk down tree. */
node = lsdb->table->top;
while (node && node->p.prefixlen <= key.prefixlen &&
prefix_match (&node->p, (struct prefix *) &key))
node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)];
}
if (node)
route_lock_node (node);
while (node && node->info == NULL)
node = route_next (node);
if (node == NULL)
route_unlock_node (node);
return NULL;
if (! prefix_match ((struct prefix *) &key, &node->p))
return NULL;
lsa = node->info;
ospf6_lsa_lock (lsa);
return lsa;
}
struct ospf6_lsa *
ospf6_lsdb_type_next (u_int16_t type, struct ospf6_lsa *lsa)
{
struct ospf6_lsa *next = ospf6_lsdb_next (lsa);
if (next)
{
if (next->header->type != type)
{
route_unlock_node (next->rn);
ospf6_lsa_unlock (next);
next = NULL;
}
}
return next;
}
void
@ -492,6 +417,7 @@ ospf6_lsdb_show (struct vty *vty, enum ospf_lsdb_show_level level,
struct ospf6_lsdb *lsdb)
{
struct ospf6_lsa *lsa;
const struct route_node *end = NULL;
void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
switch (level)
@ -526,24 +452,15 @@ ospf6_lsdb_show (struct vty *vty, enum ospf_lsdb_show_level level,
if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
ospf6_lsa_show_summary_header (vty);
if (type && adv_router)
lsa = ospf6_lsdb_type_router_head (*type, *adv_router, lsdb);
else if (type)
lsa = ospf6_lsdb_type_head (*type, lsdb);
else
lsa = ospf6_lsdb_head (lsdb);
end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router),
*type, *adv_router, &lsa);
while (lsa)
{
if ((! adv_router || lsa->header->adv_router == *adv_router) &&
(! id || lsa->header->id == *id))
(*showfunc) (vty, lsa);
if (type && adv_router)
lsa = ospf6_lsdb_type_router_next (*type, *adv_router, lsa);
else if (type)
lsa = ospf6_lsdb_type_next (*type, lsa);
else
lsa = ospf6_lsdb_next (lsa);
lsa = ospf6_lsdb_next (end, lsa);
}
}

View File

@ -48,29 +48,32 @@ extern struct ospf6_lsa *ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id,
extern void ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
extern void ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
extern struct ospf6_lsa *ospf6_lsdb_head (struct ospf6_lsdb *lsdb);
extern struct ospf6_lsa *ospf6_lsdb_next (struct ospf6_lsa *lsa);
#define ALL_LSDB(lsdb, lsa) \
lsa = ospf6_lsdb_head(lsdb); lsa; \
lsa = ospf6_lsdb_next(lsa)
extern struct ospf6_lsa *ospf6_lsdb_type_router_head (u_int16_t type,
u_int32_t adv_router,
struct ospf6_lsdb *lsdb);
extern struct ospf6_lsa *ospf6_lsdb_type_router_next (u_int16_t type,
u_int32_t adv_router,
extern const struct route_node *ospf6_lsdb_head (
struct ospf6_lsdb *lsdb,
int argmode,
uint16_t type,
uint32_t adv_router,
struct ospf6_lsa **lsa);
extern struct ospf6_lsa *ospf6_lsdb_next (const struct route_node *iterend,
struct ospf6_lsa *lsa);
#define ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa) \
lsa = ospf6_lsdb_type_router_head(type, adv_router, lsdb); lsa; \
lsa = ospf6_lsdb_type_router_next(type, adv_router, lsa)
const struct route_node *iterend = \
ospf6_lsdb_head(lsdb, 2, type, adv_router, &lsa); \
lsa; \
lsa = ospf6_lsdb_next(iterend, lsa)
extern struct ospf6_lsa *ospf6_lsdb_type_head (u_int16_t type,
struct ospf6_lsdb *lsdb);
extern struct ospf6_lsa *ospf6_lsdb_type_next (u_int16_t type,
struct ospf6_lsa *lsa);
#define ALL_LSDB_TYPED(lsdb, type, lsa) \
lsa = ospf6_lsdb_type_head(type, lsdb); lsa; \
lsa = ospf6_lsdb_type_next(type, lsa)
const struct route_node *iterend = \
ospf6_lsdb_head(lsdb, 1, type, 0, &lsa); \
lsa; \
lsa = ospf6_lsdb_next(iterend, lsa)
#define ALL_LSDB(lsdb, lsa) \
const struct route_node *iterend = \
ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa); \
lsa; \
lsa = ospf6_lsdb_next(iterend, lsa)
extern void ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb);
extern void ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa);