bgpd: make bgp_table a wrapper around table library

Make the BGP table code a thin wrapper around the table implementation
in libzebra.

  * bgpd/bgp_table.[ch]

    - Use the ROUTE_NODE_FIELDS macro to embed the fields of a
      route_node in the bgp_node structure.

    - Add a route_table field to the bgp_table structure.

      Initialize the route_table with a delegate, such that the nodes
      in the table are bgp_node structures.

    - Add inline wrappers that call route_table functions underneath,
      and accept/return the correct BGP types.

  * bgpd/bgp_route.c

    Change some code to use inline wrappers instead of accessing
    fields of nodes/tables directly. The latter does not always work
    because the types of some fields need to be translated now.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h
index 53df0bc..ff42399 100644
--- a/bgpd/bgp_table.h
+++ b/bgpd/bgp_table.h
@@ -21,6 +21,8 @@
 #ifndef _QUAGGA_BGP_TABLE_H
 #define _QUAGGA_BGP_TABLE_H
 
+#include "table.h"
+
 typedef enum
 {
   BGP_TABLE_MAIN,
@@ -40,22 +42,20 @@
   /* The owner of this 'bgp_table' structure. */
   struct peer *owner;
 
-  struct bgp_node *top;
-  
-  unsigned long count;
+  struct route_table *route_table;
 };
 
 struct bgp_node
 {
-  struct prefix p;
-
-  struct bgp_table *table;
-  struct bgp_node *parent;
-  struct bgp_node *link[2];
-#define l_left   link[0]
-#define l_right  link[1]
-
-  void *info;
+  /*
+   * CAUTION
+   *
+   * These fields must be the very first fields in this structure.
+   *
+   * @see bgp_node_to_rnode
+   * @see bgp_node_from_rnode
+   */
+  ROUTE_NODE_FIELDS;
 
   struct bgp_adj_out *adj_out;
 
@@ -63,8 +63,6 @@
 
   struct bgp_node *prn;
 
-  int lock;
-
   u_char flags;
 #define BGP_NODE_PROCESS_SCHEDULED	(1 << 0)
 };
@@ -73,19 +71,207 @@
 extern void bgp_table_lock (struct bgp_table *);
 extern void bgp_table_unlock (struct bgp_table *);
 extern void bgp_table_finish (struct bgp_table **);
