fib: supporting inner flow hash on tunnels

Change-Id: I53011e089bfecb08483792029b534b09b9e33a10
Type: improvement
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
diff --git a/src/vnet/gre/gre.api b/src/vnet/gre/gre.api
index f4e0253..9c69ba4 100644
--- a/src/vnet/gre/gre.api
+++ b/src/vnet/gre/gre.api
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-option version = "2.1.0";
+option version = "2.1.1";
 
 import "vnet/interface_types.api";
 import "vnet/tunnel/tunnel_types.api";
diff --git a/src/vnet/gre/gre.c b/src/vnet/gre/gre.c
index 5b102ae..d842d68 100644
--- a/src/vnet/gre/gre.c
+++ b/src/vnet/gre/gre.c
@@ -410,7 +410,11 @@
 
   ti = gm->tunnel_index_by_sw_if_index[sw_if_index];
   t = pool_elt_at_index (gm->tunnels, ti);
-  af = ADJ_FLAG_MIDCHAIN_IP_STACK;
+
+  if (t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH)
+    af = ADJ_FLAG_MIDCHAIN_FIXUP_FLOW_HASH;
+  else
+    af = ADJ_FLAG_MIDCHAIN_IP_STACK;
 
   if (VNET_LINK_ETHERNET == adj_get_link_type (ai))
     af |= ADJ_FLAG_MIDCHAIN_NO_COUNT;
@@ -429,12 +433,18 @@
 mgre_mk_complete_walk (adj_index_t ai, void *data)
 {
   mgre_walk_ctx_t *ctx = data;
+  adj_flags_t af;
+
+  if (ctx->t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH)
+    af = ADJ_FLAG_MIDCHAIN_FIXUP_FLOW_HASH;
+  else
+    af = ADJ_FLAG_MIDCHAIN_IP_STACK;
 
   adj_nbr_midchain_update_rewrite
     (ai, gre_get_fixup (ctx->t->tunnel_dst.fp_proto,
 			adj_get_link_type (ai)),
      uword_to_pointer (ctx->t->flags, void *),
-     ADJ_FLAG_MIDCHAIN_IP_STACK,
+     af,
      gre_build_rewrite (vnet_get_main (),
 			ctx->t->sw_if_index,
 			adj_get_link_type (ai),
diff --git a/src/vnet/ipip/ipip.api b/src/vnet/ipip/ipip.api
index 4fbfa1d..2740a51 100644
--- a/src/vnet/ipip/ipip.api
+++ b/src/vnet/ipip/ipip.api
@@ -49,7 +49,7 @@
  *
  */
 
-option version = "2.0.1";
+option version = "2.0.2";
 
 import "vnet/interface_types.api";
 import "vnet/ip/ip_types.api";
diff --git a/src/vnet/ipip/ipip.c b/src/vnet/ipip/ipip.c
index 87aba12..357eb58 100644
--- a/src/vnet/ipip/ipip.c
+++ b/src/vnet/ipip/ipip.c
@@ -288,7 +288,11 @@
   if (!t)
     return;
 
-  af = ADJ_FLAG_MIDCHAIN_IP_STACK;
+  if (t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH)
+    af = ADJ_FLAG_MIDCHAIN_FIXUP_FLOW_HASH;
+  else
+    af = ADJ_FLAG_MIDCHAIN_IP_STACK;
+
   if (VNET_LINK_ETHERNET == adj_get_link_type (ai))
     af |= ADJ_FLAG_MIDCHAIN_NO_COUNT;
 
@@ -317,14 +321,18 @@
   af = ADJ_FLAG_NONE;
   fixup = ipip_get_fixup (ctx->t, adj_get_link_type (ai), &af);
 
+  if (ctx->t->flags & TUNNEL_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH)
+    af = ADJ_FLAG_MIDCHAIN_FIXUP_FLOW_HASH;
+  else
+    af = ADJ_FLAG_MIDCHAIN_IP_STACK;
+
   adj_nbr_midchain_update_rewrite
     (ai, fixup,
      uword_to_pointer (ctx->t->flags, void *),
-     ADJ_FLAG_MIDCHAIN_IP_STACK, ipip_build_rewrite (vnet_get_main (),
-						     ctx->t->sw_if_index,
-						     adj_get_link_type (ai),
-						     &teib_entry_get_nh
-						     (ctx->ne)->fp_addr));
+     af, ipip_build_rewrite (vnet_get_main (),
+			     ctx->t->sw_if_index,
+			     adj_get_link_type (ai),
+			     &teib_entry_get_nh (ctx->ne)->fp_addr));
 
   teib_entry_adj_stack (ctx->ne, ai);
 
diff --git a/src/vnet/tunnel/tunnel.h b/src/vnet/tunnel/tunnel.h
index 6c97fc1..de06b60 100644
--- a/src/vnet/tunnel/tunnel.h
+++ b/src/vnet/tunnel/tunnel.h
@@ -43,7 +43,8 @@
   _(ENCAP_SET_DF, "encap-set-df", 0x2)              \
   _(ENCAP_COPY_DSCP, "encap-copy-dscp", 0x4)        \
   _(ENCAP_COPY_ECN, "encap-copy-ecn", 0x8)          \
-  _(DECAP_COPY_ECN, "decap-copy-ecn", 0x10)
+  _(DECAP_COPY_ECN, "decap-copy-ecn", 0x10)         \
+  _(ENCAP_INNER_HASH, "encap-inner-hash", 0x20)
 
 typedef enum tunnel_encap_decap_flags_t_
 {
diff --git a/src/vnet/tunnel/tunnel_types.api b/src/vnet/tunnel/tunnel_types.api
index 9835489..d193405 100644
--- a/src/vnet/tunnel/tunnel_types.api
+++ b/src/vnet/tunnel/tunnel_types.api
@@ -30,6 +30,8 @@
   TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_COPY_ECN = 0x8,
   /** at decap, copy the ECN bit of the tunnel header into the payload */
   TUNNEL_API_ENCAP_DECAP_FLAG_DECAP_COPY_ECN = 0x10,
+  /** at encap, compute flow hash on the inner packet for more entropy */
+  TUNNEL_API_ENCAP_DECAP_FLAG_ENCAP_INNER_HASH = 0x20 [backwards_compatible],
 };
 
 /**