GRE over IPv6

Refactors the GRE node to work with both IPv4 and IPv6 transports.

Note that this changes the binary configuration API to support both
address families; each address uses the same memory for either
address type and a flag to indicate which is in use.

The CLI and VAT syntax remains unchanged; the code detects whether
an IPv4 or an IPv6 address was given.

Configuration examples:

IPv4 CLI: create gre tunnel src 192.168.1.1 dst 192.168.1.2
IPv6 CLI: create gre tunnel src 2620:124:9000::1 dst 2620:124:9000::2

IPv4 VAT: gre_add_del_tunnel src 192.168.1.1 dst 192.168.1.2
IPv6 VAT: gre_add_del_tunnel src 2620:124:9000::1 dst 2620:124:9000::2

Change-Id: Ica8ee775dc101047fb8cd41617ddc8fafc2741b0
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
diff --git a/src/vnet/gre/gre.h b/src/vnet/gre/gre.h
index 788cba2..ad3e025 100644
--- a/src/vnet/gre/gre.h
+++ b/src/vnet/gre/gre.h
@@ -21,8 +21,6 @@
 #include <vnet/vnet.h>
 #include <vnet/gre/packet.h>
 #include <vnet/ip/ip.h>
-#include <vnet/ip/ip4.h>
-#include <vnet/ip/ip4_packet.h>
 #include <vnet/pg/pg.h>
 #include <vnet/ip/format.h>
 #include <vnet/adj/adj_types.h>
@@ -87,11 +85,11 @@
   /**
    * The tunnel's source/local address
    */
-  ip4_address_t tunnel_src;
+  ip46_address_t tunnel_src;
   /**
    * The tunnel's destination/remote address
    */
-  ip4_address_t tunnel_dst;
+  fib_prefix_t tunnel_dst;
   /**
    * The FIB in which the src.dst address are present
    */
@@ -142,10 +140,16 @@
    *  Hash tables mapping name/protocol to protocol info index.
    */
   uword * protocol_info_by_name, * protocol_info_by_protocol;
+
   /**
-   * Hash mapping src/dst addr pair to tunnel
+   * Hash mapping ipv4 src/dst addr pair to tunnel
    */
-  uword * tunnel_by_key;
+  uword * tunnel_by_key4;
+
+  /**
+     * Hash mapping ipv6 src/dst addr pair to tunnel
+     */
+    uword * tunnel_by_key6;
 
   /**
    * Free vlib hw_if_indices.
@@ -176,6 +180,14 @@
   gre_header_t gre;
 }) ip4_and_gre_header_t;
 
+/**
+ * @brief IPv6 and GRE header.
+ */
+typedef CLIB_PACKED (struct {
+  ip6_header_t ip6;
+  gre_header_t gre;
+}) ip6_and_gre_header_t;
+
 always_inline gre_protocol_info_t *
 gre_get_protocol_info (gre_main_t * em, gre_protocol_t protocol)
 {
@@ -204,7 +216,8 @@
 format_function_t format_gre_header;
 format_function_t format_gre_header_with_length;
 
-extern vlib_node_registration_t gre_input_node;
+extern vlib_node_registration_t gre4_input_node;
+extern vlib_node_registration_t gre6_input_node;
 extern vnet_device_class_t gre_device_class;
 extern vnet_device_class_t gre_device_teb_class;
 
@@ -228,7 +241,8 @@
 typedef struct {
   u8 is_add;
 
-  ip4_address_t src, dst;
+  ip46_address_t src, dst;
+  u8 is_ipv6;
   u32 outer_fib_id;
   u8 teb;
 } vnet_gre_add_del_tunnel_args_t;