-extern void bgp_unlock_node (struct bgp_node *node);
-extern struct bgp_node *bgp_table_top (const struct bgp_table *const);
-extern struct bgp_node *bgp_route_next (struct bgp_node *);
-extern struct bgp_node *bgp_route_next_until (struct bgp_node *, struct bgp_node *);
-extern struct bgp_node *bgp_node_get (struct bgp_table *const, struct prefix *);
-extern struct bgp_node *bgp_node_lookup (const struct bgp_table *const, struct prefix *);
-extern struct bgp_node *bgp_lock_node (struct bgp_node *node);
-extern struct bgp_node *bgp_node_match (const struct bgp_table *, struct prefix *);
-extern struct bgp_node *bgp_node_match_ipv4 (const struct bgp_table *,
-					  struct in_addr *);
+
+
+/*
+ * bgp_node_from_rnode
+ *
+ * Returns the bgp_node structure corresponding to a route_node.
+ */
+static inline struct bgp_node *
+bgp_node_from_rnode (struct route_node *rnode)
+{
+  return (struct bgp_node *) rnode;
+}
+
+/*
+ * bgp_node_to_rnode
+ *
+ * Returns the route_node structure corresponding to a bgp_node.
+ */
+static inline struct route_node *
+bgp_node_to_rnode (struct bgp_node *node)
+{
+  return (struct route_node *) node;
+}
+
+/*
+ * bgp_node_table
+ *
+ * Returns the bgp_table that the given node is in.
+ */
+static inline struct bgp_table *
+bgp_node_table (struct bgp_node *node)
+{
+  return bgp_node_to_rnode (node)->table->info;
+}
+
+/*
+ * bgp_node_info
+ *
+ * Returns the 'info' pointer corresponding to a bgp node.
+ */
+static inline void *
+bgp_node_info (const struct bgp_node *node)
+{
+  return node->info;
+}
+
+/*
+ * bgp_node_set_info
+ */
+static inline void
+bgp_node_set_info (struct bgp_node *node, void *info)
+{
+  node->info = info;
+}
+
+/*
+ * bgp_node_prefix
+ */
+static inline struct prefix *
+bgp_node_prefix (struct bgp_node *node)
+{
+  return &node->p;
+}
+
+/*
+ * bgp_node_prefixlen
+ */
+static inline u_char
+bgp_node_prefixlen (struct bgp_node *node)
+{
+  return bgp_node_prefix (node)->prefixlen;
+}
+
+/*
+ * bgp_node_parent_nolock
+ *
+ * Gets the parent node of the given node without locking it.
+ */
+static inline struct bgp_node *
+bgp_node_parent_nolock (struct bgp_node *node)
+{
+  return bgp_node_from_rnode (node->parent);
+}
+
+/*
+ * bgp_unlock_node
+ */
+static inline void
+bgp_unlock_node (struct bgp_node *node)
+{
+  route_unlock_node (bgp_node_to_rnode (node));
+}
+
+/*
+ * bgp_table_top_nolock
+ *
+ * Gets the top node in the table without locking it.
+ *
+ * @see bgp_table_top
+ */
+static inline struct bgp_node *
+bgp_table_top_nolock (const struct bgp_table *const table)
+{
+  return bgp_node_from_rnode (table->route_table->top);
+}
+
+/*
+ * bgp_table_top
+ */
+static inline struct bgp_node *
+bgp_table_top (const struct bgp_table *const table)
+{
+  return bgp_node_from_rnode (route_top (table->route_table));
+}
+
+/*
+ * bgp_route_next
+ */
+static inline struct bgp_node *
+bgp_route_next (struct bgp_node *node)
+{
+  return bgp_node_from_rnode (route_next (bgp_node_to_rnode (node)));
+}
+
+/*
+ * bgp_route_next_until
+ */
+static inline struct bgp_node *
+bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
+{
+  struct route_node *rnode;
+
+  rnode = route_next_until (bgp_node_to_rnode (node),
+			    bgp_node_to_rnode (limit));
+  return bgp_node_from_rnode (rnode);
+}
+
+/*
+ * bgp_node_get
+ */
+static inline struct bgp_node *
+bgp_node_get (struct bgp_table *const table, struct prefix *p)
+{
+  return bgp_node_from_rnode (route_node_get (table->route_table, p));
+}
+
+/*
+ * bgp_node_lookup
+ */
+static inline struct bgp_node *
+bgp_node_lookup (const struct bgp_table *const table, struct prefix *p)
+{
+  return bgp_node_from_rnode (route_node_lookup (table->route_table, p));
+}
+
+/*
+ * bgp_lock_node
+ */
+static inline struct bgp_node *
+bgp_lock_node (struct bgp_node *node)
+{
+  return bgp_node_from_rnode (route_lock_node (bgp_node_to_rnode (node)));
+}
+
+/*
+ * bgp_node_match
+ */
+static inline struct bgp_node *
+bgp_node_match (const struct bgp_table *table, struct prefix *p)
+{
+  return bgp_node_from_rnode (route_node_match (table->route_table, p));
+}
+
+/*
+ * bgp_node_match_ipv4
+ */
+static inline struct bgp_node *
+bgp_node_match_ipv4 (const struct bgp_table *table, struct in_addr *addr)
+{
+  return bgp_node_from_rnode (route_node_match_ipv4 (table->route_table, 
+						     addr));
+}
+
 #ifdef HAVE_IPV6
-extern struct bgp_node *bgp_node_match_ipv6 (const struct bgp_table *,
-					  struct in6_addr *);
+
+/*
+ * bgp_node_match_ipv6
+ */
+static inline struct bgp_node *
+bgp_node_match_ipv6 (const struct bgp_table *table, struct in6_addr *addr)
+{
+  return bgp_node_from_rnode (route_node_match_ipv6 (table->route_table,
+						     addr));
+}
+
 #endif /* HAVE_IPV6 */
-extern unsigned long bgp_table_count (const struct bgp_table *const);
+
+static inline unsigned long
+bgp_table_count (const struct bgp_table *const table)
+{
+  return route_table_count (table->route_table);
+}
+
 #endif /* _QUAGGA_BGP_TABLE_H */