IPSEC-GRE: fixes and API update to common types.

Change-Id: Icdcbac7453baa837a9c0c4a2401dff4a6aa6cba0
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c
index cf95588..e68accd 100644
--- a/src/vnet/ipsec/ah_decrypt.c
+++ b/src/vnet/ipsec/ah_decrypt.c
@@ -259,12 +259,9 @@
 	    }
 
 	  /* for IPSec-GRE tunnel next node is ipsec-gre-input */
-	  if (PREDICT_FALSE
-	      ((vnet_buffer (i_b0)->ipsec.flags) &
-	       IPSEC_FLAG_IPSEC_GRE_TUNNEL))
+	  if (PREDICT_FALSE (ipsec_sa_is_set_IS_GRE (sa0)))
 	    next0 = AH_DECRYPT_NEXT_IPSEC_GRE_INPUT;
 
-
 	  vnet_buffer (i_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
 	trace:
 	  if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED))
diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c
index 3e09d9d..c6cb439 100644
--- a/src/vnet/ipsec/esp_decrypt.c
+++ b/src/vnet/ipsec/esp_decrypt.c
@@ -396,7 +396,7 @@
 	    }
 	}
 
-      if (vnet_buffer (b[0])->ipsec.flags & IPSEC_FLAG_IPSEC_GRE_TUNNEL)
+      if (PREDICT_FALSE (ipsec_sa_is_set_IS_GRE (sa0)))
 	next[0] = ESP_DECRYPT_NEXT_IPSEC_GRE_INPUT;
 
     trace:
diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c
index 4c7242d..753d753 100644
--- a/src/vnet/ipsec/ipsec_api.c
+++ b/src/vnet/ipsec/ipsec_api.c
@@ -308,11 +308,18 @@
   ipsec_sa_flags_t flags = IPSEC_SA_FLAG_NONE;
   in = clib_net_to_host_u32 (in);
 
-#define _(v,f,s) if (in & IPSEC_API_SAD_FLAG_##f)    \
-    flags |= IPSEC_SA_FLAG_##f;
-  foreach_ipsec_sa_flags
-#undef _
-    return (flags);
+  if (in & IPSEC_API_SAD_FLAG_USE_ESN)
+    flags |= IPSEC_SA_FLAG_USE_ESN;
+  if (in & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
+    flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
+  if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL)
+    flags |= IPSEC_SA_FLAG_IS_TUNNEL;
+  if (in & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6)
+    flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
+  if (in & IPSEC_API_SAD_FLAG_UDP_ENCAP)
+    flags |= IPSEC_SA_FLAG_UDP_ENCAP;
+
+  return (flags);
 }
 
 static vl_api_ipsec_sad_flags_t
diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c
index dd99f78..a861655 100644
--- a/src/vnet/ipsec/ipsec_format.c
+++ b/src/vnet/ipsec/ipsec_format.c
@@ -244,6 +244,19 @@
 }
 
 u8 *
