ip: Move the IP6 fib into ip6_[m]fib.c

Type: improvement

reduce the compile time by moving the bihash includes out of ip[46].h

Signed-off-by: Neale Ranns <nranns@cisco.com>
Change-Id: I6b9216e10aff1013071f9238b3e1ebbdd205bd80
diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h
index bfddd6e..16d985f 100644
--- a/src/plugins/cnat/cnat_types.h
+++ b/src/plugins/cnat/cnat_types.h
@@ -16,6 +16,7 @@
 #ifndef __CNAT_TYPES_H__
 #define __CNAT_TYPES_H__
 
+#include <vppinfra/bihash_24_8.h>
 #include <vnet/fib/fib_node.h>
 #include <vnet/fib/fib_source.h>
 #include <vnet/ip/ip_types.h>
diff --git a/src/plugins/lisp/lisp-gpe/lisp_gpe_fwd_entry.c b/src/plugins/lisp/lisp-gpe/lisp_gpe_fwd_entry.c
index 334164c..00d5af4 100644
--- a/src/plugins/lisp/lisp-gpe/lisp_gpe_fwd_entry.c
+++ b/src/plugins/lisp/lisp-gpe/lisp_gpe_fwd_entry.c
@@ -20,8 +20,6 @@
 #include <vnet/fib/fib_table.h>
 #include <vnet/fib/fib_entry.h>
 #include <vnet/fib/fib_path_list.h>
-#include <vnet/fib/ip6_fib.h>
-#include <vnet/fib/ip4_fib.h>
 #include <vnet/dpo/drop_dpo.h>
 #include <vnet/dpo/lookup_dpo.h>
 #include <vnet/dpo/load_balance.h>
diff --git a/src/vnet/fib/ip6_fib.c b/src/vnet/fib/ip6_fib.c
index ddd7079..861edcc 100644
--- a/src/vnet/fib/ip6_fib.c
+++ b/src/vnet/fib/ip6_fib.c
@@ -20,6 +20,12 @@
 #include <vppinfra/bihash_24_8.h>
 #include <vppinfra/bihash_template.c>
 
+ip6_fib_table_instance_t ip6_fib_table[IP6_FIB_NUM_TABLES];
+
+/* ip6 lookup table config parameters */
+u32 ip6_fib_table_nbuckets;
+uword ip6_fib_table_size;
+
 static void
 vnet_ip6_fib_init (u32 fib_index)
 {
@@ -183,7 +189,7 @@
     int i, n_p, rv;
     u64 fib;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
     n_p = vec_len (table->prefix_lengths_in_search_order);
 
     kv.key[0] = addr->as_u64[0];
@@ -230,7 +236,7 @@
     u64 fib;
     int rv;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
     mask = &ip6_main.fib_masks[len];
     fib = ((u64)((fib_index))<<32);
 
@@ -283,7 +289,7 @@
     ip6_address_t *mask;
     u64 fib;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
     mask = &ip6_main.fib_masks[len];
     fib = ((u64)((fib_index))<<32);
 
@@ -315,7 +321,7 @@
     ip6_address_t *mask;
     u64 fib;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
     mask = &ip6_main.fib_masks[len];
     fib = ((u64)((fib_index))<<32);
 
@@ -368,7 +374,7 @@
     ip6_address_t *mask;
     u64 fib;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_FWDING];
     mask = &ip6_main.fib_masks[len];
     fib = ((u64)((fib_index))<<32);
 
@@ -399,7 +405,7 @@
     ip6_address_t *mask;
     u64 fib;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_FWDING];
     mask = &ip6_main.fib_masks[len];
     fib = ((u64)((fib_index))<<32);
 
@@ -511,7 +517,7 @@
     };
 
     clib_bihash_foreach_key_value_pair_24_8(
-        &ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
+        &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
         ip6_fib_walk_cb,
         &ctx);
 
@@ -532,7 +538,7 @@
     };
 
     clib_bihash_foreach_key_value_pair_24_8(
-        &ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
+        &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
         ip6_fib_walk_cb,
         &ctx);
 }
