]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: rewrite LSDB iteration
authorDavid Lamparter <equinox@opensourcerouting.org>
Thu, 6 Jul 2017 13:02:31 +0000 (15:02 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Tue, 11 Jul 2017 13:05:39 +0000 (15:05 +0200)
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>
ospf6d/ospf6_lsdb.c
ospf6d/ospf6_lsdb.h

index 6879d71a167f51b1a8f099d6e62762b467af4f81..26b8724dea4d992c151aef91d8ecf5b42d2875e5 100644 (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;
-
-  /* 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
@@ -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);
     }
 }
 
index 529fbefba6db3945696c1a646c061d80df8bd0e4..0eb5322b41e29c5907c7cc9d8ffbeed9001c8e72 100644 (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 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);