mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 14:33:09 +00:00
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:
parent
f1c73d1495
commit
954306f70c
@ -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)
|
||||
if (argmode > 0)
|
||||
{
|
||||
struct route_node *node = lsa->rn;
|
||||
struct ospf6_lsa *next = NULL;
|
||||
struct prefix_ipv6 key = { .family = AF_INET6, .prefixlen = 0 };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user