+format_ipsec_sa_flags (u8 * s, va_list * args)
+{
+  ipsec_sa_flags_t flags = va_arg (*args, int);
+
+  if (0)
+    ;
+#define _(v, f, str) else if (flags & IPSEC_SA_FLAG_##f) s = format(s, "%s ", str);
+  foreach_ipsec_sa_flags
+#undef _
+    return (s);
+}
+
+u8 *
 format_ipsec_sa (u8 * s, va_list * args)
 {
   u32 sai = va_arg (*args, u32);
@@ -254,15 +267,11 @@
 
   sa = pool_elt_at_index (im->sad, sai);
 
-  s = format (s, "[%d] sa 0x%x spi %u mode %s%s protocol %s%s%s%s",
+  s = format (s, "[%d] sa 0x%x spi %u mode %s%s protocol %s %U",
 	      sai, sa->id, sa->spi,
 	      ipsec_sa_is_set_IS_TUNNEL (sa) ? "tunnel" : "transport",
 	      ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? "-ip6" : "",
-	      sa->protocol ? "esp" : "ah",
-	      ipsec_sa_is_set_UDP_ENCAP (sa) ? " udp-encap-enabled" : "",
-	      ipsec_sa_is_set_USE_ANTI_REPLAY (sa) ? " anti-replay" : "",
-	      ipsec_sa_is_set_USE_ESN (sa) ?
-	      " extended-sequence-number" : "");
+	      sa->protocol ? "esp" : "ah", format_ipsec_sa_flags, sa->flags);
   s = format (s, "\n   seq %u seq-hi %u", sa->seq, sa->seq_hi);
   s = format (s, "\n   last-seq %u last-seq-hi %u window %U",
 	      sa->last_seq, sa->last_seq_hi,
diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c
index 17f28a0..bfdc2bb 100644
--- a/src/vnet/ipsec/ipsec_if.c
+++ b/src/vnet/ipsec/ipsec_if.c
@@ -429,7 +429,7 @@
 
 int
 ipsec_add_del_ipsec_gre_tunnel (vnet_main_t * vnm,
-				ipsec_add_del_ipsec_gre_tunnel_args_t * args)
+				const ipsec_gre_tunnel_add_del_args_t * args)
 {
   ipsec_tunnel_if_t *t = 0;
   ipsec_main_t *im = &ipsec_main;
@@ -441,22 +441,27 @@
   p = hash_get (im->sa_index_by_sa_id, args->local_sa_id);
   if (!p)
     return VNET_API_ERROR_INVALID_VALUE;
-  isa = p[0];
+  osa = p[0];
+  sa = pool_elt_at_index (im->sad, p[0]);
+  ipsec_sa_set_IS_GRE (sa);
 
   p = hash_get (im->sa_index_by_sa_id, args->remote_sa_id);
   if (!p)
     return VNET_API_ERROR_INVALID_VALUE;
-  osa = p[0];
+  isa = p[0];
   sa = pool_elt_at_index (im->sad, p[0]);
+  ipsec_sa_set_IS_GRE (sa);
 
+  /* we form the key from the input/remote SA whose tunnel is srouce
+   * at the remote end */
   if (ipsec_sa_is_set_IS_TUNNEL (sa))
     {
-      key.remote_ip = sa->tunnel_dst_addr.ip4.as_u32;
+      key.remote_ip = sa->tunnel_src_addr.ip4.as_u32;
       key.spi = clib_host_to_net_u32 (sa->spi);
     }
   else
     {
-      key.remote_ip = args->remote_ip.as_u32;
+      key.remote_ip = args->src.as_u32;
       key.spi = clib_host_to_net_u32 (sa->spi);
     }
 
diff --git a/src/vnet/ipsec/ipsec_if.h b/src/vnet/ipsec/ipsec_if.h
index 7f0eb08..34a1721 100644
--- a/src/vnet/ipsec/ipsec_if.h
+++ b/src/vnet/ipsec/ipsec_if.h
@@ -97,17 +97,18 @@
   u8 is_add;
   u32 local_sa_id;
   u32 remote_sa_id;
-  ip4_address_t local_ip;
-  ip4_address_t remote_ip;
-} ipsec_add_del_ipsec_gre_tunnel_args_t;
+  ip4_address_t src;
+  ip4_address_t dst;
+} ipsec_gre_tunnel_add_del_args_t;
 
 extern int ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
 					     ipsec_add_del_tunnel_args_t *
 					     args, u32 * sw_if_index);
 extern int ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args);
 extern int ipsec_add_del_ipsec_gre_tunnel (vnet_main_t * vnm,
-					   ipsec_add_del_ipsec_gre_tunnel_args_t
-					   * args);
+					   const
+					   ipsec_gre_tunnel_add_del_args_t *
+					   args);
 
 extern int ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index,
 				    ipsec_if_set_key_type_t type,
