}
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);
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;
-
- /* skip to the existing lsdb entry */
- while (node && node->info == NULL)
- node = route_next (node);
- if (node == NULL)
- return NULL;
+ *lsa = NULL;
- if (node->info)
- ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
- return (struct ospf6_lsa *) node->info;
-}
+ if (argmode > 0)
+ {
+ struct prefix_ipv6 key = { .family = AF_INET6, .prefixlen = 0 };
-struct ospf6_lsa *
-ospf6_lsdb_next (struct ospf6_lsa *lsa)
-{
- struct route_node *node = lsa->rn;
- struct ospf6_lsa *next = NULL;
+ ospf6_lsdb_set_key (&key, &type, sizeof (type));
+ if (argmode > 1)
+ ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
- do {
- node = route_next (node);
- } while (node && node->info == NULL);
+ node = route_table_get_next (lsdb->table, &key);
+ if (!node || !prefix_match((struct prefix *)&key, &node->p))
+ return NULL;
- if ((node != NULL) && (node->info != NULL))
+ for (end = node;
+ end && end->parent && end->parent->p.prefixlen >= key.prefixlen;
+ end = end->parent)
+ ;
+ }
+ else
{
- next = node->info;
- ospf6_lsa_lock (next);
+ node = route_top (lsdb->table);
+ end = NULL;
}
- ospf6_lsa_unlock (lsa);
- return next;
-}
+ while (node && !node->info)
+ node = route_next_until(node, end);
-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, &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)
- return NULL;
-
- if (! prefix_match ((struct prefix *) &key, &node->p))
+ if (!node)
return NULL;
-
- lsa = node->info;
- ospf6_lsa_lock (lsa);
-
- return lsa;
-}
-
-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 = ospf6_lsdb_next(lsa);
-
- if (next)
+ if (!node->info)
{
- if (next->header->type != type ||
- next->header->adv_router != adv_router)
- {
- route_unlock_node (next->rn);
- ospf6_lsa_unlock (next);
- next = NULL;
- }
+ route_unlock_node(node);
+ return NULL;
}
- return next;
+ *lsa = node->info;
+ ospf6_lsa_lock (*lsa);
+
+ return end;
}
struct ospf6_lsa *
-ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
+ospf6_lsdb_next (const struct route_node *iterend,
+ struct ospf6_lsa *lsa)
{
- 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)
- return NULL;
+ struct route_node *node = lsa->rn;
- if (! prefix_match ((struct prefix *) &key, &node->p))
- return NULL;
+ ospf6_lsa_unlock(lsa);
- lsa = node->info;
- ospf6_lsa_lock (lsa);
-
- return lsa;
-}
+ do
+ node = route_next_until(node, iterend);
+ while (node && !node->info);
-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 (node && node->info)
{
- if (next->header->type != type)
- {
- route_unlock_node (next->rn);
- ospf6_lsa_unlock (next);
- next = NULL;
- }
+ struct ospf6_lsa *next = node->info;
+ ospf6_lsa_lock (next);
+ return next;
}
- return next;
+ if (node)
+ route_unlock_node (node);
+ return NULL;
}
void
struct ospf6_lsdb *lsdb)
{
struct ospf6_lsa *lsa;
+ const struct route_node *end = NULL;
void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
switch (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);
}
}
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 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);
-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,
- 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);