Merge pull request #794 from opensourcerouting/table-hash-ospf6-lsdb-refactor

use hash in lib/table, also refactor ospf6 lsdb code
This commit is contained in:
Donald Sharp 2017-07-14 12:18:06 -04:00 committed by GitHub
commit 9b42781b5d
21 changed files with 796 additions and 335 deletions

View File

@ -1776,6 +1776,8 @@ rfapiNhlAddSubtree (
struct rfapi_ip_prefix rprefix; struct rfapi_ip_prefix rprefix;
int rcount = 0; int rcount = 0;
/* FIXME: need to find a better way here to work without sticking our
* hands in node->link */
if (rn->l_left && rn->l_left != omit_node) if (rn->l_left && rn->l_left != omit_node)
{ {
if (rn->l_left->info) if (rn->l_left->info)

View File

@ -1804,6 +1804,8 @@ rfapiRibUpdatePendingNodeSubtree (
struct route_node *omit_subtree, /* may be NULL */ struct route_node *omit_subtree, /* may be NULL */
uint32_t lifetime) uint32_t lifetime)
{ {
/* FIXME: need to find a better way here to work without sticking our
* hands in node->link */
if (it_node->l_left && (it_node->l_left != omit_subtree)) if (it_node->l_left && (it_node->l_left != omit_subtree))
{ {
if (it_node->l_left->info) if (it_node->l_left->info)

View File

@ -19,12 +19,15 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#define FRR_COMPILING_TABLE_C
#include <zebra.h> #include <zebra.h>
#include "prefix.h" #include "prefix.h"
#include "table.h" #include "table.h"
#include "memory.h" #include "memory.h"
#include "sockunion.h" #include "sockunion.h"
#include "jhash.h"
DEFINE_MTYPE( LIB, ROUTE_TABLE, "Route table") DEFINE_MTYPE( LIB, ROUTE_TABLE, "Route table")
DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node") DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node")
@ -32,6 +35,22 @@ DEFINE_MTYPE( LIB, ROUTE_NODE, "Route node")
static void route_node_delete (struct route_node *); static void route_node_delete (struct route_node *);
static void route_table_free (struct route_table *); static void route_table_free (struct route_table *);
static unsigned route_table_hash_key(void *pp)
{
struct prefix copy;
/* make sure *all* unused bits are zero, particularly including alignment /
* padding and unused prefix bytes. */
memset (&copy, 0, sizeof(copy));
prefix_copy (&copy, (struct prefix *)pp);
return jhash (&copy, sizeof(copy), 0x55aa5a5a);
}
static int route_table_hash_cmp(const void *a, const void *b)
{
const struct prefix *pa = a, *pb = b;
return prefix_cmp(pa, pb) == 0;
}
/* /*
* route_table_init_with_delegate * route_table_init_with_delegate
@ -43,6 +62,9 @@ route_table_init_with_delegate (route_table_delegate_t *delegate)
rt = XCALLOC (MTYPE_ROUTE_TABLE, sizeof (struct route_table)); rt = XCALLOC (MTYPE_ROUTE_TABLE, sizeof (struct route_table));
rt->delegate = delegate; rt->delegate = delegate;
rt->hash = hash_create(route_table_hash_key,
route_table_hash_cmp,
"route table hash");
return rt; return rt;
} }
@ -63,13 +85,16 @@ route_node_new (struct route_table *table)
static struct route_node * static struct route_node *
route_node_set (struct route_table *table, const struct prefix *prefix) route_node_set (struct route_table *table, const struct prefix *prefix)
{ {
struct route_node *node; struct route_node *node, *inserted;
node = route_node_new (table); node = route_node_new (table);
prefix_copy (&node->p, prefix); prefix_copy (&node->p, prefix);
node->table = table; node->table = table;
inserted = hash_get (node->table->hash, node, hash_alloc_intern);
assert (inserted == node);
return node; return node;
} }
@ -92,6 +117,9 @@ route_table_free (struct route_table *rt)
if (rt == NULL) if (rt == NULL)
return; return;
hash_clean (rt->hash, NULL);
hash_free (rt->hash);
node = rt->top; node = rt->top;
/* Bulk deletion of nodes remaining in this table. This function is not /* Bulk deletion of nodes remaining in this table. This function is not
@ -208,8 +236,9 @@ route_unlock_node (struct route_node *node)
/* Find matched prefix. */ /* Find matched prefix. */
struct route_node * struct route_node *
route_node_match (const struct route_table *table, const struct prefix *p) route_node_match (const struct route_table *table, union prefixconstptr pu)
{ {
const struct prefix *p = pu.p;
struct route_node *node; struct route_node *node;
struct route_node *matched; struct route_node *matched;
@ -267,58 +296,42 @@ route_node_match_ipv6 (const struct route_table *table,
/* Lookup same prefix node. Return NULL when we can't find route. */ /* Lookup same prefix node. Return NULL when we can't find route. */
struct route_node * struct route_node *
route_node_lookup (const struct route_table *table, const struct prefix *p) route_node_lookup (const struct route_table *table, union prefixconstptr pu)
{ {
const struct prefix *p = pu.p;
struct route_node *node; struct route_node *node;
u_char prefixlen = p->prefixlen;
const u_char *prefix = &p->u.prefix;
node = table->top; node = hash_get (table->hash, (void *)p, NULL);
return (node && node->info) ? route_lock_node (node) : NULL;
while (node && node->p.prefixlen <= prefixlen &&
prefix_match (&node->p, p))
{
if (node->p.prefixlen == prefixlen)
return node->info ? route_lock_node (node) : NULL;
node = node->link[prefix_bit(prefix, node->p.prefixlen)];
}
return NULL;
} }
/* Lookup same prefix node. Return NULL when we can't find route. */ /* Lookup same prefix node. Return NULL when we can't find route. */
struct route_node * struct route_node *
route_node_lookup_maynull (const struct route_table *table, const struct prefix *p) route_node_lookup_maynull (const struct route_table *table, union prefixconstptr pu)
{ {
const struct prefix *p = pu.p;
struct route_node *node; struct route_node *node;
u_char prefixlen = p->prefixlen;
const u_char *prefix = &p->u.prefix;
node = table->top; node = hash_get (table->hash, (void *)p, NULL);
return node ? route_lock_node (node) : NULL;
while (node && node->p.prefixlen <= prefixlen &&
prefix_match (&node->p, p))
{
if (node->p.prefixlen == prefixlen)
return route_lock_node (node);
node = node->link[prefix_bit(prefix, node->p.prefixlen)];
}
return NULL;
} }
/* Add node to routing table. */ /* Add node to routing table. */
struct route_node * struct route_node *
route_node_get (struct route_table *const table, const struct prefix *p) route_node_get (struct route_table *const table, union prefixconstptr pu)
{ {
const struct prefix *p = pu.p;
struct route_node *new; struct route_node *new;
struct route_node *node; struct route_node *node;
struct route_node *match; struct route_node *match;
struct route_node *inserted;
u_char prefixlen = p->prefixlen; u_char prefixlen = p->prefixlen;
const u_char *prefix = &p->u.prefix; const u_char *prefix = &p->u.prefix;
node = hash_get (table->hash, (void *)p, NULL);
if (node && node->info)
return route_lock_node (node);
match = NULL; match = NULL;
node = table->top; node = table->top;
while (node && node->p.prefixlen <= prefixlen && while (node && node->p.prefixlen <= prefixlen &&
@ -346,6 +359,8 @@ route_node_get (struct route_table *const table, const struct prefix *p)
new->p.family = p->family; new->p.family = p->family;
new->table = table; new->table = table;
set_link (new, node); set_link (new, node);
inserted = hash_get (node->table->hash, new, hash_alloc_intern);
assert (inserted == new);
if (match) if (match)
set_link (match, new); set_link (match, new);
@ -401,6 +416,8 @@ route_node_delete (struct route_node *node)
node->table->count--; node->table->count--;
hash_release (node->table->hash, node);
/* WARNING: FRAGILE CODE! /* WARNING: FRAGILE CODE!
* route_node_free may have the side effect of free'ing the entire table. * route_node_free may have the side effect of free'ing the entire table.
* this is permitted only if table->count got decremented to zero above, * this is permitted only if table->count got decremented to zero above,
@ -473,7 +490,7 @@ route_next (struct route_node *node)
/* Unlock current node and lock next node until limit. */ /* Unlock current node and lock next node until limit. */
struct route_node * struct route_node *
route_next_until (struct route_node *node, struct route_node *limit) route_next_until (struct route_node *node, const struct route_node *limit)
{ {
struct route_node *next; struct route_node *next;
struct route_node *start; struct route_node *start;
@ -578,7 +595,7 @@ route_table_init (void)
* +1 if p1 occurs after p2 (p1 > p2) * +1 if p1 occurs after p2 (p1 > p2)
*/ */
int int
route_table_prefix_iter_cmp (struct prefix *p1, struct prefix *p2) route_table_prefix_iter_cmp (const struct prefix *p1, const struct prefix *p2)
{ {
struct prefix common_space; struct prefix common_space;
struct prefix *common = &common_space; struct prefix *common = &common_space;
@ -661,7 +678,7 @@ route_get_subtree_next (struct route_node *node)
*/ */
static struct route_node * static struct route_node *
route_table_get_next_internal (const struct route_table *table, route_table_get_next_internal (const struct route_table *table,
struct prefix *p) const struct prefix *p)
{ {
struct route_node *node, *tmp_node; struct route_node *node, *tmp_node;
int cmp; int cmp;
@ -762,8 +779,9 @@ route_table_get_next_internal (const struct route_table *table,
* iteration. * iteration.
*/ */
struct route_node * struct route_node *
route_table_get_next (const struct route_table *table, struct prefix *p) route_table_get_next (const struct route_table *table, union prefixconstptr pu)
{ {
const struct prefix *p = pu.p;
struct route_node *node; struct route_node *node;
node = route_table_get_next_internal (table, p); node = route_table_get_next_internal (table, p);

View File

@ -23,6 +23,7 @@
#define _ZEBRA_TABLE_H #define _ZEBRA_TABLE_H
#include "memory.h" #include "memory.h"
#include "hash.h"
DECLARE_MTYPE(ROUTE_TABLE) DECLARE_MTYPE(ROUTE_TABLE)
DECLARE_MTYPE(ROUTE_NODE) DECLARE_MTYPE(ROUTE_NODE)
@ -56,6 +57,7 @@ struct route_table_delegate_t_
struct route_table struct route_table
{ {
struct route_node *top; struct route_node *top;
struct hash *hash;
/* /*
* Delegate that performs certain functions for this table. * Delegate that performs certain functions for this table.
@ -71,6 +73,41 @@ struct route_table
void *info; void *info;
}; };
/*
* node->link is really internal to the table code and should not be
* accessed by outside code. We don't have any writers (yay), though some
* readers are left to be fixed.
*
* rationale: we need to add a hash table in parallel, to speed up
* exact-match lookups.
*
* same really applies for node->parent, though that's less of an issue.
* table->link should be - and is - NEVER written by outside code
*/
#ifdef FRR_COMPILING_TABLE_C
#define table_rdonly(x) x
#define table_internal(x) x
#else
#define table_rdonly(x) const x
#define table_internal(x) const x \
__attribute__((deprecated("this should only be accessed by lib/table.c")))
/* table_internal is for node->link and node->lock, once we have done
* something about remaining accesses */
#endif
/* so... the problem with this is that "const" doesn't mean "readonly".
* It in fact may allow the compiler to optimize based on the assumption
* that the value doesn't change. Hence, since the only purpose of this
* is to aid in development, don't put the "const" in release builds.
*
* (I haven't seen this actually break, but GCC and LLVM are getting ever
* more aggressive in optimizing...)
*/
#ifndef DEV_BUILD
#undef table_rdonly
#define table_rdonly(x) x
#endif
/* /*
* Macro that defines all fields in a route node. * Macro that defines all fields in a route node.
*/ */
@ -79,12 +116,12 @@ struct route_table
struct prefix p; \ struct prefix p; \
\ \
/* Tree link. */ \ /* Tree link. */ \
struct route_table *table; \ struct route_table * table_rdonly(table); \
struct route_node *parent; \ struct route_node * table_rdonly(parent); \
struct route_node *link[2]; \ struct route_node * table_rdonly(link[2]); \
\ \
/* Lock of this radix */ \ /* Lock of this radix */ \
unsigned int lock; \ unsigned int table_rdonly(lock); \
\ \
/* Each node of route. */ \ /* Each node of route. */ \
void *info; \ void *info; \
@ -153,16 +190,16 @@ extern void route_unlock_node (struct route_node *node);
extern struct route_node *route_top (struct route_table *); extern struct route_node *route_top (struct route_table *);
extern struct route_node *route_next (struct route_node *); extern struct route_node *route_next (struct route_node *);
extern struct route_node *route_next_until (struct route_node *, extern struct route_node *route_next_until (struct route_node *,
struct route_node *); const struct route_node *);
extern struct route_node *route_node_get (struct route_table *const, extern struct route_node *route_node_get (struct route_table *const,
const struct prefix *); union prefixconstptr);
extern struct route_node *route_node_lookup (const struct route_table *, extern struct route_node *route_node_lookup (const struct route_table *,
const struct prefix *); union prefixconstptr);
extern struct route_node *route_node_lookup_maynull (const struct route_table *, extern struct route_node *route_node_lookup_maynull (const struct route_table *,
const struct prefix *); union prefixconstptr);
extern struct route_node *route_lock_node (struct route_node *node); extern struct route_node *route_lock_node (struct route_node *node);
extern struct route_node *route_node_match (const struct route_table *, extern struct route_node *route_node_match (const struct route_table *,
const struct prefix *); union prefixconstptr);
extern struct route_node *route_node_match_ipv4 (const struct route_table *, extern struct route_node *route_node_match_ipv4 (const struct route_table *,
const struct in_addr *); const struct in_addr *);
extern struct route_node *route_node_match_ipv6 (const struct route_table *, extern struct route_node *route_node_match_ipv6 (const struct route_table *,
@ -176,9 +213,9 @@ extern void route_node_destroy (route_table_delegate_t *,
struct route_table *, struct route_node *); struct route_table *, struct route_node *);
extern struct route_node * extern struct route_node *
route_table_get_next (const struct route_table *table, struct prefix *p); route_table_get_next (const struct route_table *table, union prefixconstptr pu);
extern int extern int
route_table_prefix_iter_cmp (struct prefix *p1, struct prefix *p2); route_table_prefix_iter_cmp (const struct prefix *p1, const struct prefix *p2);
/* /*
* Iterator functions. * Iterator functions.

View File

@ -989,13 +989,11 @@ ospf6_abr_examin_brouter (u_int32_t router_id)
return; return;
type = htons (OSPF6_LSTYPE_INTER_ROUTER); type = htons (OSPF6_LSTYPE_INTER_ROUTER);
for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa; for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router_id, lsa))
lsa = ospf6_lsdb_type_router_next (type, router_id, lsa)) ospf6_abr_examin_summary (lsa, oa);
ospf6_abr_examin_summary (lsa, oa);
type = htons (OSPF6_LSTYPE_INTER_PREFIX); type = htons (OSPF6_LSTYPE_INTER_PREFIX);
for (lsa = ospf6_lsdb_type_router_head (type, router_id, oa->lsdb); lsa; for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router_id, lsa))
lsa = ospf6_lsdb_type_router_next (type, router_id, lsa))
ospf6_abr_examin_summary (lsa, oa); ospf6_abr_examin_summary (lsa, oa);
} }
@ -1006,13 +1004,11 @@ ospf6_abr_reimport (struct ospf6_area *oa)
u_int16_t type; u_int16_t type;
type = htons (OSPF6_LSTYPE_INTER_ROUTER); type = htons (OSPF6_LSTYPE_INTER_ROUTER);
for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa; for (ALL_LSDB_TYPED(oa->lsdb, type, lsa))
lsa = ospf6_lsdb_type_next (type, lsa))
ospf6_abr_examin_summary (lsa, oa); ospf6_abr_examin_summary (lsa, oa);
type = htons (OSPF6_LSTYPE_INTER_PREFIX); type = htons (OSPF6_LSTYPE_INTER_PREFIX);
for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa; for (ALL_LSDB_TYPED(oa->lsdb, type, lsa))
lsa = ospf6_lsdb_type_next (type, lsa))
ospf6_abr_examin_summary (lsa, oa); ospf6_abr_examin_summary (lsa, oa);
} }

View File

@ -343,8 +343,7 @@ ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
type = htons (OSPF6_LSTYPE_AS_EXTERNAL); type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix); router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa; for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa))
lsa = ospf6_lsdb_type_router_next (type, router, lsa))
{ {
if (! OSPF6_LSA_IS_MAXAGE (lsa)) if (! OSPF6_LSA_IS_MAXAGE (lsa))
ospf6_asbr_lsa_add (lsa); ospf6_asbr_lsa_add (lsa);
@ -360,8 +359,7 @@ ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
type = htons (OSPF6_LSTYPE_AS_EXTERNAL); type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix); router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa))
lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
ospf6_asbr_lsa_remove (lsa); ospf6_asbr_lsa_remove (lsa);
} }
@ -444,8 +442,7 @@ ospf6_asbr_send_externals_to_area (struct ospf6_area *oa)
{ {
struct ospf6_lsa *lsa; struct ospf6_lsa *lsa;
for (lsa = ospf6_lsdb_head (oa->ospf6->lsdb); lsa; for (ALL_LSDB(oa->ospf6->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL)
{ {

View File

@ -985,8 +985,7 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
oi->lsupdate_list->count, duration, oi->lsupdate_list->count, duration,
(oi->thread_send_lsupdate ? "on" : "off")); (oi->thread_send_lsupdate ? "on" : "off"));
for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa; for (ALL_LSDB(oi->lsupdate_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
timerclear (&res); timerclear (&res);
@ -996,8 +995,7 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
oi->lsack_list->count, duration, oi->lsack_list->count, duration,
(oi->thread_send_lsack ? "on" : "off")); (oi->thread_send_lsack ? "on" : "off"));
for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa; for (ALL_LSDB(oi->lsack_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
ospf6_bfd_show_info(vty, oi->bfd_info, 1); ospf6_bfd_show_info(vty, oi->bfd_info, 1);
return 0; return 0;

View File

@ -341,8 +341,7 @@ ospf6_router_lsa_originate (struct thread *thread)
type = ntohs (OSPF6_LSTYPE_ROUTER); type = ntohs (OSPF6_LSTYPE_ROUTER);
router = oa->ospf6->router_id; router = oa->ospf6->router_id;
count = 0; count = 0;
for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa; for (ALL_LSDB_TYPED_ADVRTR(oa->lsdb, type, router, lsa))
lsa = ospf6_lsdb_type_router_next (type, router, lsa))
{ {
if (ntohl (lsa->header->id) < link_state_id) if (ntohl (lsa->header->id) < link_state_id)
continue; continue;
@ -495,8 +494,7 @@ ospf6_network_lsa_originate (struct thread *thread)
/* Collect the interface's Link-LSAs to describe /* Collect the interface's Link-LSAs to describe
network's optional capabilities */ network's optional capabilities */
type = htons (OSPF6_LSTYPE_LINK); type = htons (OSPF6_LSTYPE_LINK);
for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; for (ALL_LSDB_TYPED(oi->lsdb, type, lsa))
lsa = ospf6_lsdb_type_next (type, lsa))
{ {
link_lsa = (struct ospf6_link_lsa *) link_lsa = (struct ospf6_link_lsa *)
((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
@ -1095,8 +1093,7 @@ ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
route_advertise = ospf6_route_table_create (0, 0); route_advertise = ospf6_route_table_create (0, 0);
type = ntohs (OSPF6_LSTYPE_LINK); type = ntohs (OSPF6_LSTYPE_LINK);
for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; for (ALL_LSDB_TYPED(oi->lsdb, type, lsa))
lsa = ospf6_lsdb_type_next (type, lsa))
{ {
if (OSPF6_LSA_IS_MAXAGE (lsa)) if (OSPF6_LSA_IS_MAXAGE (lsa))
continue; continue;
@ -1428,8 +1425,7 @@ ospf6_intra_route_calculation (struct ospf6_area *oa)
route->flag = OSPF6_ROUTE_REMOVE; route->flag = OSPF6_ROUTE_REMOVE;
type = htons (OSPF6_LSTYPE_INTRA_PREFIX); type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa; for (ALL_LSDB_TYPED(oa->lsdb, type, lsa))
lsa = ospf6_lsdb_type_next (type, lsa))
ospf6_intra_prefix_lsa_add (lsa); ospf6_intra_prefix_lsa_add (lsa);
oa->route_table->hook_add = hook_add; oa->route_table->hook_add = hook_add;

View File

@ -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);
@ -80,8 +80,7 @@ _lsdb_count_assert (struct ospf6_lsdb *lsdb)
{ {
struct ospf6_lsa *debug; struct ospf6_lsa *debug;
unsigned int num = 0; unsigned int num = 0;
for (debug = ospf6_lsdb_head (lsdb); debug; for (ALL_LSDB(lsdb, debug))
debug = ospf6_lsdb_next (debug))
num++; num++;
if (num == lsdb->count) if (num == lsdb->count)
@ -89,8 +88,7 @@ _lsdb_count_assert (struct ospf6_lsdb *lsdb)
zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d", zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d",
lsdb, lsdb->count, num); lsdb, lsdb->count, num);
for (debug = ospf6_lsdb_head (lsdb); debug; for (ALL_LSDB(lsdb, debug))
debug = ospf6_lsdb_next (debug))
zlog_debug ("%p %p %s lsdb[%p]", debug->prev, debug->next, debug->name, zlog_debug ("%p %p %s lsdb[%p]", debug->prev, debug->next, debug->name,
debug->lsdb); debug->lsdb);
zlog_debug ("DUMP END"); zlog_debug ("DUMP END");
@ -223,9 +221,7 @@ ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
struct ospf6_lsdb *lsdb) struct ospf6_lsdb *lsdb)
{ {
struct route_node *node; struct route_node *node;
struct route_node *matched = NULL;
struct prefix_ipv6 key; struct prefix_ipv6 key;
struct prefix *p;
if (lsdb == NULL) if (lsdb == NULL)
return NULL; return NULL;
@ -234,28 +230,14 @@ ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
ospf6_lsdb_set_key (&key, &type, sizeof (type)); ospf6_lsdb_set_key (&key, &type, sizeof (type));
ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router)); ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
ospf6_lsdb_set_key (&key, &id, sizeof (id)); ospf6_lsdb_set_key (&key, &id, sizeof (id));
p = (struct prefix *) &key;
{ {
char buf[PREFIX2STR_BUFFER]; char buf[PREFIX2STR_BUFFER];
prefix2str (p, buf, sizeof (buf)); prefix2str (&key, buf, sizeof (buf));
zlog_debug ("lsdb_lookup_next: key: %s", buf); zlog_debug ("lsdb_lookup_next: key: %s", buf);
} }
node = lsdb->table->top; node = route_table_get_next (lsdb->table, &key);
/* walk down tree. */
while (node && node->p.prefixlen <= p->prefixlen &&
prefix_match (&node->p, p))
{
matched = node;
node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
}
if (matched)
node = matched;
else
node = lsdb->table->top;
route_lock_node (node);
/* skip to real existing entry */ /* skip to real existing entry */
while (node && node->info == NULL) while (node && node->info == NULL)
@ -264,166 +246,84 @@ ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
if (! node) if (! node)
return NULL; return NULL;
if (prefix_same (&node->p, p)) route_unlock_node (node);
if (! node->info)
return NULL;
return (struct ospf6_lsa *) node->info;
}
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, *end;
*lsa = NULL;
if (argmode > 0)
{ {
node = route_next (node); struct prefix_ipv6 key = { .family = AF_INET6, .prefixlen = 0 };
while (node && node->info == NULL)
node = route_next (node); ospf6_lsdb_set_key (&key, &type, sizeof (type));
if (argmode > 1)
ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
node = route_table_get_next (lsdb->table, &key);
if (!node || !prefix_match((struct prefix *)&key, &node->p))
return NULL;
for (end = node;
end && end->parent && end->parent->p.prefixlen >= key.prefixlen;
end = end->parent)
;
}
else
{
node = route_top (lsdb->table);
end = NULL;
} }
if (! node) 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;
}
route_unlock_node (node); *lsa = node->info;
return (struct ospf6_lsa *) node->info; ospf6_lsa_lock (*lsa);
}
/* Iteration function */ return end;
struct ospf6_lsa *
ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
{
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;
if (node->info)
ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
return (struct ospf6_lsa *) node->info;
} }
struct ospf6_lsa * struct ospf6_lsa *
ospf6_lsdb_next (struct ospf6_lsa *lsa) ospf6_lsdb_next (const struct route_node *iterend,
struct ospf6_lsa *lsa)
{ {
struct route_node *node = lsa->rn; struct route_node *node = lsa->rn;
struct ospf6_lsa *next = NULL;
do { ospf6_lsa_unlock(lsa);
node = route_next (node);
} while (node && node->info == NULL);
if ((node != NULL) && (node->info != NULL)) do
node = route_next_until(node, iterend);
while (node && !node->info);
if (node && node->info)
{ {
next = node->info; struct ospf6_lsa *next = node->info;
ospf6_lsa_lock (next); ospf6_lsa_lock (next);
return 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, &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) if (node)
route_lock_node (node); route_unlock_node (node);
while (node && node->info == NULL) return NULL;
node = route_next (node);
if (node == 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_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 (next->header->type != type ||
next->header->adv_router != adv_router)
{
route_unlock_node (next->rn);
ospf6_lsa_unlock (next);
next = NULL;
}
}
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)
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
@ -434,7 +334,7 @@ ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
if (lsdb == NULL) if (lsdb == NULL)
return; return;
for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa)) for (ALL_LSDB(lsdb, lsa))
ospf6_lsdb_remove (lsa, lsdb); ospf6_lsdb_remove (lsa, lsdb);
} }
@ -455,7 +355,7 @@ ospf6_lsdb_maxage_remover (struct ospf6_lsdb *lsdb)
int reschedule = 0; int reschedule = 0;
struct ospf6_lsa *lsa; struct ospf6_lsa *lsa;
for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa)) for (ALL_LSDB(lsdb, lsa))
{ {
if (! OSPF6_LSA_IS_MAXAGE (lsa)) if (! OSPF6_LSA_IS_MAXAGE (lsa))
continue; continue;
@ -491,6 +391,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)
@ -525,24 +426,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);
} }
} }
@ -556,8 +448,7 @@ ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
/* This routine is curently invoked only for Inter-Prefix LSAs for /* This routine is curently invoked only for Inter-Prefix LSAs for
* non-summarized routes (no area/range). * non-summarized routes (no area/range).
*/ */
for (lsa = ospf6_lsdb_type_router_head (type, adv_router, lsdb); lsa; for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa))
lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa))
{ {
tmp_id = ntohl (lsa->header->id); tmp_id = ntohl (lsa->header->id);
if (tmp_id < id) if (tmp_id < id)

View File

@ -48,20 +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,
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, #define ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv_router, lsa) \
u_int32_t adv_router, const struct route_node *iterend = \
struct ospf6_lsdb *lsdb); ospf6_lsdb_head(lsdb, 2, type, adv_router, &lsa); \
extern struct ospf6_lsa *ospf6_lsdb_type_router_next (u_int16_t type, lsa; \
u_int32_t adv_router, lsa = ospf6_lsdb_next(iterend, lsa)
struct ospf6_lsa *lsa);
extern struct ospf6_lsa *ospf6_lsdb_type_head (u_int16_t type, #define ALL_LSDB_TYPED(lsdb, type, lsa) \
struct ospf6_lsdb *lsdb); const struct route_node *iterend = \
extern struct ospf6_lsa *ospf6_lsdb_type_next (u_int16_t type, ospf6_lsdb_head(lsdb, 1, type, 0, &lsa); \
struct ospf6_lsa *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);

View File

@ -1826,8 +1826,7 @@ ospf6_dbdesc_send (struct thread *thread)
p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc)); p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT)) if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
{ {
for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa; for (ALL_LSDB(on->dbdesc_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay); ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
@ -1870,8 +1869,7 @@ ospf6_dbdesc_send_newone (struct thread *thread)
/* move LSAs from summary_list to dbdesc_list (within neighbor structure) /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
so that ospf6_send_dbdesc () can send those LSAs */ so that ospf6_send_dbdesc () can send those LSAs */
size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc); size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
for (lsa = ospf6_lsdb_head (on->summary_list); lsa; for (ALL_LSDB(on->summary_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
{ {
@ -1932,8 +1930,7 @@ ospf6_lsreq_send (struct thread *thread)
/* set Request entries in lsreq */ /* set Request entries in lsreq */
p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
for (lsa = ospf6_lsdb_head (on->request_list); lsa; for (ALL_LSDB(on->request_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
/* MTU check */ /* MTU check */
if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if)) if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if))
@ -2015,8 +2012,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
/* lsupdate_list lists those LSA which doesn't need to be /* lsupdate_list lists those LSA which doesn't need to be
retransmitted. remove those from the list */ retransmitted. remove those from the list */
for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa; for (ALL_LSDB(on->lsupdate_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
/* MTU check */ /* MTU check */
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
@ -2061,8 +2057,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
lsa_cnt = 0; lsa_cnt = 0;
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
/* MTU check */ /* MTU check */
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header)) if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
@ -2138,8 +2133,7 @@ ospf6_lsupdate_send_interface (struct thread *thread)
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate)); p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
lsa_cnt = 0; lsa_cnt = 0;
for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa; for (ALL_LSDB(oi->lsupdate_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
/* MTU check */ /* MTU check */
if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header))) if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
@ -2213,8 +2207,7 @@ ospf6_lsack_send_neighbor (struct thread *thread)
p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
for (lsa = ospf6_lsdb_head (on->lsack_list); lsa; for (ALL_LSDB(on->lsack_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
/* MTU check */ /* MTU check */
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
@ -2281,8 +2274,7 @@ ospf6_lsack_send_interface (struct thread *thread)
p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header)); p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa; for (ALL_LSDB(oi->lsack_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
/* MTU check */ /* MTU check */
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi)) if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))

View File

@ -123,8 +123,7 @@ ospf6_neighbor_delete (struct ospf6_neighbor *on)
ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list); ospf6_lsdb_remove_all (on->request_list);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_decrement_retrans_count (lsa); ospf6_decrement_retrans_count (lsa);
ospf6_lsdb_remove (lsa, on->retrans_list); ospf6_lsdb_remove (lsa, on->retrans_list);
@ -302,16 +301,14 @@ negotiation_done (struct thread *thread)
/* clear ls-list */ /* clear ls-list */
ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list); ospf6_lsdb_remove_all (on->request_list);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_decrement_retrans_count (lsa); ospf6_decrement_retrans_count (lsa);
ospf6_lsdb_remove (lsa, on->retrans_list); ospf6_lsdb_remove (lsa, on->retrans_list);
} }
/* Interface scoped LSAs */ /* Interface scoped LSAs */
for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa; for (ALL_LSDB(on->ospf6_if->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
if (OSPF6_LSA_IS_MAXAGE (lsa)) if (OSPF6_LSA_IS_MAXAGE (lsa))
{ {
@ -323,8 +320,7 @@ negotiation_done (struct thread *thread)
} }
/* Area scoped LSAs */ /* Area scoped LSAs */
for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa; for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
if (OSPF6_LSA_IS_MAXAGE (lsa)) if (OSPF6_LSA_IS_MAXAGE (lsa))
{ {
@ -336,8 +332,7 @@ negotiation_done (struct thread *thread)
} }
/* AS scoped LSAs */ /* AS scoped LSAs */
for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa; for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
if (OSPF6_LSA_IS_MAXAGE (lsa)) if (OSPF6_LSA_IS_MAXAGE (lsa))
{ {
@ -472,8 +467,7 @@ adj_ok (struct thread *thread)
OSPF6_NEIGHBOR_EVENT_ADJ_OK); OSPF6_NEIGHBOR_EVENT_ADJ_OK);
ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list); ospf6_lsdb_remove_all (on->request_list);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_decrement_retrans_count (lsa); ospf6_decrement_retrans_count (lsa);
ospf6_lsdb_remove (lsa, on->retrans_list); ospf6_lsdb_remove (lsa, on->retrans_list);
@ -506,8 +500,7 @@ seqnumber_mismatch (struct thread *thread)
ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list); ospf6_lsdb_remove_all (on->request_list);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_decrement_retrans_count (lsa); ospf6_decrement_retrans_count (lsa);
ospf6_lsdb_remove (lsa, on->retrans_list); ospf6_lsdb_remove (lsa, on->retrans_list);
@ -545,8 +538,7 @@ bad_lsreq (struct thread *thread)
ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list); ospf6_lsdb_remove_all (on->request_list);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_decrement_retrans_count (lsa); ospf6_decrement_retrans_count (lsa);
ospf6_lsdb_remove (lsa, on->retrans_list); ospf6_lsdb_remove (lsa, on->retrans_list);
@ -582,8 +574,7 @@ oneway_received (struct thread *thread)
ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->summary_list);
ospf6_lsdb_remove_all (on->request_list); ospf6_lsdb_remove_all (on->request_list);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
{ {
ospf6_decrement_retrans_count (lsa); ospf6_decrement_retrans_count (lsa);
ospf6_lsdb_remove (lsa, on->retrans_list); ospf6_lsdb_remove (lsa, on->retrans_list);
@ -748,18 +739,15 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
"Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum)); "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum));
vty_out (vty, " Summary-List: %d LSAs\n", on->summary_list->count); vty_out (vty, " Summary-List: %d LSAs\n", on->summary_list->count);
for (lsa = ospf6_lsdb_head (on->summary_list); lsa; for (ALL_LSDB(on->summary_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
vty_out (vty, " Request-List: %d LSAs\n", on->request_list->count); vty_out (vty, " Request-List: %d LSAs\n", on->request_list->count);
for (lsa = ospf6_lsdb_head (on->request_list); lsa; for (ALL_LSDB(on->request_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
vty_out (vty, " Retrans-List: %d LSAs\n", on->retrans_list->count); vty_out (vty, " Retrans-List: %d LSAs\n", on->retrans_list->count);
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; for (ALL_LSDB(on->retrans_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
timerclear (&res); timerclear (&res);
@ -769,8 +757,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
vty_out (vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n", vty_out (vty, " %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
on->dbdesc_list->count, duration, on->dbdesc_list->count, duration,
(on->thread_send_dbdesc ? "on" : "off")); (on->thread_send_dbdesc ? "on" : "off"));
for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa; for (ALL_LSDB(on->dbdesc_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
timerclear (&res); timerclear (&res);
@ -780,8 +767,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
vty_out (vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n", vty_out (vty, " %d Pending LSAs for LSReq in Time %s [thread %s]\n",
on->request_list->count, duration, on->request_list->count, duration,
(on->thread_send_lsreq ? "on" : "off")); (on->thread_send_lsreq ? "on" : "off"));
for (lsa = ospf6_lsdb_head (on->request_list); lsa; for (ALL_LSDB(on->request_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
timerclear (&res); timerclear (&res);
@ -791,8 +777,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n", vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
on->lsupdate_list->count, duration, on->lsupdate_list->count, duration,
(on->thread_send_lsupdate ? "on" : "off")); (on->thread_send_lsupdate ? "on" : "off"));
for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa; for (ALL_LSDB(on->lsupdate_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
timerclear (&res); timerclear (&res);
@ -802,8 +787,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n", vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
on->lsack_list->count, duration, on->lsack_list->count, duration,
(on->thread_send_lsack ? "on" : "off")); (on->thread_send_lsack ? "on" : "off"));
for (lsa = ospf6_lsdb_head (on->lsack_list); lsa; for (ALL_LSDB(on->lsack_list, lsa))
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s\n", lsa->name); vty_out (vty, " %s\n", lsa->name);
ospf6_bfd_show_info(vty, on->bfd_info, 0); ospf6_bfd_show_info(vty, on->bfd_info, 0);

View File

@ -460,9 +460,8 @@ ospfv3GeneralGroup (struct variable *v, oid *name, size_t *length,
case OSPFv3ASSCOPELSACHECKSUMSUM: case OSPFv3ASSCOPELSACHECKSUMSUM:
if (ospf6) if (ospf6)
{ {
for (sum = 0, lsa = ospf6_lsdb_head (ospf6->lsdb); sum = 0;
lsa; for (ALL_LSDB(ospf6->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
sum += ntohs (lsa->header->checksum); sum += ntohs (lsa->header->checksum);
return SNMP_INTEGER (sum); return SNMP_INTEGER (sum);
} }
@ -474,11 +473,8 @@ ospfv3GeneralGroup (struct variable *v, oid *name, size_t *length,
case OSPFv3EXTLSACOUNT: case OSPFv3EXTLSACOUNT:
if (ospf6) if (ospf6)
{ {
for (count = 0, lsa = ospf6_lsdb_type_head (htons (OSPF6_LSTYPE_AS_EXTERNAL), count = 0;
ospf6->lsdb); for (ALL_LSDB_TYPED(ospf6->lsdb, htons (OSPF6_LSTYPE_AS_EXTERNAL), lsa))
lsa;
lsa = ospf6_lsdb_type_next (htons (OSPF6_LSTYPE_AS_EXTERNAL),
lsa))
count += 1; count += 1;
return SNMP_INTEGER (count); return SNMP_INTEGER (count);
} }
@ -590,9 +586,8 @@ ospfv3AreaEntry (struct variable *v, oid *name, size_t *length,
case OSPFv3AREASCOPELSACOUNT: case OSPFv3AREASCOPELSACOUNT:
return SNMP_INTEGER (area->lsdb->count); return SNMP_INTEGER (area->lsdb->count);
case OSPFv3AREASCOPELSACKSUMSUM: case OSPFv3AREASCOPELSACKSUMSUM:
for (sum = 0, lsa = ospf6_lsdb_head (area->lsdb); sum = 0;
lsa; for (ALL_LSDB(area->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
sum += ntohs (lsa->header->checksum); sum += ntohs (lsa->header->checksum);
return SNMP_INTEGER (sum); return SNMP_INTEGER (sum);
case OSPFv3AREASUMMARY: case OSPFv3AREASUMMARY:
@ -962,9 +957,8 @@ ospfv3IfEntry (struct variable *v, oid *name, size_t *length,
case OSPFv3IFLINKSCOPELSACOUNT: case OSPFv3IFLINKSCOPELSACOUNT:
return SNMP_INTEGER (oi->lsdb->count); return SNMP_INTEGER (oi->lsdb->count);
case OSPFv3IFLINKLSACKSUMSUM: case OSPFv3IFLINKLSACKSUMSUM:
for (sum = 0, lsa = ospf6_lsdb_head (oi->lsdb); sum = 0;
lsa; for (ALL_LSDB(oi->lsdb, lsa))
lsa = ospf6_lsdb_next (lsa))
sum += ntohs (lsa->header->checksum); sum += ntohs (lsa->header->checksum);
return SNMP_INTEGER (sum); return SNMP_INTEGER (sum);
case OSPFv3IFDEMANDNBRPROBE: case OSPFv3IFDEMANDNBRPROBE:

View File

@ -296,8 +296,7 @@ ospf6_nexthop_calc (struct ospf6_vertex *w, struct ospf6_vertex *v,
ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc)); ROUTER_LSDESC_GET_NBR_ROUTERID (lsdesc));
i = 0; i = 0;
for (lsa = ospf6_lsdb_type_router_head (type, adv_router, oi->lsdb); lsa; for (ALL_LSDB_TYPED_ADVRTR(oi->lsdb, type, adv_router, lsa))
lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa))
{ {
if (VERTEX_IS_TYPE (ROUTER, v) && if (VERTEX_IS_TYPE (ROUTER, v) &&
htonl (ROUTER_LSDESC_GET_NBR_IFID (lsdesc)) != lsa->header->id) htonl (ROUTER_LSDESC_GET_NBR_IFID (lsdesc)) != lsa->header->id)

1
tests/.gitignore vendored
View File

@ -44,3 +44,4 @@ __pycache__
/lib/test_timer_correctness /lib/test_timer_correctness
/lib/test_timer_performance /lib/test_timer_performance
/lib/test_ttable /lib/test_ttable
/ospf6d/test_lsdb

View File

@ -24,6 +24,14 @@ else
TESTS_BGPD = TESTS_BGPD =
endif endif
if OSPF6D
TESTS_OSPF6D = \
ospf6d/test_lsdb \
# end
else
TESTS_OSPF6D =
endif
if ENABLE_BGP_VNC if ENABLE_BGP_VNC
BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a BGP_VNC_RFP_LIB=@top_builddir@/$(LIBRFP)/librfp.a
else else
@ -31,6 +39,7 @@ BGP_VNC_RFP_LIB =
endif endif
lib/cli/test_cli.o: lib/cli/test_cli_clippy.c lib/cli/test_cli.o: lib/cli/test_cli_clippy.c
ospf6d/test_lsdb.o: ospf6d/test_lsdb_clippy.c
check_PROGRAMS = \ check_PROGRAMS = \
lib/test_buffer \ lib/test_buffer \
@ -51,7 +60,9 @@ check_PROGRAMS = \
lib/test_ttable \ lib/test_ttable \
lib/cli/test_cli \ lib/cli/test_cli \
lib/cli/test_commands \ lib/cli/test_commands \
$(TESTS_BGPD) $(TESTS_BGPD) \
$(TESTS_OSPF6D) \
# end
../vtysh/vtysh_cmd.c: ../vtysh/vtysh_cmd.c:
$(MAKE) -C ../vtysh vtysh_cmd.c $(MAKE) -C ../vtysh vtysh_cmd.c
@ -100,8 +111,11 @@ bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
bgpd_test_mpath_SOURCES = bgpd/test_mpath.c bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c
ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@ ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@
BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm
OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD)
lib_test_buffer_LDADD = $(ALL_TESTS_LDADD) lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
lib_test_checksum_LDADD = $(ALL_TESTS_LDADD) lib_test_checksum_LDADD = $(ALL_TESTS_LDADD)
@ -126,6 +140,7 @@ bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD) bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD) bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD) bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD)
EXTRA_DIST = \ EXTRA_DIST = \
runtests.py \ runtests.py \
@ -150,6 +165,9 @@ EXTRA_DIST = \
lib/test_timer_correctness.py \ lib/test_timer_correctness.py \
lib/test_ttable.py \ lib/test_ttable.py \
lib/test_ttable.refout \ lib/test_ttable.refout \
ospf6d/test_lsdb.py \
ospf6d/test_lsdb.in \
ospf6d/test_lsdb.refout \
# end # end
.PHONY: tests.xml .PHONY: tests.xml

View File

@ -2,7 +2,10 @@ import frrtest
import pytest import pytest
import os import os
@pytest.mark.skipif('QUAGGA_TEST_COMMANDS' not in os.environ,
reason='QUAGGA_TEST_COMMANDS not set')
class TestCommands(frrtest.TestRefOut): class TestCommands(frrtest.TestRefOut):
program = './test_commands' program = './test_commands'
@pytest.mark.skipif('QUAGGA_TEST_COMMANDS' not in os.environ,
reason='QUAGGA_TEST_COMMANDS not set')
def test_refout(self):
return super(TestCommands, self).test_refout(self)

253
tests/ospf6d/test_lsdb.c Normal file
View File

@ -0,0 +1,253 @@
/*
* CLI/command dummy handling tester
*
* Copyright (C) 2015 by David Lamparter,
* for Open Source Routing / NetDEF, Inc.
*
* Quagga is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* Quagga is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "prefix.h"
#include "vector.h"
#include "vty.h"
#include "ospf6d/ospf6_lsa.h"
#include "ospf6d/ospf6_lsdb.h"
#include "tests/lib/cli/common_cli.h"
#include "tests/ospf6d/test_lsdb_clippy.c"
static struct ospf6_lsdb *lsdb;
static struct ospf6_lsa **lsas = NULL;
static size_t lsa_count = 0;
static void lsa_check_resize(size_t len)
{
if (lsa_count >= len)
return;
lsas = realloc(lsas, len * sizeof(lsas[0]));
memset(lsas + lsa_count, 0, sizeof(lsas[0]) * (len - lsa_count));
lsa_count = len;
}
DEFPY(lsa_set, lsa_set_cmd,
"lsa set (0-999999)$idx {type (0-65535)|id A.B.C.D|adv A.B.C.D}",
"LSA\n"
"set\n"
"LSA index in array\n"
"OSPF6 type code\n"
"OSPF6 type code\n"
"LS-ID\n"
"LS-ID\n"
"Advertising router\n"
"Advertising router\n")
{
struct ospf6_lsa_header hdr;
memset(&hdr, 0, sizeof(hdr));
hdr.type = htons(type);
hdr.id = id.s_addr;
hdr.adv_router = adv.s_addr;
lsa_check_resize(idx + 1);
if (lsas[idx])
ospf6_lsa_unlock(lsas[idx]);
lsas[idx] = ospf6_lsa_create_headeronly(&hdr);
ospf6_lsa_lock(lsas[idx]);
return CMD_SUCCESS;
}
DEFPY(lsa_drop, lsa_drop_cmd,
"lsa drop (0-999999)$idx",
"LSA\n"
"drop reference\n"
"LSA index in array\n")
{
if ((size_t)idx >= lsa_count)
return CMD_SUCCESS;
if (lsas[idx]->lock != 1)
vty_out(vty, "refcount at %u\n", lsas[idx]->lock);
ospf6_lsa_unlock(lsas[idx]);
lsas[idx] = NULL;
return CMD_SUCCESS;
}
DEFPY(lsdb_add, lsdb_add_cmd,
"lsdb add (0-999999)$idx",
"LSDB\n"
"insert LSA into LSDB\n"
"LSA index in array\n")
{
ospf6_lsdb_add(lsas[idx], lsdb);
return CMD_SUCCESS;
}
DEFPY(lsdb_remove, lsdb_remove_cmd,
"lsdb remove (0-999999)$idx",
"LSDB\n"
"remove LSA from LSDB\n"
"LSA index in array\n")
{
ospf6_lsdb_remove(lsas[idx], lsdb);
return CMD_SUCCESS;
}
static void lsa_show_oneline(struct vty *vty, struct ospf6_lsa *lsa)
{
char adv_router[64], id[64];
if (!lsa) {
vty_out(vty, "lsa = NULL\n");
return;
}
inet_ntop(AF_INET, &lsa->header->id,
id, sizeof (id));
inet_ntop(AF_INET, &lsa->header->adv_router,
adv_router, sizeof (adv_router));
vty_out(vty, "type %u adv %s id %s\n",
ntohs(lsa->header->type), adv_router, id);
}
DEFPY(lsdb_walk, lsdb_walk_cmd,
"lsdb walk",
"LSDB\n"
"walk entries\n")
{
struct ospf6_lsa *lsa;
unsigned cnt = 0;
for (ALL_LSDB(lsdb, lsa)) {
lsa_show_oneline(vty, lsa);
cnt++;
}
vty_out(vty, "%u entries.\n", cnt);
return CMD_SUCCESS;
}
DEFPY(lsdb_walk_type, lsdb_walk_type_cmd,
"lsdb walk type (0-65535)",
"LSDB\n"
"walk entries\n"
"entry type\n"
"entry type\n")
{
struct ospf6_lsa *lsa;
unsigned cnt = 0;
type = htons(type);
for (ALL_LSDB_TYPED(lsdb, type, lsa)) {
lsa_show_oneline(vty, lsa);
cnt++;
}
vty_out(vty, "%u entries.\n", cnt);
return CMD_SUCCESS;
}
DEFPY(lsdb_walk_type_adv, lsdb_walk_type_adv_cmd,
"lsdb walk type (0-65535) adv A.B.C.D",
"LSDB\n"
"walk entries\n"
"entry type\n"
"entry type\n"
"advertising router ID\n"
"advertising router ID\n")
{
struct ospf6_lsa *lsa;
unsigned cnt = 0;
type = htons(type);
for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv.s_addr, lsa)) {
lsa_show_oneline(vty, lsa);
cnt++;
}
vty_out(vty, "%u entries.\n", cnt);
return CMD_SUCCESS;
}
DEFPY(lsdb_get, lsdb_get_cmd,
"lsdb <get-next|get> type (0-65535) adv A.B.C.D id A.B.C.D",
"LSDB\n"
"get entry's successor\n"
"entry type\n"
"entry type\n"
"advertising router ID\n"
"advertising router ID\n"
"LS-ID\n"
"LS-ID\n")
{
struct ospf6_lsa *lsa;
type = htons(type);
if (!strcmp(argv[1]->text, "get-next"))
lsa = ospf6_lsdb_lookup_next(type, id.s_addr, adv.s_addr, lsdb);
else
lsa = ospf6_lsdb_lookup(type, id.s_addr, adv.s_addr, lsdb);
lsa_show_oneline(vty, lsa);
return CMD_SUCCESS;
}
DEFPY(lsa_refcounts, lsa_refcounts_cmd,
"lsa refcounts",
"LSA\n"
"show reference counts\n")
{
for (size_t i = 0; i < lsa_count; i++)
if (lsas[i])
vty_out(vty, "[%zu] %u\n", i, lsas[i]->lock);
return CMD_SUCCESS;
}
DEFPY(lsdb_create, lsdb_create_cmd,
"lsdb create",
"LSDB\n"
"create LSDB\n")
{
if (lsdb)
ospf6_lsdb_delete(lsdb);
lsdb = ospf6_lsdb_create(NULL);
return CMD_SUCCESS;
}
DEFPY(lsdb_delete, lsdb_delete_cmd,
"lsdb delete",
"LSDB\n"
"delete LSDB\n")
{
ospf6_lsdb_delete(lsdb);
lsdb = NULL;
return CMD_SUCCESS;
}
struct zebra_privs_t ospf6d_privs;
void test_init(int argc, char **argv)
{
ospf6_lsa_init();
install_element(ENABLE_NODE, &lsa_set_cmd);
install_element(ENABLE_NODE, &lsa_refcounts_cmd);
install_element(ENABLE_NODE, &lsa_drop_cmd);
install_element(ENABLE_NODE, &lsdb_create_cmd);
install_element(ENABLE_NODE, &lsdb_delete_cmd);
install_element(ENABLE_NODE, &lsdb_add_cmd);
install_element(ENABLE_NODE, &lsdb_remove_cmd);
install_element(ENABLE_NODE, &lsdb_walk_cmd);
install_element(ENABLE_NODE, &lsdb_walk_type_cmd);
install_element(ENABLE_NODE, &lsdb_walk_type_adv_cmd);
install_element(ENABLE_NODE, &lsdb_get_cmd);
}

72
tests/ospf6d/test_lsdb.in Normal file
View File

@ -0,0 +1,72 @@
lsa set 0 type 1 adv 1.2.3.4 id 0.0.0.1
lsa set 1 type 1 adv 1.2.3.4 id 0.0.0.2
lsa set 2 type 2 adv 1.2.3.4 id 0.0.0.3
lsa set 3 type 2 adv 128.2.3.4 id 0.0.0.4
lsa set 4 type 2 adv 128.2.3.4 id 0.0.0.5
lsa set 5 type 3 adv 0.0.0.1 id 0.0.0.6
lsa refcounts
lsdb create
lsdb walk
lsdb walk type 1
lsdb walk type 2
lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa refcounts
lsdb add 0
lsdb add 1
lsa refcounts
lsdb walk
lsdb walk type 1
lsdb walk type 2
lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa refcounts
lsdb remove 0
lsdb add 2
lsdb add 3
lsdb add 4
lsa refcounts
lsdb walk
lsdb walk type 1
lsdb walk type 2
lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa refcounts
lsdb add 5
lsa refcounts
lsdb walk
lsdb walk type 1
lsdb walk type 2
lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa refcounts
lsdb remove 1
lsdb remove 5
lsa refcounts
lsdb walk
lsdb walk type 1
lsdb walk type 2
lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa refcounts
lsdb delete
lsa refcounts
lsa drop 0
lsa drop 1
lsa drop 2
lsa drop 3
lsa drop 4
lsa drop 5

View File

@ -0,0 +1,4 @@
import frrtest
class TestLSDB(frrtest.TestRefOut):
program = './test_lsdb'

View File

@ -0,0 +1,192 @@
test# lsa set 0 type 1 adv 1.2.3.4 id 0.0.0.1
test# lsa set 1 type 1 adv 1.2.3.4 id 0.0.0.2
test# lsa set 2 type 2 adv 1.2.3.4 id 0.0.0.3
test# lsa set 3 type 2 adv 128.2.3.4 id 0.0.0.4
test# lsa set 4 type 2 adv 128.2.3.4 id 0.0.0.5
test# lsa set 5 type 3 adv 0.0.0.1 id 0.0.0.6
test# lsa refcounts
[0] 1
[1] 1
[2] 1
[3] 1
[4] 1
[5] 1
test#
test# lsdb create
test#
test# lsdb walk
0 entries.
test# lsdb walk type 1
0 entries.
test# lsdb walk type 2
0 entries.
test# lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsa = NULL
test# lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa = NULL
test# lsa refcounts
[0] 1
[1] 1
[2] 1
[3] 1
[4] 1
[5] 1
test#
test# lsdb add 0
test# lsdb add 1
test# lsa refcounts
[0] 2
[1] 2
[2] 1
[3] 1
[4] 1
[5] 1
test#
test# lsdb walk
type 1 adv 1.2.3.4 id 0.0.0.1
type 1 adv 1.2.3.4 id 0.0.0.2
2 entries.
test# lsdb walk type 1
type 1 adv 1.2.3.4 id 0.0.0.1
type 1 adv 1.2.3.4 id 0.0.0.2
2 entries.
test# lsdb walk type 2
0 entries.
test# lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
type 1 adv 1.2.3.4 id 0.0.0.2
test# lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
lsa = NULL
test# lsa refcounts
[0] 2
[1] 2
[2] 1
[3] 1
[4] 1
[5] 1
test#
test# lsdb remove 0
test# lsdb add 2
test# lsdb add 3
test# lsdb add 4
test# lsa refcounts
[0] 1
[1] 2
[2] 2
[3] 2
[4] 2
[5] 1
test#
test# lsdb walk
type 1 adv 1.2.3.4 id 0.0.0.2
type 2 adv 1.2.3.4 id 0.0.0.3
type 2 adv 128.2.3.4 id 0.0.0.4
type 2 adv 128.2.3.4 id 0.0.0.5
4 entries.
test# lsdb walk type 1
type 1 adv 1.2.3.4 id 0.0.0.2
1 entries.
test# lsdb walk type 2
type 2 adv 1.2.3.4 id 0.0.0.3
type 2 adv 128.2.3.4 id 0.0.0.4
type 2 adv 128.2.3.4 id 0.0.0.5
3 entries.
test# lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
type 1 adv 1.2.3.4 id 0.0.0.2
test# lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
type 2 adv 1.2.3.4 id 0.0.0.3
test# lsa refcounts
[0] 1
[1] 2
[2] 2
[3] 2
[4] 2
[5] 1
test#
test# lsdb add 5
test# lsa refcounts
[0] 1
[1] 2
[2] 2
[3] 2
[4] 2
[5] 2
test#
test# lsdb walk
type 1 adv 1.2.3.4 id 0.0.0.2
type 2 adv 1.2.3.4 id 0.0.0.3
type 2 adv 128.2.3.4 id 0.0.0.4
type 2 adv 128.2.3.4 id 0.0.0.5
type 3 adv 0.0.0.1 id 0.0.0.6
5 entries.
test# lsdb walk type 1
type 1 adv 1.2.3.4 id 0.0.0.2
1 entries.
test# lsdb walk type 2
type 2 adv 1.2.3.4 id 0.0.0.3
type 2 adv 128.2.3.4 id 0.0.0.4
type 2 adv 128.2.3.4 id 0.0.0.5
3 entries.
test# lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
type 1 adv 1.2.3.4 id 0.0.0.2
test# lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
type 2 adv 1.2.3.4 id 0.0.0.3
test# lsa refcounts
[0] 1
[1] 2
[2] 2
[3] 2
[4] 2
[5] 2
test#
test# lsdb remove 1
test# lsdb remove 5
test# lsa refcounts
[0] 1
[1] 1
[2] 2
[3] 2
[4] 2
[5] 1
test#
test# lsdb walk
type 2 adv 1.2.3.4 id 0.0.0.3
type 2 adv 128.2.3.4 id 0.0.0.4
type 2 adv 128.2.3.4 id 0.0.0.5
3 entries.
test# lsdb walk type 1
0 entries.
test# lsdb walk type 2
type 2 adv 1.2.3.4 id 0.0.0.3
type 2 adv 128.2.3.4 id 0.0.0.4
type 2 adv 128.2.3.4 id 0.0.0.5
3 entries.
test# lsdb get type 1 adv 1.2.3.4 id 0.0.0.2
lsa = NULL
test# lsdb get-next type 1 adv 1.2.3.4 id 0.0.0.2
type 2 adv 1.2.3.4 id 0.0.0.3
test# lsa refcounts
[0] 1
[1] 1
[2] 2
[3] 2
[4] 2
[5] 1
test#
test# lsdb delete
test#
test# lsa refcounts
[0] 1
[1] 1
[2] 1
[3] 1
[4] 1
[5] 1
test# lsa drop 0
test# lsa drop 1
test# lsa drop 2
test# lsa drop 3
test# lsa drop 4
test# lsa drop 5
test#
test#
end.