diff --git a/src/vnet/ipsec/ipsec_if_in.c b/src/vnet/ipsec/ipsec_if_in.c
index 63d463b..9ba2c10 100644
--- a/src/vnet/ipsec/ipsec_if_in.c
+++ b/src/vnet/ipsec/ipsec_if_in.c
@@ -197,6 +197,7 @@
 		}
 	      else
 		{
+		  b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
 		  n_no_tunnel++;
 		  next[0] = IPSEC_INPUT_NEXT_DROP;
 		  goto pkt1;
@@ -224,6 +225,7 @@
 		}
 	      else
 		{
+		  b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
 		  n_no_tunnel++;
 		  next[0] = IPSEC_INPUT_NEXT_DROP;
 		  goto pkt1;
@@ -236,7 +238,6 @@
 
       if (PREDICT_TRUE (t0->hw_if_index != ~0))
 	{
-	  vnet_buffer (b[0])->ipsec.flags = 0;
 	  sw_if_index0 = t0->sw_if_index;
 	  vnet_buffer (b[0])->sw_if_index[VLIB_RX] = sw_if_index0;
 
@@ -245,6 +246,7 @@
 	      vlib_increment_combined_counter
 		(drop_counter, thread_index, sw_if_index0, 1, len0);
 	      n_disabled++;
+	      b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_DISABLED];
 	      next[0] = IPSEC_INPUT_NEXT_DROP;
 	      goto pkt1;
 	    }
@@ -268,10 +270,6 @@
 	      n_bytes = len0;
 	    }
 	}
-      else
-	{
-	  vnet_buffer (b[0])->ipsec.flags = IPSEC_FLAG_IPSEC_GRE_TUNNEL;
-	}
 
     pkt1:
       if (is_ip6)
@@ -295,6 +293,7 @@
 		}
 	      else
 		{
+		  b[1]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
 		  n_no_tunnel++;
 		  next[1] = IPSEC_INPUT_NEXT_DROP;
 		  goto trace1;
@@ -322,6 +321,7 @@
 		}
 	      else
 		{
+		  b[1]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
 		  n_no_tunnel++;
 		  next[1] = IPSEC_INPUT_NEXT_DROP;
 		  goto trace1;
@@ -334,7 +334,6 @@
 
       if (PREDICT_TRUE (t1->hw_if_index != ~0))
 	{
-	  vnet_buffer (b[1])->ipsec.flags = 0;
 	  sw_if_index1 = t1->sw_if_index;
 	  vnet_buffer (b[1])->sw_if_index[VLIB_RX] = sw_if_index1;
 
@@ -343,6 +342,7 @@
 	      vlib_increment_combined_counter
 		(drop_counter, thread_index, sw_if_index1, 1, len1);
 	      n_disabled++;
+	      b[1]->error = node->errors[IPSEC_IF_INPUT_ERROR_DISABLED];
 	      next[1] = IPSEC_INPUT_NEXT_DROP;
 	      goto trace1;
 	    }
@@ -366,10 +366,6 @@
 	      n_bytes = len1;
 	    }
 	}
-      else
-	{
-	  vnet_buffer (b[1])->ipsec.flags = IPSEC_FLAG_IPSEC_GRE_TUNNEL;
-	}
 
     trace1:
       if (PREDICT_FALSE (is_trace))
@@ -460,6 +456,7 @@
 		}
 	      else
 		{
+		  b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
 		  n_no_tunnel++;
 		  next[0] = IPSEC_INPUT_NEXT_DROP;
 		  goto trace00;
@@ -487,6 +484,7 @@
 		}
 	      else
 		{
+		  b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_NO_TUNNEL];
 		  n_no_tunnel++;
 		  next[0] = IPSEC_INPUT_NEXT_DROP;
 		  goto trace00;
