mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-30 16:33:58 +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
|
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);
|
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;
|
return (struct ospf6_lsa *) node->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iteration function */
|
const struct route_node *
|
||||||
struct ospf6_lsa *
|
ospf6_lsdb_head (struct ospf6_lsdb *lsdb,
|
||||||
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);
|
*lsa = NULL;
|
||||||
if (node == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* skip to the existing lsdb entry */
|
if (argmode > 0)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
next = node->info;
|
struct prefix_ipv6 key = { .family = AF_INET6, .prefixlen = 0 };
|
||||||
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));
|
ospf6_lsdb_set_key (&key, &type, sizeof (type));
|
||||||
|
if (argmode > 1)
|
||||||
ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
|
ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
|
||||||
|
|
||||||
node = lsdb->table->top;
|
node = route_table_get_next (lsdb->table, &key);
|
||||||
|
if (!node || !prefix_match((struct prefix *)&key, &node->p))
|
||||||
/* 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)
|
|
||||||
return NULL;
|
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;
|
return NULL;
|
||||||
|
if (!node->info)
|
||||||
|
{
|
||||||
|
route_unlock_node(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
lsa = node->info;
|
*lsa = node->info;
|
||||||
ospf6_lsa_lock (lsa);
|
ospf6_lsa_lock (*lsa);
|
||||||
|
|
||||||
return lsa;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ospf6_lsa *
|
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 *lsa)
|
||||||
{
|
{
|
||||||
struct ospf6_lsa *next = ospf6_lsdb_next(lsa);
|
struct route_node *node = lsa->rn;
|
||||||
|
|
||||||
if (next)
|
ospf6_lsa_unlock(lsa);
|
||||||
{
|
|
||||||
if (next->header->type != type ||
|
|
||||||
next->header->adv_router != adv_router)
|
|
||||||
{
|
|
||||||
route_unlock_node (next->rn);
|
|
||||||
ospf6_lsa_unlock (next);
|
|
||||||
next = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
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)
|
if (node)
|
||||||
route_lock_node (node);
|
route_unlock_node (node);
|
||||||
while (node && node->info == NULL)
|
|
||||||
node = route_next (node);
|
|
||||||
|
|
||||||
if (node == NULL)
|
|
||||||
return NULL;
|
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
|
void
|
||||||
@ -492,6 +417,7 @@ ospf6_lsdb_show (struct vty *vty, enum ospf_lsdb_show_level level,
|
|||||||
struct ospf6_lsdb *lsdb)
|
struct ospf6_lsdb *lsdb)
|
||||||
{
|
{
|
||||||
struct ospf6_lsa *lsa;
|
struct ospf6_lsa *lsa;
|
||||||
|
const struct route_node *end = NULL;
|
||||||
void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
|
void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
|
||||||
|
|
||||||
switch (level)
|
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)
|
if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
|
||||||
ospf6_lsa_show_summary_header (vty);
|
ospf6_lsa_show_summary_header (vty);
|
||||||
|
|
||||||
if (type && adv_router)
|
end = ospf6_lsdb_head(lsdb, !!type + !!(type && adv_router),
|
||||||
lsa = ospf6_lsdb_type_router_head (*type, *adv_router, lsdb);
|
*type, *adv_router, &lsa);
|
||||||
else if (type)
|
|
||||||
lsa = ospf6_lsdb_type_head (*type, lsdb);
|
|
||||||
else
|
|
||||||
lsa = ospf6_lsdb_head (lsdb);
|
|
||||||
while (lsa)
|
while (lsa)
|
||||||
{
|
{
|
||||||
if ((! adv_router || lsa->header->adv_router == *adv_router) &&
|
if ((! adv_router || lsa->header->adv_router == *adv_router) &&
|
||||||
(! id || lsa->header->id == *id))
|
(! id || lsa->header->id == *id))
|
||||||
(*showfunc) (vty, lsa);
|
(*showfunc) (vty, lsa);
|
||||||
|
|
||||||
if (type && adv_router)
|
lsa = ospf6_lsdb_next (end, lsa);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb);
|
||||||
extern void ospf6_lsdb_remove (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 const struct route_node *ospf6_lsdb_head (
|
||||||
extern struct ospf6_lsa *ospf6_lsdb_next (struct ospf6_lsa *lsa);
|
struct ospf6_lsdb *lsdb,
|
||||||
#define ALL_LSDB(lsdb, lsa) \
|
int argmode,
|
||||||
lsa = ospf6_lsdb_head(lsdb); lsa; \
|
uint16_t type,
|
||||||
lsa = ospf6_lsdb_next(lsa)
|
uint32_t adv_router,
|
||||||
|
struct ospf6_lsa **lsa);
|
||||||
extern struct ospf6_lsa *ospf6_lsdb_type_router_head (u_int16_t type,
|
extern struct ospf6_lsa *ospf6_lsdb_next (const struct route_node *iterend,
|
||||||
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,
|
|
||||||
struct ospf6_lsa *lsa);
|
struct ospf6_lsa *lsa);
|
||||||
|
|
||||||
#define ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa) \
|
#define ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa) \
|
||||||
lsa = ospf6_lsdb_type_router_head(type, adv_router, lsdb); lsa; \
|
const struct route_node *iterend = \
|
||||||
lsa = ospf6_lsdb_type_router_next(type, adv_router, lsa)
|
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) \
|
#define ALL_LSDB_TYPED(lsdb, type, lsa) \
|
||||||
lsa = ospf6_lsdb_type_head(type, lsdb); lsa; \
|
const struct route_node *iterend = \
|
||||||
lsa = ospf6_lsdb_type_next(type, lsa)
|
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_remove_all (struct ospf6_lsdb *lsdb);
|
||||||
extern void ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa);
|
extern void ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa);
|
||||||
|
Loading…
Reference in New Issue
Block a user