@@ -595,8 +601,8 @@
 {
     uword bytes_inuse;
 
-    bytes_inuse = (alloc_arena_next(&(ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash)) +
-                   alloc_arena_next(&(ip6_main.ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash)));
+    bytes_inuse = (alloc_arena_next(&(ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash)) +
+                   alloc_arena_next(&(ip6_fib_table[IP6_FIB_TABLE_FWDING].ip6_hash)));
 
     s = format(s, "%=30s %=6d %=12ld\n",
                "IPv6 unicast",
@@ -681,11 +687,11 @@
     {
         vlib_cli_output (vm, "IPv6 Non-Forwarding Hash Table:\n%U\n",
                          BV (format_bihash),
-                         &im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
+                         &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
                          detail);
         vlib_cli_output (vm, "IPv6 Forwarding Hash Table:\n%U\n",
                          BV (format_bihash),
-                         &im6->ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash,
+                         &ip6_fib_table[IP6_FIB_TABLE_FWDING].ip6_hash,
                          detail);
         return (NULL);
     }
@@ -728,7 +734,7 @@
 	/* Show summary? */
 	if (! verbose)
 	{
-	    clib_bihash_24_8_t * h = &im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
+	    clib_bihash_24_8_t * h = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
 	    int len;
 
 	    vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count");
@@ -862,3 +868,55 @@
     .function = ip6_show_fib,
 };
 /* *INDENT-ON* */
+
+static clib_error_t *
+ip6_config (vlib_main_t * vm, unformat_input_t * input)
+{
+  uword heapsize = 0;
+  u32 nbuckets = 0;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "hash-buckets %d", &nbuckets))
+          ;
+      else if (unformat (input, "heap-size %U",
+			 unformat_memory_size, &heapsize))
+	;
+      else
+	return clib_error_return (0, "unknown input '%U'",
+				  format_unformat_error, input);
+    }
+
+  ip6_fib_table_nbuckets = nbuckets;
+  ip6_fib_table_size = heapsize;
+
+  return 0;
+}
+
+VLIB_EARLY_CONFIG_FUNCTION (ip6_config, "ip6");
+
+static clib_error_t *
+ip6_fib_init (vlib_main_t * vm)
+{
+    if (ip6_fib_table_nbuckets == 0)
+        ip6_fib_table_nbuckets = IP6_FIB_DEFAULT_HASH_NUM_BUCKETS;
+
+    ip6_fib_table_nbuckets = 1 << max_log2 (ip6_fib_table_nbuckets);
+
+    if (ip6_fib_table_size == 0)
+        ip6_fib_table_size = IP6_FIB_DEFAULT_HASH_MEMORY_SIZE;
+
+    clib_bihash_init_24_8 (&(ip6_fib_table[IP6_FIB_TABLE_FWDING].ip6_hash),
+                           "ip6 FIB fwding table",
+                           ip6_fib_table_nbuckets, ip6_fib_table_size);
+    clib_bihash_init_24_8 (&ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
+                           "ip6 FIB non-fwding table",
+                           ip6_fib_table_nbuckets, ip6_fib_table_size);
+
+    return (NULL);
+}
+
+VLIB_INIT_FUNCTION (ip6_fib_init) =
+{
+  .runs_before = VLIB_INITS("ip6_lookup_init"),
+};
diff --git a/src/vnet/fib/ip6_fib.h b/src/vnet/fib/ip6_fib.h
index 50b360b..706bebb 100644
--- a/src/vnet/fib/ip6_fib.h
+++ b/src/vnet/fib/ip6_fib.h
@@ -22,6 +22,54 @@
 #include <vnet/fib/fib_table.h>
 #include <vnet/ip/lookup.h>
 #include <vnet/dpo/load_balance.h>
