ipsec: One DPO per SA

An SA can be used only for ESP or AH nver both, so it needs only one
coresponding DPO.

Type: refactor

Change-Id: I689060f795ee352245a0eaed0890a6b234c63d71
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c
index 1620f87..d12ca67 100644
--- a/src/vnet/ipsec/ah_encrypt.c
+++ b/src/vnet/ipsec/ah_encrypt.c
@@ -294,9 +294,8 @@
 			    &sa0->ip4_hdr.address_pair,
 			    sizeof (ip4_address_t));
 
-	  next[0] = sa0->dpo[IPSEC_PROTOCOL_AH].dpoi_next_node;
-	  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] =
-	    sa0->dpo[IPSEC_PROTOCOL_AH].dpoi_index;
+	  next[0] = sa0->dpo.dpoi_next_node;
+	  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = sa0->dpo.dpoi_index;
 	}
       else if (is_ip6 && ipsec_sa_is_set_IS_TUNNEL (sa0) &&
 	       ipsec_sa_is_set_IS_TUNNEL_V6 (sa0))
@@ -304,9 +303,8 @@
 	  clib_memcpy_fast (&oh6_0->ip6.src_address,
 			    &sa0->ip6_hdr.src_address,
 			    sizeof (ip6_address_t) * 2);
-	  next[0] = sa0->dpo[IPSEC_PROTOCOL_AH].dpoi_next_node;
-	  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] =
-	    sa0->dpo[IPSEC_PROTOCOL_AH].dpoi_index;
+	  next[0] = sa0->dpo.dpoi_next_node;
+	  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = sa0->dpo.dpoi_index;
 	}
 
       if (PREDICT_TRUE (sa0->integ_op_id))
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index ef1f5bb..d7cda05 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -367,7 +367,7 @@
 	      esp_update_ip4_hdr (ip4, len, /* is_transport */ 0, 0);
 	    }
 
-	  dpo = sa0->dpo + IPSEC_PROTOCOL_ESP;
+	  dpo = &sa0->dpo;
 	  if (!is_tun)
 	    {
 	      next[0] = dpo->dpoi_next_node;
diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c
index 5bcfcdb..d0d073b 100644
--- a/src/vnet/ipsec/ipsec_format.c
+++ b/src/vnet/ipsec/ipsec_format.c
@@ -326,9 +326,7 @@
 	    format (s, "\n    resovle via fib-entry: %d",
 		    sa->fib_entry_index);
 	  s = format (s, "\n    stacked on:");
-	  s =
-	    format (s, "\n      %U", format_dpo_id,
-		    &sa->dpo[IPSEC_PROTOCOL_ESP], 6);
+	  s = format (s, "\n      %U", format_dpo_id, &sa->dpo, 6);
 	}
     }
 
diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c
index 633f640..e8a0159 100644
--- a/src/vnet/ipsec/ipsec_sa.c
+++ b/src/vnet/ipsec/ipsec_sa.c
@@ -80,14 +80,14 @@
 
   fib_entry_contribute_forwarding (sa->fib_entry_index, fct, &tmp);
 
-  dpo_stack_from_node ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
-			im->ah6_encrypt_node_index :
-			im->ah4_encrypt_node_index),
-		       &sa->dpo[IPSEC_PROTOCOL_AH], &tmp);
-  dpo_stack_from_node ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
-			im->esp6_encrypt_node_index :
-			im->esp4_encrypt_node_index),
-		       &sa->dpo[IPSEC_PROTOCOL_ESP], &tmp);
+  if (IPSEC_PROTOCOL_AH == sa->protocol)
+    dpo_stack_from_node ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
+			  im->ah6_encrypt_node_index :
+			  im->ah4_encrypt_node_index), &sa->dpo, &tmp);
+  else
+    dpo_stack_from_node ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
+			  im->esp6_encrypt_node_index :
+			  im->esp4_encrypt_node_index), &sa->dpo, &tmp);
   dpo_reset (&tmp);
 }
 
@@ -305,8 +305,7 @@
       fib_table_entry_special_remove
 	(sa->tx_fib_index,
 	 fib_entry_get_prefix (sa->fib_entry_index), FIB_SOURCE_RR);
-      dpo_reset (&sa->dpo[IPSEC_PROTOCOL_AH]);
-      dpo_reset (&sa->dpo[IPSEC_PROTOCOL_ESP]);
+      dpo_reset (&sa->dpo);
     }
   vnet_crypto_key_del (vm, sa->crypto_key_index);
   vnet_crypto_key_del (vm, sa->integ_key_index);
diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h
index 969b5d1..53035aa 100644
--- a/src/vnet/ipsec/ipsec_sa.h
+++ b/src/vnet/ipsec/ipsec_sa.h
@@ -71,8 +71,6 @@
   IPSEC_PROTOCOL_ESP = 1
 } ipsec_protocol_t;
 
-#define IPSEC_N_PROTOCOLS (IPSEC_PROTOCOL_ESP+1)
-
 #define IPSEC_KEY_MAX_LEN 128
 typedef struct ipsec_key_t_
 {
@@ -124,6 +122,7 @@
   u32 last_seq;
   u32 last_seq_hi;
   u64 replay_window;
+  dpo_id_t dpo;
 
   vnet_crypto_key_index_t crypto_key_index;
   vnet_crypto_key_index_t integ_key_index;
@@ -131,8 +130,6 @@
   vnet_crypto_op_id_t crypto_dec_op_id:16;
   vnet_crypto_op_id_t integ_op_id:16;
 
-  dpo_id_t dpo[IPSEC_N_PROTOCOLS];
-
   /* data accessed by dataplane code should be above this comment */
     CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);