summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_lsdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_lsdb.c')
-rw-r--r--ospf6d/ospf6_lsdb.c843
1 files changed, 264 insertions, 579 deletions
diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c
index ad53eb4f..97a278e9 100644
--- a/ospf6d/ospf6_lsdb.c
+++ b/ospf6d/ospf6_lsdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Yasuhiro Ohara
+ * Copyright (C) 2003 Yasuhiro Ohara
*
* This file is part of GNU Zebra.
*
@@ -24,24 +24,14 @@
#include "memory.h"
#include "log.h"
#include "command.h"
-#include "if.h"
+#include "prefix.h"
+#include "table.h"
-#include "ospf6_dump.h"
+#include "ospf6d.h"
+#include "ospf6_proto.h"
+#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
-#include "ospf6_interface.h"
-#include "ospf6_area.h"
-#include "ospf6_top.h"
-
-#define OSPF6_LSDB_MATCH_TYPE 0x01
-#define OSPF6_LSDB_MATCH_ID 0x02
-#define OSPF6_LSDB_MATCH_ADV_ROUTER 0x04
-#define OSPF6_LSDB_SHOW_DUMP 0x08
-#define OSPF6_LSDB_SHOW_DETAIL 0x10
-
-struct ospf6_lsdb_hook_t hooks[0x2000];
-struct ospf6_lsdb_hook_t *ospf6_lsdb_hook = hooks;
-
struct ospf6_lsdb *
ospf6_lsdb_create ()
{
@@ -68,656 +58,351 @@ ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
}
static void
-ospf6_lsdb_set_key (struct prefix_ipv6 *key, int flag,
- u_int16_t type, u_int32_t id, u_int32_t adv_router)
+ospf6_lsdb_set_key (struct prefix_ipv6 *key, void *value, int len)
{
- int len = 0;
- memset (key, 0, sizeof (struct prefix_ipv6));
+ assert (key->prefixlen % 8 == 0);
- if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_TYPE))
- {
- len += 2;
- if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER))
- {
- len += 4;
- if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ID))
- len += 4;
- }
- }
+ memcpy ((caddr_t) &key->prefix + key->prefixlen / 8,
+ (caddr_t) value, len);
+ key->family = AF_INET6;
+ key->prefixlen += len * 8;
+}
- if (len > 0)
- memcpy ((char *)&key->prefix, &type, 2);
- if (len > 2)
- memcpy ((char *)&key->prefix + 2, &adv_router, 4);
- if (len > 6)
- memcpy ((char *)&key->prefix + 6, &id, 4);
+#ifndef NDEBUG
+static void
+_lsdb_count_assert (struct ospf6_lsdb *lsdb)
+{
+ struct ospf6_lsa *debug;
+ int num = 0;
+ for (debug = ospf6_lsdb_head (lsdb); debug;
+ debug = ospf6_lsdb_next (debug))
+ num++;
- key->family = AF_INET6;
- key->prefixlen = len * 8;
+ if (num == lsdb->count)
+ return;
+
+ if (IS_OSPF6_DEBUG_LSA (DATABASE))
+ {
+ zlog_info ("PANIC !! lsdb[%p]->count = %d, real = %d",
+ lsdb, lsdb->count, num);
+ for (debug = ospf6_lsdb_head (lsdb); debug;
+ debug = ospf6_lsdb_next (debug))
+ zlog_info ("%p %p %s", debug->prev, debug->next, debug->name);
+ zlog_info ("DUMP END");
+ }
+ assert (num == lsdb->count);
}
+#define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
+#else /*NDEBUG*/
+#define ospf6_lsdb_count_assert(t) ((void) 0)
+#endif /*NDEBUG*/
void
ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
{
- int flag;
struct prefix_ipv6 key;
- struct route_node *rn;
- struct ospf6_lsa *old = NULL;
-
- flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |
- OSPF6_LSDB_MATCH_ADV_ROUTER;
- ospf6_lsdb_set_key (&key, flag, lsa->header->type, lsa->header->id,
- lsa->header->adv_router);
-
- rn = route_node_get (lsdb->table, (struct prefix *) &key);
- if (rn->info)
- old = rn->info;
- rn->info = lsa;
+ struct route_node *current, *nextnode, *prevnode;
+ struct ospf6_lsa *next, *prev, *old = NULL;
+
+ memset (&key, 0, sizeof (key));
+ ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
+ ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
+ sizeof (lsa->header->adv_router));
+ ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
+
+ current = route_node_get (lsdb->table, (struct prefix *) &key);
+ old = current->info;
+ current->info = lsa;
ospf6_lsa_lock (lsa);
if (old)
- ospf6_lsa_unlock (old);
+ {
+ if (old->prev)
+ old->prev->next = lsa;
+ if (old->next)
+ old->next->prev = lsa;
+ lsa->next = old->next;
+ lsa->prev = old->prev;
+ }
else
- lsdb->count++;
-}
+ {
+ /* next link */
+ nextnode = current;
+ route_lock_node (nextnode);
+ do {
+ nextnode = route_next (nextnode);
+ } while (nextnode && nextnode->info == NULL);
+ if (nextnode == NULL)
+ lsa->next = NULL;
+ else
+ {
+ next = nextnode->info;
+ lsa->next = next;
+ next->prev = lsa;
+ route_unlock_node (nextnode);
+ }
-void
-ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
-{
- int flag;
- struct prefix_ipv6 key;
- struct route_node *rn;
- struct ospf6_lsa *old;
+ /* prev link */
+ prevnode = current;
+ route_lock_node (prevnode);
+ do {
+ prevnode = route_prev (prevnode);
+ } while (prevnode && prevnode->info == NULL);
+ if (prevnode == NULL)
+ lsa->prev = NULL;
+ else
+ {
+ prev = prevnode->info;
+ lsa->prev = prev;
+ prev->next = lsa;
+ route_unlock_node (prevnode);
+ }
- flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |
- OSPF6_LSDB_MATCH_ADV_ROUTER;
- ospf6_lsdb_set_key (&key, flag, lsa->header->type, lsa->header->id,
- lsa->header->adv_router);
+ lsdb->count++;
+ }
- rn = route_node_lookup (lsdb->table, (struct prefix *) &key);
- if (! rn || ! rn->info)
+ if (old)
{
- zlog_warn ("LSDB: Can't remove: no such LSA: %s", lsa->str);
- return;
+ if (OSPF6_LSA_IS_CHANGED (old, lsa))
+ {
+ if (OSPF6_LSA_IS_MAXAGE (lsa))
+ {
+ if (lsdb->hook_remove)
+ {
+ (*lsdb->hook_remove) (old);
+ (*lsdb->hook_remove) (lsa);
+ }
+ }
+ else
+ {
+ if (lsdb->hook_remove)
+ (*lsdb->hook_remove) (old);
+ if (lsdb->hook_add)
+ (*lsdb->hook_add) (lsa);
+ }
+ }
}
-
- old = rn->info;
- if (old != lsa)
+ else if (OSPF6_LSA_IS_MAXAGE (lsa))
{
- zlog_warn ("LSDB: Can't remove: different instance: %s (%p <-> %p) %s",
- lsa->str, lsa, old, old->str);
- return;
+ if (lsdb->hook_remove)
+ (*lsdb->hook_remove) (lsa);
+ }
+ else
+ {
+ if (lsdb->hook_add)
+ (*lsdb->hook_add) (lsa);
}
- rn->info = NULL;
- ospf6_lsa_unlock (old);
- lsdb->count--;
-}
-
-static void
-ospf6_lsdb_lookup_node (struct ospf6_lsdb_node *node,
- u_int16_t type, u_int32_t id, u_int32_t adv_router,
- struct ospf6_lsdb *lsdb)
-{
- int flag;
- struct route_node *rn;
-
- memset (node, 0, sizeof (struct ospf6_lsdb_node));
-
- flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |
- OSPF6_LSDB_MATCH_ADV_ROUTER;
- ospf6_lsdb_set_key (&node->key, flag, type, id, adv_router);
-
- rn = route_node_lookup (lsdb->table, (struct prefix *) &node->key);
- if (! rn || ! rn->info)
- return;
+ if (old)
+ ospf6_lsa_unlock (old);
- node->node = rn;
- node->next = route_next (rn);
- node->lsa = rn->info;
- if (node->next != NULL)
- route_unlock_node (node->next);
+ ospf6_lsdb_count_assert (lsdb);
}
-struct ospf6_lsa *
-ospf6_lsdb_lookup_lsdb (u_int16_t type, u_int32_t id, u_int32_t adv_router,
- struct ospf6_lsdb *lsdb)
-{
- struct ospf6_lsdb_node node;
- ospf6_lsdb_lookup_node (&node, type, id, adv_router, lsdb);
- return node.lsa;
-}
-
-/* Iteration function */
void
-ospf6_lsdb_head (struct ospf6_lsdb_node *node, struct ospf6_lsdb *lsdb)
+ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
{
- struct route_node *rn;
-
- memset (node, 0, sizeof (struct ospf6_lsdb_node));
-
- rn = route_top (lsdb->table);
- if (rn == NULL)
- return;
-
- while (rn && rn->info == NULL)
- rn = route_next (rn);
-
- if (rn && rn->info)
- {
- node->node = rn;
- node->next = route_next (rn);
- node->lsa = rn->info;
- if (node->next != NULL)
- route_unlock_node (node->next);
- }
-}
+ struct route_node *node;
+ struct prefix_ipv6 key;
-void
-ospf6_lsdb_type (struct ospf6_lsdb_node *node, u_int16_t type,
- struct ospf6_lsdb *lsdb)
-{
- int flag;
- struct route_node *rn;
+ memset (&key, 0, sizeof (key));
+ ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
+ ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
+ sizeof (lsa->header->adv_router));
+ ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
- memset (node, 0, sizeof (struct ospf6_lsdb_node));
+ node = route_node_lookup (lsdb->table, (struct prefix *) &key);
+ assert (node && node->info == lsa);
- flag = OSPF6_LSDB_MATCH_TYPE;
- ospf6_lsdb_set_key (&node->key, flag, type, 0, 0);
+ if (lsa->prev)
+ lsa->prev->next = lsa->next;
+ if (lsa->next)
+ lsa->next->prev = lsa->prev;
- /* get the closest radix node */
- rn = route_node_get (lsdb->table, (struct prefix *) &node->key);
+ node->info = NULL;
+ lsdb->count--;
- /* skip to the real existing lsdb entry */
- while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&
- prefix_match ((struct prefix *) &node->key, &rn->p))
- rn = route_next (rn);
+ if (lsdb->hook_remove)
+ (*lsdb->hook_remove) (lsa);
- if (rn && rn->info)
- {
- node->node = rn;
- node->next = route_next (rn);
- node->lsa = rn->info;
- if (node->next != NULL)
- route_unlock_node (node->next);
- }
+ ospf6_lsa_unlock (lsa);
+ route_unlock_node (node);
+ ospf6_lsdb_count_assert (lsdb);
}
-void
-ospf6_lsdb_type_router (struct ospf6_lsdb_node *node,
- u_int16_t type, u_int32_t adv_router,
- struct ospf6_lsdb *lsdb)
+struct ospf6_lsa *
+ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
+ struct ospf6_lsdb *lsdb)
{
- int flag;
- struct route_node *rn;
-
- memset (node, 0, sizeof (struct ospf6_lsdb_node));
-
- flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ADV_ROUTER;
- ospf6_lsdb_set_key (&node->key, flag, type, 0, adv_router);
+ struct route_node *node;
+ struct prefix_ipv6 key;
- /* get the closest radix node */
- rn = route_node_get (lsdb->table, (struct prefix *) &node->key);
+ if (lsdb == NULL)
+ return NULL;
- /* skip to the real existing lsdb entry */
- while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&
- prefix_match ((struct prefix *) &node->key, &rn->p))
- rn = route_next (rn);
+ memset (&key, 0, sizeof (key));
+ ospf6_lsdb_set_key (&key, &type, sizeof (type));
+ ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
+ ospf6_lsdb_set_key (&key, &id, sizeof (id));
- if (rn && rn->info)
- {
- node->node = rn;
- node->next = route_next (rn);
- node->lsa = rn->info;
- if (node->next != NULL)
- route_unlock_node (node->next);
- }
+ node = route_node_lookup (lsdb->table, (struct prefix *) &key);
+ if (node == NULL || node->info == NULL)
+ return NULL;
+ return (struct ospf6_lsa *) node->info;
}
-void
-ospf6_lsdb_next (struct ospf6_lsdb_node *node)
+/* Iteration function */
+struct ospf6_lsa *
+ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
{
- struct route_node *rn;
-
- route_lock_node (node->node);
- rn = route_next (node->node);
-
- /* skip to the real existing lsdb entry */
- while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&
- prefix_match ((struct prefix *) &node->key, &rn->p))
- rn = route_next (rn);
-
- if (rn && rn->info && rn->p.prefixlen >= node->key.prefixlen &&
- prefix_match ((struct prefix *) &node->key, &rn->p))
- {
- node->node = rn;
- node->next = route_next (rn);
- node->lsa = rn->info;
- if (node->next != NULL)
- route_unlock_node (node->next);
- }
- else
- {
- node->node = NULL;
- node->next = NULL;
- node->lsa = NULL;
- }
+ struct route_node *node;
+
+ 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;
+
+ route_unlock_node (node);
+ if (node->info)
+ ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
+ return (struct ospf6_lsa *) node->info;
}
struct ospf6_lsa *
-ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
- void *scope)
+ospf6_lsdb_next (struct ospf6_lsa *lsa)
{
- struct ospf6_interface *o6i;
- struct ospf6_area *o6a;
- listnode i, j;
+ struct ospf6_lsa *next = lsa->next;
- if (scope == (void *) ospf6)
- return ospf6_lsdb_lookup_lsdb (type, id, adv_router, ospf6->lsdb);
+ ospf6_lsa_unlock (lsa);
+ if (next)
+ ospf6_lsa_lock (next);
- for (i = listhead (ospf6->area_list); i; nextnode (i))
- {
- o6a = getdata (i);
-
- if (scope == (void *) o6a)
- return ospf6_lsdb_lookup_lsdb (type, id, adv_router, o6a->lsdb);
-
- for (j = listhead (o6a->if_list); j; nextnode (j))
- {
- o6i = getdata (j);
-
- if (scope == (void *) o6i)
- return ospf6_lsdb_lookup_lsdb (type, id, adv_router, o6i->lsdb);
- }
- }
-
- zlog_warn ("LSDB: Can't lookup: unknown scope, type %#hx", ntohs (type));
- return NULL;
+ return next;
}
-void
-ospf6_lsdb_install (struct ospf6_lsa *new)
-{
- struct ospf6_lsdb *lsdb;
- struct ospf6_lsa *old;
- int need_hook = 0;
- void (*hook) (struct ospf6_lsa *, struct ospf6_lsa *);
-
- struct ospf6 *as = NULL;
- struct ospf6_area *area = NULL;
- struct ospf6_interface *linklocal = NULL;
- hook = NULL;
+/* Macro version of check_bit (). */
+#define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
- switch (ntohs (new->header->type) & OSPF6_LSTYPE_SCOPE_MASK)
- {
- case OSPF6_LSA_SCOPE_LINKLOCAL:
- linklocal = (struct ospf6_interface *) new->scope;
- lsdb = linklocal->lsdb;
- break;
- case OSPF6_LSA_SCOPE_AREA:
- area = (struct ospf6_area *) new->scope;
- lsdb = area->lsdb;
- break;
- case OSPF6_LSA_SCOPE_AS:
- as = (struct ospf6 *) new->scope;
- lsdb = as->lsdb;
- break;
- default:
- zlog_warn ("LSDB: Can't install: scope unknown: %s", new->str);
- return;
- }
+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;
- /* whether schedule calculation or not */
- old = ospf6_lsdb_lookup_lsdb (new->header->type, new->header->id,
- new->header->adv_router, lsdb);
+ memset (&key, 0, sizeof (key));
+ ospf6_lsdb_set_key (&key, &type, sizeof (type));
+ ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
- if (! old || ospf6_lsa_differ (old, new))
- need_hook++;
+ node = lsdb->table->top;
- /* log */
- if (IS_OSPF6_DUMP_LSDB)
- zlog_info ("LSDB: Install: %s %s", new->str,
- ((IS_LSA_MAXAGE (new)) ? "(MaxAge)" : ""));
+ /* Walk down tree. */
+ while (node && node->p.prefixlen <= key.prefixlen &&
+ prefix_match (&node->p, (struct prefix *) &key))
+ node = node->link[CHECK_BIT(&key.prefix, node->p.prefixlen)];
- if (old)
- ospf6_lsa_lock (old);
+ if (node)
+ route_lock_node (node);
+ while (node && node->info == NULL)
+ node = route_next (node);
- ospf6_lsdb_add (new, lsdb);
- gettimeofday (&new->installed, NULL);
+ if (node == NULL)
+ return NULL;
+ else
+ route_unlock_node (node);
- hook = ospf6_lsdb_hook[ntohs (new->header->type) &
- OSPF6_LSTYPE_CODE_MASK].hook;
- if (need_hook && hook)
- (*hook) (old, new);
+ if (! prefix_match ((struct prefix *) &key, &node->p))
+ return NULL;
- /* old LSA should be freed here */
- if (old)
- ospf6_lsa_unlock (old);
-}
+ lsa = node->info;
+ ospf6_lsa_lock (lsa);
-void
-ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
-{
- struct ospf6_lsdb_node node;
- for (ospf6_lsdb_head (&node, lsdb); ! ospf6_lsdb_is_end (&node);
- ospf6_lsdb_next (&node))
- ospf6_lsdb_remove (node.lsa, lsdb);
+ return lsa;
}
-void
-ospf6_lsdb_remove_maxage (struct ospf6_lsdb *lsdb)
+struct ospf6_lsa *
+ospf6_lsdb_type_router_next (u_int16_t type, u_int32_t adv_router,
+ struct ospf6_lsa *lsa)
{
- struct ospf6_lsdb_node node;
- struct ospf6_lsa *lsa;
+ struct ospf6_lsa *next = lsa->next;
- for (ospf6_lsdb_head (&node, lsdb); ! ospf6_lsdb_is_end (&node);
- ospf6_lsdb_next (&node))
+ if (next)
{
- lsa = node.lsa;
-
- /* contiue if it's not MaxAge */
- if (! IS_LSA_MAXAGE (lsa))
- continue;
-
- /* continue if it's referenced by some retrans-lists */
- if (lsa->lock != 1)
- continue;
-
- if (IS_OSPF6_DUMP_LSDB)
- zlog_info ("Remove MaxAge LSA: %s", lsa->str);
-
- ospf6_lsdb_remove (lsa, lsdb);
+ if (next->header->type != type ||
+ next->header->adv_router != adv_router)
+ next = NULL;
}
-}
-
-
-
-/* vty functions */
-
-static int
-ospf6_lsdb_match (int flag, u_int16_t type, u_int32_t id,
- u_int32_t adv_router, struct ospf6_lsa *lsa)
-{
- if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_TYPE) &&
- lsa->header->type != type)
- return 0;
- if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ID) &&
- lsa->header->id != id)
- return 0;
-
- if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER) &&
- lsa->header->adv_router != adv_router)
- return 0;
-
- return 1;
+ if (next)
+ ospf6_lsa_lock (next);
+ ospf6_lsa_unlock (lsa);
+ return next;
}
-int
-show_ipv6_ospf6_lsdb (struct vty *vty, int argc, char **argv,
- struct ospf6_lsdb *lsdb)
+struct ospf6_lsa *
+ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
{
- u_int flag;
- u_int16_t type = 0;
- u_int32_t id, adv_router;
- int ret;
- struct ospf6_lsdb_node node;
- char invalid[32], *invalidp;
- int l_argc = argc;
- char **l_argv = argv;
-
- flag = 0;
- memset (invalid, 0, sizeof (invalid));
- invalidp = invalid;
-
- /* chop tail if the words is 'dump' or 'summary' */
- if (l_argc > 0 && ! strcmp (l_argv[l_argc - 1], "dump"))
- {
- SET_FLAG (flag, OSPF6_LSDB_SHOW_DUMP);
- l_argc --;
- }
- else if (l_argc > 0 && ! strcmp (l_argv[l_argc - 1], "detail"))
- {
- SET_FLAG (flag, OSPF6_LSDB_SHOW_DETAIL);
- l_argc --;
- }
+ struct route_node *node;
+ struct prefix_ipv6 key;
+ struct ospf6_lsa *lsa;
- if (l_argc > 0)
- {
- SET_FLAG (flag, OSPF6_LSDB_MATCH_TYPE);
- if (! strncmp (l_argv[0], "r", 1))
- type = htons (OSPF6_LSA_TYPE_ROUTER);
- if (! strncmp (l_argv[0], "n", 1))
- type = htons (OSPF6_LSA_TYPE_NETWORK);
- if (! strncmp (l_argv[0], "a", 1))
- type = htons (OSPF6_LSA_TYPE_AS_EXTERNAL);
- if (! strcmp (l_argv[0], "intra-prefix"))
- type = htons (OSPF6_LSA_TYPE_INTRA_PREFIX);
- if (! strcmp (l_argv[0], "inter-router"))
- type = htons (OSPF6_LSA_TYPE_INTER_ROUTER);
- if (! strcmp (l_argv[0], "inter-prefix"))
- type = htons (OSPF6_LSA_TYPE_INTER_PREFIX);
- if (! strncmp (l_argv[0], "l", 1))
- type = htons (OSPF6_LSA_TYPE_LINK);
- if (! strncmp (l_argv[0], "0x", 2) && strlen (l_argv[0]) == 6)
- type = htons ((short) strtol (l_argv[0], (char **)NULL, 16));
- if (! strncmp (l_argv[0], "*", 1))
- UNSET_FLAG (flag, OSPF6_LSDB_MATCH_TYPE);
- }
+ memset (&key, 0, sizeof (key));
+ ospf6_lsdb_set_key (&key, &type, sizeof (type));
- if (l_argc > 1)
- {
- SET_FLAG (flag, OSPF6_LSDB_MATCH_ID);
- if (! strncmp (l_argv[1], "*", 1))
- UNSET_FLAG (flag, OSPF6_LSDB_MATCH_ID);
- else
- {
- ret = inet_pton (AF_INET, l_argv[1], &id);
- if (ret != 1)
- {
- id = htonl (strtoul (l_argv[1], &invalidp, 10));
- if (invalid[0] != '\0')
- {
- vty_out (vty, "Link State ID is not parsable: %s%s",
- l_argv[1], VTY_NEWLINE);
- return CMD_SUCCESS;
- }
- }
- }
- }
+ /* Walk down tree. */
+ node = lsdb->table->top;
+ while (node && node->p.prefixlen <= key.prefixlen &&
+ prefix_match (&node->p, (struct prefix *) &key))
+ node = node->link[CHECK_BIT(&key.prefix, node->p.prefixlen)];
- if (l_argc > 2)
- {
- SET_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER);
- if (! strncmp (l_argv[2], "*", 1))
- UNSET_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER);
- else
- {
- ret = inet_pton (AF_INET, l_argv[2], &adv_router);
- if (ret != 1)
- {
- adv_router = htonl (strtoul (l_argv[2], &invalidp, 10));
- if (invalid[0] != '\0')
- {
- vty_out (vty, "Advertising Router is not parsable: %s%s",
- l_argv[2], VTY_NEWLINE);
- return CMD_SUCCESS;
- }
- }
- }
- }
+ if (node)
+ route_lock_node (node);
+ while (node && node->info == NULL)
+ node = route_next (node);
- if (! CHECK_FLAG (flag, OSPF6_LSDB_SHOW_DETAIL))
- ospf6_lsa_show_summary_header (vty);
+ if (node == NULL)
+ return NULL;
+ else
+ route_unlock_node (node);
- for (ospf6_lsdb_head (&node, lsdb); ! ospf6_lsdb_is_end (&node);
- ospf6_lsdb_next (&node))
- {
- if (! ospf6_lsdb_match (flag, type, id, adv_router, node.lsa))
- continue;
+ if (! prefix_match ((struct prefix *) &key, &node->p))
+ return NULL;
- if (CHECK_FLAG (flag, OSPF6_LSDB_SHOW_DUMP))
- ospf6_lsa_show_dump (vty, node.lsa);
- else if (CHECK_FLAG (flag, OSPF6_LSDB_SHOW_DETAIL))
- ospf6_lsa_show (vty, node.lsa);
- else
- ospf6_lsa_show_summary (vty, node.lsa);
- }
+ lsa = node->info;
+ ospf6_lsa_lock (lsa);
- return CMD_SUCCESS;
+ return lsa;
}
-DEFUN (show_ipv6_ospf6_database,
- show_ipv6_ospf6_database_cmd,
- "show ipv6 ospf6 database",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "LSA Database\n"
- )
+struct ospf6_lsa *
+ospf6_lsdb_type_next (u_int16_t type, struct ospf6_lsa *lsa)
{
- struct ospf6_area *o6a;
- struct ospf6_interface *o6i;
- listnode i, j;
-
- /* call show function for each of LSAs in the LSDBs */
+ struct ospf6_lsa *next = lsa->next;
- for (i = listhead (ospf6->area_list); i; nextnode (i))
+ if (next)
{
- o6a = (struct ospf6_area *) getdata (i);
-
- /* LinkLocal LSDBs */
- for (j = listhead (o6a->if_list); j; nextnode (j))
- {
- o6i = (struct ospf6_interface *) getdata (j);
-
- vty_out (vty, "%s", VTY_NEWLINE);
- vty_out (vty, " Interface %s (Area: %s):%s",
- o6i->interface->name, o6a->str, VTY_NEWLINE);
- vty_out (vty, "%s", VTY_NEWLINE);
- show_ipv6_ospf6_lsdb (vty, argc, argv, o6i->lsdb);
- }
-
- /* Area LSDBs */
- vty_out (vty, "%s", VTY_NEWLINE);
- vty_out (vty, " Area %s:%s", o6a->str, VTY_NEWLINE);
- vty_out (vty, "%s", VTY_NEWLINE);
- show_ipv6_ospf6_lsdb (vty, argc, argv, o6a->lsdb);
+ if (next->header->type != type)
+ next = NULL;
}
- /* AS LSDBs */
- vty_out (vty, "%s", VTY_NEWLINE);
- vty_out (vty, " AS:%s", VTY_NEWLINE);
- vty_out (vty, "%s", VTY_NEWLINE);
- show_ipv6_ospf6_lsdb (vty, argc, argv, ospf6->lsdb);
-
- return CMD_SUCCESS;
+ if (next)
+ ospf6_lsa_lock (next);
+ ospf6_lsa_unlock (lsa);
+ return next;
}
-ALIAS (show_ipv6_ospf6_database,
- show_ipv6_ospf6_database_type_cmd,
- "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX|dump|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "LSA Database\n"
- "Router-LSA\n"
- "Network-LSA\n"
- "AS-External-LSA\n"
- "Intra-Area-Prefix-LSA\n"
- "Inter-Area-Router-LSA\n"
- "Inter-Area-Prefix-LSA\n"
- "Link-LSA\n"
- "All LS Type\n"
- "Specify LS Type by Hex\n"
- "Dump raw LSA data in Hex\n"
- "show detail of LSAs\n"
- )
-
-ALIAS (show_ipv6_ospf6_database,
- show_ipv6_ospf6_database_type_id_cmd,
- "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX) (A.B.C.D|*|dump|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "LSA Database\n"
- "Router-LSA\n"
- "Network-LSA\n"
- "AS-External-LSA\n"
- "Intra-Area-Prefix-LSA\n"
- "Inter-Area-Router-LSA\n"
- "Inter-Area-Prefix-LSA\n"
- "Link-LSA\n"
- "All LS Type\n"
- "Specify LS Type by Hex\n"
- "Link State ID\n"
- "All Link State ID\n"
- "Dump raw LSA data in Hex\n"
- "show detail of LSAs\n"
- )
-
-ALIAS (show_ipv6_ospf6_database,
- show_ipv6_ospf6_database_type_id_adv_router_cmd,
- "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX) (A.B.C.D|*) (A.B.C.D|*|dump|detail)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "LSA Database\n"
- "Router-LSA\n"
- "Network-LSA\n"
- "AS-External-LSA\n"
- "Intra-Area-Prefix-LSA\n"
- "Inter-Area-Router-LSA\n"
- "Inter-Area-Prefix-LSA\n"
- "Link-LSA\n"
- "All LS Type\n"
- "Specify LS Type by Hex\n"
- "Link State ID\n"
- "All Link State ID\n"
- "Advertising Router\n"
- "All Advertising Router\n"
- "Dump raw LSA data in Hex\n"
- "show detail of LSAs\n"
- )
-
-ALIAS (show_ipv6_ospf6_database,
- show_ipv6_ospf6_database_type_id_adv_router_dump_cmd,
- "show ipv6 ospf6 database (router|network|as-external|intra-prefix|inter-prefix|inter-router|link|*|HEX) (A.B.C.D|*) (A.B.C.D|*) (dump|detail|)",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- "LSA Database\n"
- "Router-LSA\n"
- "Network-LSA\n"
- "AS-External-LSA\n"
- "Intra-Area-Prefix-LSA\n"
- "Inter-Area-Router-LSA\n"
- "Inter-Area-Prefix-LSA\n"
- "Link-LSA\n"
- "All LS Type\n"
- "Specify LS Type by Hex\n"
- "Link State ID\n"
- "All Link State ID\n"
- "Advertising Router\n"
- "All Advertising Router\n"
- "Dump raw LSA data in Hex\n"
- "show detail of LSAs\n"
- )
-
void
-ospf6_lsdb_init ()
+ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
{
- install_element (VIEW_NODE, &show_ipv6_ospf6_database_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_adv_router_cmd);
- install_element (VIEW_NODE, &show_ipv6_ospf6_database_type_id_adv_router_dump_cmd);
-
- install_element (ENABLE_NODE, &show_ipv6_ospf6_database_cmd);
- install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_cmd);
- install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_id_cmd);
- install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_id_adv_router_cmd);
- install_element (ENABLE_NODE, &show_ipv6_ospf6_database_type_id_adv_router_dump_cmd);
+ struct ospf6_lsa *lsa;
+ for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
+ ospf6_lsdb_remove (lsa, lsdb);
}