Browse Source

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>
Avneesh Sachdev 7 years ago
parent
commit
f9c1b7bb9b
2 changed files with 120 additions and 26 deletions
  1. 57 11
      lib/table.c
  2. 63 15
      lib/table.h

+ 57 - 11
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);
+}

+ 63 - 15
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 *);