@@ -499,7 +497,6 @@
 
       if (PREDICT_TRUE (t0->hw_if_index != ~0))
 	{
-	  vnet_buffer (b[0])->ipsec.flags = 0;
 	  sw_if_index0 = t0->sw_if_index;
 	  vnet_buffer (b[0])->sw_if_index[VLIB_RX] = sw_if_index0;
 
@@ -508,6 +505,7 @@
 	      vlib_increment_combined_counter
 		(drop_counter, thread_index, sw_if_index0, 1, len0);
 	      n_disabled++;
+	      b[0]->error = node->errors[IPSEC_IF_INPUT_ERROR_DISABLED];
 	      next[0] = IPSEC_INPUT_NEXT_DROP;
 	      goto trace00;
 	    }
@@ -531,10 +529,6 @@
 	      n_bytes = len0;
 	    }
 	}
-      else
-	{
-	  vnet_buffer (b[0])->ipsec.flags = IPSEC_FLAG_IPSEC_GRE_TUNNEL;
-	}
 
     trace00:
       if (PREDICT_FALSE (is_trace))
@@ -563,11 +557,8 @@
 
   vlib_node_increment_counter (vm, node->node_index,
 			       IPSEC_IF_INPUT_ERROR_RX,
-			       from_frame->n_vectors - n_disabled);
-  vlib_node_increment_counter (vm, node->node_index,
-			       IPSEC_IF_INPUT_ERROR_DISABLED, n_disabled);
-  vlib_node_increment_counter (vm, node->node_index,
-			       IPSEC_IF_INPUT_ERROR_NO_TUNNEL, n_no_tunnel);
+			       from_frame->n_vectors - (n_disabled +
+							n_no_tunnel));
 
   vlib_buffer_enqueue_to_next (vm, node, from, nexts, from_frame->n_vectors);
 
diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c
index 970211e..5be72c3 100644
--- a/src/vnet/ipsec/ipsec_input.c
+++ b/src/vnet/ipsec/ipsec_input.c
@@ -253,7 +253,6 @@
 		     clib_net_to_host_u16 (ip0->length));
 
 		  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-		  vnet_buffer (b0)->ipsec.flags = 0;
 		  next0 = im->esp4_decrypt_next_index;
 		  vlib_buffer_advance (b0, ((u8 *) esp0 - (u8 *) ip0));
 		  goto trace0;
@@ -304,7 +303,6 @@
 		     clib_net_to_host_u16 (ip0->length));
 
 		  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-		  vnet_buffer (b0)->ipsec.flags = 0;
 		  next0 = im->ah4_decrypt_next_index;
 		  goto trace1;
 		}
@@ -450,7 +448,6 @@
 		     header_size);
 
 		  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-		  vnet_buffer (b0)->ipsec.flags = 0;
 		  next0 = im->esp6_decrypt_next_index;
 		  vlib_buffer_advance (b0, header_size);
 		  goto trace0;
@@ -479,7 +476,6 @@
 		     header_size);
 
 		  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-		  vnet_buffer (b0)->ipsec.flags = 0;
 		  next0 = im->ah6_decrypt_next_index;
 		  goto trace0;
 		}
diff --git a/src/vnet/ipsec/ipsec_io.h b/src/vnet/ipsec/ipsec_io.h
index c180a78..f156b48 100644
--- a/src/vnet/ipsec/ipsec_io.h
+++ b/src/vnet/ipsec/ipsec_io.h
@@ -15,8 +15,6 @@
 #ifndef __IPSEC_IO_H__
 #define __IPSEC_IO_H__
 
-#define IPSEC_FLAG_IPSEC_GRE_TUNNEL (1 << 0)
-
 #define foreach_ipsec_output_next  \
   _ (DROP, "error-drop")
 
diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h
index 94f1554..cfb44b9 100644
--- a/src/vnet/ipsec/ipsec_sa.h
+++ b/src/vnet/ipsec/ipsec_sa.h
@@ -90,6 +90,7 @@
   _ (4, IS_TUNNEL, "tunnel")                              \
   _ (8, IS_TUNNEL_V6, "tunnel-v6")                        \
   _ (16, UDP_ENCAP, "udp-encap")                          \
+  _ (32, IS_GRE, "GRE")                                   \
 
 typedef enum ipsec_sad_flags_t_
 {