+#include <vppinfra/bihash_24_8.h>
+#include <vppinfra/bihash_template.h>
+
+/*
+ * Default size of the ip6 fib hash table
+ */
+#define IP6_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
+#define IP6_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
+
+/**
+ * Enumeration of the FIB table instance types
+ */
+typedef enum ip6_fib_table_instance_type_t_
+{
+    /**
+     * This table stores the routes that are used to forward traffic.
+     * The key is the prefix, the result the adjacency to forward on.
+     */
+  IP6_FIB_TABLE_FWDING,
+    /**
+     * The table that stores ALL routes learned by the DP.
+     * Some of these routes may not be ready to install in forwarding
+     * at a given time.
+     * The key in this table is the prefix, the result is the fib_entry_t
+     */
+  IP6_FIB_TABLE_NON_FWDING,
+} ip6_fib_table_instance_type_t;
+
+#define IP6_FIB_NUM_TABLES (IP6_FIB_TABLE_NON_FWDING+1)
+
+/**
+ * A representation of a single IP6 table
+ */
+typedef struct ip6_fib_table_instance_t_
+{
+  /* The hash table */
+  clib_bihash_24_8_t ip6_hash;
+
+  /* bitmap / refcounts / vector of mask widths to search */
+  uword *non_empty_dst_address_length_bitmap;
+  u8 *prefix_lengths_in_search_order;
+  i32 dst_address_length_refcounts[129];
+} ip6_fib_table_instance_t;
+
+/**
+ * The two FIB tables; fwding and non-fwding
+ */
+extern ip6_fib_table_instance_t ip6_fib_table[IP6_FIB_NUM_TABLES];
 
 extern fib_node_index_t ip6_fib_table_lookup(u32 fib_index,
 					     const ip6_address_t *addr,
@@ -73,7 +121,7 @@
     int rv;
     u64 fib;
 
-    table = &ip6_main.ip6_table[IP6_FIB_TABLE_FWDING];
+    table = &ip6_fib_table[IP6_FIB_TABLE_FWDING];
     len = vec_len (table->prefix_lengths_in_search_order);
 
     kv.key[0] = dst->as_u64[0];
diff --git a/src/vnet/gre/interface.c b/src/vnet/gre/interface.c
index 3ea13e1..92e4f74 100644
--- a/src/vnet/gre/interface.c
+++ b/src/vnet/gre/interface.c
@@ -18,8 +18,7 @@
 #include <vnet/vnet.h>
 #include <vnet/gre/gre.h>
 #include <vnet/ip/format.h>
-#include <vnet/fib/ip4_fib.h>
-#include <vnet/fib/ip6_fib.h>
+#include <vnet/fib/fib_table.h>
 #include <vnet/adj/adj_midchain.h>
 #include <vnet/adj/adj_nbr.h>
 #include <vnet/mpls/mpls.h>
@@ -529,10 +528,9 @@
 {
   u32 outer_fib_index;
 
-  if (!a->is_ipv6)
-    outer_fib_index = ip4_fib_index_from_table_id (a->outer_table_id);
-  else
-    outer_fib_index = ip6_fib_index_from_table_id (a->outer_table_id);
+  outer_fib_index = fib_table_find ((a->is_ipv6 ?
+				     FIB_PROTOCOL_IP6 :
+				     FIB_PROTOCOL_IP4), a->outer_table_id);
 
   if (~0 == outer_fib_index)
     return VNET_API_ERROR_NO_SUCH_FIB;
diff --git a/src/vnet/interface.c b/src/vnet/interface.c
index 1cf63c7..f0ac40d 100644
--- a/src/vnet/interface.c
+++ b/src/vnet/interface.c
@@ -39,9 +39,9 @@
 
 #include <vnet/vnet.h>
 #include <vnet/plugin/plugin.h>
-#include <vnet/fib/ip6_fib.h>
 #include <vnet/adj/adj.h>
 #include <vnet/adj/adj_mcast.h>
+#include <vnet/ip/ip.h>
 
 typedef enum vnet_interface_helper_flags_t_
 {
diff --git a/src/vnet/ip/ip6.h b/src/vnet/ip/ip6.h
index ad70b7e..fcb1803 100644
--- a/src/vnet/ip/ip6.h
+++ b/src/vnet/ip/ip6.h
@@ -49,18 +49,9 @@
 #include <vnet/ip/lookup.h>
 #include <vnet/ip/ip_interface.h>
 #include <stdbool.h>
-#include <vppinfra/bihash_24_8.h>
-#include <vppinfra/bihash_40_8.h>
-#include <vppinfra/bihash_template.h>
 #include <vnet/util/radix.h>
 #include <vnet/util/throttle.h>
 
-/*
- * Default size of the ip6 fib hash table
- */
-#define IP6_FIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
-#define IP6_FIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
-
 typedef struct
 {
   ip6_address_t addr;
@@ -117,67 +108,8 @@
   uword function_opaque;
 } ip6_table_bind_callback_t;
 
-/**
- * Enumeration of the FIB table instance types
- */
-typedef enum ip6_fib_table_instance_type_t_
-{
-    /**
-     * This table stores the routes that are used to forward traffic.
-     * The key is the prefix, the result the adjacency to forward on.
-     */
-  IP6_FIB_TABLE_FWDING,
-    /**
-     * The table that stores ALL routes learned by the DP.
-     * Some of these routes may not be ready to install in forwarding
-     * at a given time.
-     * The key in this table is the prefix, the result is the fib_entry_t
-     */
-  IP6_FIB_TABLE_NON_FWDING,
-} ip6_fib_table_instance_type_t;
-
-#define IP6_FIB_NUM_TABLES (IP6_FIB_TABLE_NON_FWDING+1)
-
-/**
- * A representation of a single IP6 table
- */
-typedef struct ip6_fib_table_instance_t_
-{
-  /* The hash table */
-  clib_bihash_24_8_t ip6_hash;
-
-  /* bitmap / refcounts / vector of mask widths to search */
-  uword *non_empty_dst_address_length_bitmap;
-  u8 *prefix_lengths_in_search_order;
-  i32 dst_address_length_refcounts[129];
-} ip6_fib_table_instance_t;
-
-/**
- * A representation of a single IP6 mfib table
- */
-typedef struct ip6_mfib_table_instance_t_
-{
-  /* The hash table */
-  clib_bihash_40_8_t ip6_mhash;
-
-  /* bitmap / refcounts / vector of mask widths to search */
-  uword *non_empty_dst_address_length_bitmap;
-  u16 *prefix_lengths_in_search_order;
-  i32 dst_address_length_refcounts[257];
-} ip6_mfib_table_instance_t;
-
 typedef struct ip6_main_t
 {
-  /**
-   * The two FIB tables; fwding and non-fwding
-   */
-  ip6_fib_table_instance_t ip6_table[IP6_FIB_NUM_TABLES];
-
-  /**
-   * the single MFIB table
-   */
-  ip6_mfib_table_instance_t ip6_mtable;
-
   ip_lookup_main_t lookup_main;
 
   /* Pool of FIBs. */
@@ -219,10 +151,6 @@
   /** Functions to call when interface to table biding changes. */
   ip6_table_bind_callback_t *table_bind_callbacks;
 
-  /* ip6 lookup table config parameters */
-  u32 lookup_table_nbuckets;
-  uword lookup_table_size;
-
   /* Seed for Jenkins hash used to compute ip6 flow hash. */
   u32 flow_hash_seed;
 
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index 8c65560..294f632 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -2809,24 +2809,6 @@
 
   ip_lookup_init (&im->lookup_main, /* is_ip6 */ 1);
 
-  if (im->lookup_table_nbuckets == 0)
-    im->lookup_table_nbuckets = IP6_FIB_DEFAULT_HASH_NUM_BUCKETS;
-
-  im->lookup_table_nbuckets = 1 << max_log2 (im->lookup_table_nbuckets);
-
-  if (im->lookup_table_size == 0)
-    im->lookup_table_size = IP6_FIB_DEFAULT_HASH_MEMORY_SIZE;
-
-  clib_bihash_init_24_8 (&(im->ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash),
-			 "ip6 FIB fwding table",
-			 im->lookup_table_nbuckets, im->lookup_table_size);
-  clib_bihash_init_24_8 (&im->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
-			 "ip6 FIB non-fwding table",
-			 im->lookup_table_nbuckets, im->lookup_table_size);
-  clib_bihash_init_40_8 (&im->ip6_mtable.ip6_mhash,
-			 "ip6 mFIB table",
-			 im->lookup_table_nbuckets, im->lookup_table_size);
-
   /* Create FIB with index 0 and table id of 0. */
   fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, 0,
 				     FIB_SOURCE_DEFAULT_ROUTE);
@@ -3166,34 +3148,6 @@
 };
 /* *INDENT-ON* */
 
-static clib_error_t *
-ip6_config (vlib_main_t * vm, unformat_input_t * input)
-{
-  ip6_main_t *im = &ip6_main;
-  uword heapsize = 0;
-  u32 tmp;
-  u32 nbuckets = 0;
-
-  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
-    {
-      if (unformat (input, "hash-buckets %d", &tmp))
-	nbuckets = tmp;
-      else if (unformat (input, "heap-size %U",
-			 unformat_memory_size, &heapsize))
-	;
-      else
-	return clib_error_return (0, "unknown input '%U'",
-				  format_unformat_error, input);
-    }
-
-  im->lookup_table_nbuckets = nbuckets;
-  im->lookup_table_size = heapsize;
-
-  return 0;
-}
-
-VLIB_EARLY_CONFIG_FUNCTION (ip6_config, "ip6");
-
 /*
  * fd.io coding-style-patch-verification: ON
  *
diff --git a/src/vnet/ip/ip6_ll_table.c b/src/vnet/ip/ip6_ll_table.c
index 75489ea..e4010bc 100644
--- a/src/vnet/ip/ip6_ll_table.c
+++ b/src/vnet/ip/ip6_ll_table.c
@@ -232,7 +232,6 @@
 		 unformat_input_t * input, vlib_cli_command_t * cmd)
 {
   count_routes_in_fib_at_prefix_length_arg_t _ca, *ca = &_ca;
-  ip6_main_t *im6 = &ip6_main;
   fib_table_t *fib_table;
   int verbose, matching;
   ip6_address_t matching_address;
@@ -302,7 +301,7 @@
     if (!verbose)
       {
 	clib_bihash_24_8_t *h =
-	  &im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
+	  &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
 	int len;
 
 	vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count");
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c
index 2f02fa0..3f593c6 100644
--- a/src/vnet/ip/ip_api.c
+++ b/src/vnet/ip/ip_api.c
@@ -37,8 +37,6 @@
 #include <vnet/mfib/mfib_entry.h>
 #include <vnet/mfib/mfib_api.h>
 #include <vnet/ip/ip_source_and_port_range_check.h>
-#include <vnet/fib/ip4_fib.h>
-#include <vnet/fib/ip6_fib.h>
 #include <vnet/fib/fib_path_list.h>
 #include <vnet/ip/ip6_hop_by_hop.h>
 #include <vnet/ip/ip6_link.h>
diff --git a/src/vnet/ip6-nd/ip6_mld.c b/src/vnet/ip6-nd/ip6_mld.c
index 6e6a5ca..2a95c84 100644
--- a/src/vnet/ip6-nd/ip6_mld.c
+++ b/src/vnet/ip6-nd/ip6_mld.c
@@ -20,10 +20,11 @@
 #include <vnet/ip/ip.h>
 #include <vnet/ip-neighbor/ip_neighbor_dp.h>
 
-#include <vnet/fib/ip6_fib.h>
 #include <vnet/ip/ip6_link.h>
 #include <vnet/ip/ip6_ll_table.h>
 
+#include <vnet/ethernet/ethernet.h>
+
 /**
  * @file
  * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
diff --git a/src/vnet/l2/l2_learn.h b/src/vnet/l2/l2_learn.h
index 58e19ba..eea34ee 100644
--- a/src/vnet/l2/l2_learn.h
+++ b/src/vnet/l2/l2_learn.h
@@ -19,6 +19,7 @@
 #define included_l2learn_h
 
 #include <vlib/vlib.h>
+#include <vppinfra/bihash_8_8.h>
 #include <vnet/ethernet/ethernet.h>
 
 
diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c
index 6b3b8d9..14c724b 100644
--- a/src/vnet/mfib/ip6_mfib.c
+++ b/src/vnet/mfib/ip6_mfib.c
@@ -19,6 +19,8 @@
 #include <vnet/mfib/mfib_entry.h>
 #include <vnet/fib/ip6_fib.h>
 
+ip6_mfib_table_instance_t ip6_mfib_table;
+
 /**
  * Key and mask for radix
  */
@@ -333,7 +335,7 @@
 
     IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
 
-    rv = clib_bihash_search_inline_2_40_8(&ip6_main.ip6_mtable.ip6_mhash,
+    rv = clib_bihash_search_inline_2_40_8(&ip6_mfib_table.ip6_mhash,
                                           &key, &value);
     if (rv == 0)
 	return value.value;
@@ -356,7 +358,7 @@
     int i, n, len;
     int rv;
 
-    table = &ip6_main.ip6_mtable;
+    table = &ip6_mfib_table;
     n = vec_len (table->prefix_lengths_in_search_order);
 
     for (i = 0; i < n; i++)
@@ -421,7 +423,7 @@
     ip6_mfib_key_t key, value;
     int i, n, rv;
 
-    table = &ip6_main.ip6_mtable;
+    table = &ip6_mfib_table;
     n = vec_len (table->prefix_lengths_in_search_order);
 
     /*
@@ -471,7 +473,7 @@
     ip6_mfib_table_instance_t *table;
     ip6_mfib_key_t key;
 
-    table = &ip6_main.ip6_mtable;
+    table = &ip6_mfib_table;
     IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
     key.value = mfib_entry_index;
 
@@ -497,7 +499,7 @@
 
     IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
 
-    table = &ip6_main.ip6_mtable;
+    table = &ip6_mfib_table;
     clib_bihash_add_del_40_8(&table->ip6_mhash, &key, 0);
 
     ASSERT (table->dst_address_length_refcounts[len] > 0);
@@ -523,7 +525,7 @@
 {
     u64 bytes_inuse;
 
-    bytes_inuse = alloc_arena_next(&(ip6_main.ip6_mtable.ip6_mhash));
+    bytes_inuse = alloc_arena_next(&(ip6_mfib_table.ip6_mhash));
 
     s = format(s, "%=30s %=6d %=12ld\n",
                "IPv6 multicast",
@@ -634,7 +636,7 @@
     };
 
     clib_bihash_foreach_key_value_pair_40_8(
-        &ip6_main.ip6_mtable.ip6_mhash,
+        &ip6_mfib_table.ip6_mhash,
         ip6_mfib_walk_cb,
         &ctx);
 }
@@ -778,3 +780,19 @@
     .function = ip6_show_mfib,
 };
 /* *INDENT-ON* */
+
+static clib_error_t *
+ip6_mfib_init (vlib_main_t * vm)
+{
+    clib_bihash_init_40_8 (&ip6_mfib_table.ip6_mhash,
+                           "ip6 mFIB table",
+                           IP6_MFIB_DEFAULT_HASH_NUM_BUCKETS,
+                           IP6_MFIB_DEFAULT_HASH_MEMORY_SIZE);
+
+    return (NULL);
+}
+
+VLIB_INIT_FUNCTION (ip6_mfib_init) =
+{
+  .runs_before = VLIB_INITS("ip6_lookup_init"),
+};
diff --git a/src/vnet/mfib/ip6_mfib.h b/src/vnet/mfib/ip6_mfib.h
index f197b9d..67a821c 100644
--- a/src/vnet/mfib/ip6_mfib.h
+++ b/src/vnet/mfib/ip6_mfib.h
@@ -25,11 +25,40 @@
 #ifndef __IP6_MFIB_H__
 #define __IP6_MFIB_H__
 
+#include <vppinfra/bihash_40_8.h>
+#include <vppinfra/bihash_template.h>
+
 #include <vlib/vlib.h>
 #include <vnet/ip/ip.h>
 
 #include <vnet/mfib/mfib_table.h>
 
+/*
+ * Default size of the ip6 fib hash table
+ */
+#define IP6_MFIB_DEFAULT_HASH_NUM_BUCKETS (64 * 1024)
+#define IP6_MFIB_DEFAULT_HASH_MEMORY_SIZE (32<<20)
+
+
+/**
+ * A representation of a single IP6 mfib table
+ */
+typedef struct ip6_mfib_table_instance_t_
+{
+  /* The hash table */
+  clib_bihash_40_8_t ip6_mhash;
+
+  /* bitmap / refcounts / vector of mask widths to search */
+  uword *non_empty_dst_address_length_bitmap;
+  u16 *prefix_lengths_in_search_order;
+  i32 dst_address_length_refcounts[257];
+} ip6_mfib_table_instance_t;
+
+/**
+ * the single MFIB table
+ */
+extern ip6_mfib_table_instance_t ip6_mfib_table;
+
 extern fib_node_index_t ip6_mfib_table_lookup(const ip6_mfib_t *fib,
                                               const ip6_address_t *src,
                                               const ip6_address_t *grp,
diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h
index d76970f..ab34d9f 100644
--- a/src/vnet/session/transport_types.h
+++ b/src/vnet/session/transport_types.h
@@ -19,6 +19,8 @@
 #include <vnet/vnet.h>
 #include <vnet/ip/ip.h>
 #include <vnet/tcp/tcp_debug.h>
+#include <vppinfra/bihash_24_8.h>
+
 
 #define TRANSPORT_MAX_HDRS_LEN    140	/* Max number of bytes for headers */