mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 22:26:14 +00:00
lib: prepare table code for reuse by bgp_table
* lib/table.[ch] - Add a macro (ROUTE_NODE_FIELDS) that expands to all the fields of a route_node structure. - Add the route_table_delegate_t structure, a function vector which allows clients to customize the behavior of one or more tables. The delegate currently contains the 'create_node' and 'destroy_node' functions, and hence enables a table to use an alternative node structure. The alternative node is expected to embed the fields of a route_node using ROUTE_NODE_FIELDS. - Add route_table_init_with_delegate() to create a new table with a given delegate. - Make route_table_init() a thin wrapper around route_table_init_with_delegate(). The delegate it passes in simply creates/destroys route_node structures as before. - Add a user data pointer (info) to the route_table structure. This can be used by a client to keep per-table state. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
3eb8ef37bc
commit
f9c1b7bb9b
68
lib/table.c
68
lib/table.c
@ -30,12 +30,17 @@
|
||||
static void route_node_delete (struct route_node *);
|
||||
static void route_table_free (struct route_table *);
|
||||
|
||||
|
||||
/*
|
||||
* route_table_init_with_delegate
|
||||
*/
|
||||
struct route_table *
|
||||
route_table_init (void)
|
||||
route_table_init_with_delegate (route_table_delegate_t *delegate)
|
||||
{
|
||||
struct route_table *rt;
|
||||
|
||||
rt = XCALLOC (MTYPE_ROUTE_TABLE, sizeof (struct route_table));
|
||||
rt->delegate = delegate;
|
||||
return rt;
|
||||
}
|
||||
|
||||
@ -47,11 +52,9 @@ route_table_finish (struct route_table *rt)
|
||||
|
||||
/* Allocate new route node. */
|
||||
static struct route_node *
|
||||
route_node_new (void)
|
||||
route_node_new (struct route_table *table)
|
||||
{
|
||||
struct route_node *node;
|
||||
node = XCALLOC (MTYPE_ROUTE_NODE, sizeof (struct route_node));
|
||||
return node;
|
||||
return table->delegate->create_node (table->delegate, table);
|
||||
}
|
||||
|
||||
/* Allocate new route node with prefix set. */
|
||||
@ -60,7 +63,7 @@ route_node_set (struct route_table *table, struct prefix *prefix)
|
||||
{
|
||||
struct route_node *node;
|
||||
|
||||
node = route_node_new ();
|
||||
node = route_node_new (table);
|
||||
|
||||
prefix_copy (&node->p, prefix);
|
||||
node->table = table;
|
||||
@ -70,9 +73,9 @@ route_node_set (struct route_table *table, struct prefix *prefix)
|
||||
|
||||
/* Free route node. */
|
||||
static void
|
||||
route_node_free (struct route_node *node)
|
||||
route_node_free (struct route_table *table, struct route_node *node)
|
||||
{
|
||||
XFREE (MTYPE_ROUTE_NODE, node);
|
||||
table->delegate->destroy_node (table->delegate, table, node);
|
||||
}
|
||||
|
||||
/* Free route table. */
|
||||
@ -109,7 +112,7 @@ route_table_free (struct route_table *rt)
|
||||
|
||||
tmp_node->table->count--;
|
||||
tmp_node->lock = 0; /* to cause assert if unlocked after this */
|
||||
route_node_free (tmp_node);
|
||||
route_node_free (rt, tmp_node);
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
@ -314,7 +317,7 @@ route_node_get (struct route_table *const table, struct prefix *p)
|
||||
}
|
||||
else
|
||||
{
|
||||
new = route_node_new ();
|
||||
new = route_node_new (table);
|
||||
route_common (&node->p, p, &new->p);
|
||||
new->p.family = p->family;
|
||||
new->table = table;
|
||||
@ -374,7 +377,7 @@ route_node_delete (struct route_node *node)
|
||||
|
||||
node->table->count--;
|
||||
|
||||
route_node_free (node);
|
||||
route_node_free (node->table, node);
|
||||
|
||||
/* If parent node is stub then delete it also. */
|
||||
if (parent && parent->lock == 0)
|
||||
@ -482,3 +485,46 @@ route_table_count (const struct route_table *table)
|
||||
{
|
||||
return table->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* route_node_create
|
||||
*
|
||||
* Default function for creating a route node.
|
||||
*/
|
||||
static struct route_node *
|
||||
route_node_create (route_table_delegate_t *delegate,
|
||||
struct route_table *table)
|
||||
{
|
||||
struct route_node *node;
|
||||
node = XCALLOC (MTYPE_ROUTE_NODE, sizeof (struct route_node));
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* route_node_destroy
|
||||
*
|
||||
* Default function for destroying a route node.
|
||||
*/
|
||||
static void
|
||||
route_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
{
|
||||
XFREE (MTYPE_ROUTE_NODE, node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Default delegate.
|
||||
*/
|
||||
static route_table_delegate_t default_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = route_node_destroy
|
||||
};
|
||||
|
||||
/*
|
||||
* route_table_init
|
||||
*/
|
||||
struct route_table *
|
||||
route_table_init (void)
|
||||
{
|
||||
return route_table_init_with_delegate (&default_delegate);
|
||||
}
|
||||
|
78
lib/table.h
78
lib/table.h
@ -23,39 +23,87 @@
|
||||
#ifndef _ZEBRA_TABLE_H
|
||||
#define _ZEBRA_TABLE_H
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
struct route_node;
|
||||
struct route_table;
|
||||
|
||||
/*
|
||||
* route_table_delegate_t
|
||||
*
|
||||
* Function vector that can be used by a client to customize the
|
||||
* behavior of one or more route tables.
|
||||
*/
|
||||
typedef struct route_table_delegate_t_ route_table_delegate_t;
|
||||
|
||||
typedef struct route_node * (*route_table_create_node_func_t)
|
||||
(route_table_delegate_t *, struct route_table *);
|
||||
|
||||
typedef void (*route_table_destroy_node_func_t)
|
||||
(route_table_delegate_t *, struct route_table *, struct route_node *);
|
||||
|
||||
struct route_table_delegate_t_
|
||||
{
|
||||
route_table_create_node_func_t create_node;
|
||||
route_table_destroy_node_func_t destroy_node;
|
||||
};
|
||||
|
||||
/* Routing table top structure. */
|
||||
struct route_table
|
||||
{
|
||||
struct route_node *top;
|
||||
|
||||
/*
|
||||
* Delegate that performs certain functions for this table.
|
||||
*/
|
||||
route_table_delegate_t *delegate;
|
||||
|
||||
unsigned long count;
|
||||
|
||||
/*
|
||||
* User data.
|
||||
*/
|
||||
void *info;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macro that defines all fields in a route node.
|
||||
*/
|
||||
#define ROUTE_NODE_FIELDS \
|
||||
/* Actual prefix of this radix. */ \
|
||||
struct prefix p; \
|
||||
\
|
||||
/* Tree link. */ \
|
||||
struct route_table *table; \
|
||||
struct route_node *parent; \
|
||||
struct route_node *link[2]; \
|
||||
\
|
||||
/* Lock of this radix */ \
|
||||
unsigned int lock; \
|
||||
\
|
||||
/* Each node of route. */ \
|
||||
void *info; \
|
||||
\
|
||||
/* Aggregation. */ \
|
||||
void *aggregate;
|
||||
|
||||
|
||||
/* Each routing entry. */
|
||||
struct route_node
|
||||
{
|
||||
/* Actual prefix of this radix. */
|
||||
struct prefix p;
|
||||
ROUTE_NODE_FIELDS;
|
||||
|
||||
/* Tree link. */
|
||||
struct route_table *table;
|
||||
struct route_node *parent;
|
||||
struct route_node *link[2];
|
||||
#define l_left link[0]
|
||||
#define l_right link[1]
|
||||
|
||||
/* Lock of this radix */
|
||||
unsigned int lock;
|
||||
|
||||
/* Each node of route. */
|
||||
void *info;
|
||||
|
||||
/* Aggregation. */
|
||||
void *aggregate;
|
||||
};
|
||||
|
||||
/* Prototypes. */
|
||||
extern struct route_table *route_table_init (void);
|
||||
|
||||
extern struct route_table *
|
||||
route_table_init_with_delegate (route_table_delegate_t *);
|
||||
|
||||
extern void route_table_finish (struct route_table *);
|
||||
extern void route_unlock_node (struct route_node *node);
|
||||
extern struct route_node *route_top (struct route_table *);
|
||||
|
Loading…
Reference in New Issue
Block a user