diff options
| author | Avneesh Sachdev <avneesh@opensourcerouting.org> | 2012-08-17 08:19:48 -0700 | 
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2012-09-26 21:48:49 +0200 | 
| commit | f9c1b7bb9b98342f1f3b0bfe3af01844f364dce9 (patch) | |
| tree | 350c8e0d98e4dcc53b126c6ce1c7568c440fcb06 /lib | |
| parent | 3eb8ef37bc463f88bfa36bd26fd43f7f6ad36c20 (diff) | |
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>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/table.c | 68 | ||||
| -rw-r--r-- | lib/table.h | 78 | 
2 files changed, 120 insertions, 26 deletions
diff --git a/lib/table.c b/lib/table.c index 7efb8c4f..6bbc9c62 100644 --- a/lib/table.c +++ b/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); +} diff --git a/lib/table.h b/lib/table.h index 1e8df46d..4d3eddb1 100644 --- a/lib/table.h +++ b/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 *);  | 
