ipsec: move the IPSec SA pool out of ipsec_main

Type: refactor

this allows the ipsec_sa_get funtion to be moved from ipsec.h to
ipsec_sa.h where it belongs.
Also use ipsec_sa_get throughout the code base.

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: I2dce726c4f7052b5507dd8dcfead0ed5604357df
diff --git a/src/plugins/dpdk/ipsec/esp_decrypt.c b/src/plugins/dpdk/ipsec/esp_decrypt.c
index 4981de3..9a782ab 100644
--- a/src/plugins/dpdk/ipsec/esp_decrypt.c
+++ b/src/plugins/dpdk/ipsec/esp_decrypt.c
@@ -98,7 +98,6 @@
 			 vlib_frame_t * from_frame, int is_ip6)
 {
   u32 n_left_from, *from, *to_next, next_index, thread_index;
-  ipsec_main_t *im = &ipsec_main;
   u32 thread_idx = vlib_get_thread_index ();
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
   crypto_resource_t *res = 0;
@@ -181,7 +180,7 @@
 
 	  if (sa_index0 != last_sa_index)
 	    {
-	      sa0 = pool_elt_at_index (im->sad, sa_index0);
+	      sa0 = ipsec_sa_get (sa_index0);
 
 	      cipher_alg =
 		vec_elt_at_index (dcm->cipher_algs, sa0->crypto_alg);
@@ -498,7 +497,6 @@
   u32 n_left_from, *from, *to_next = 0, next_index;
   ipsec_sa_t *sa0;
   u32 sa_index0 = ~0;
-  ipsec_main_t *im = &ipsec_main;
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
 
   from = vlib_frame_vector_args (from_frame);
@@ -535,7 +533,7 @@
 	  esp0 = vlib_buffer_get_current (b0);
 
 	  sa_index0 = vnet_buffer (b0)->ipsec.sad_index;
-	  sa0 = pool_elt_at_index (im->sad, sa_index0);
+	  sa0 = ipsec_sa_get (sa_index0);
 
 	  to_next[0] = bi0;
 	  to_next += 1;
diff --git a/src/plugins/dpdk/ipsec/esp_encrypt.c b/src/plugins/dpdk/ipsec/esp_encrypt.c
index f50291f..157c93f 100644
--- a/src/plugins/dpdk/ipsec/esp_encrypt.c
+++ b/src/plugins/dpdk/ipsec/esp_encrypt.c
@@ -229,7 +229,7 @@
 
 	  if (sa_index0 != last_sa_index)
 	    {
-	      sa0 = pool_elt_at_index (im->sad, sa_index0);
+	      sa0 = ipsec_sa_get (sa_index0);
 
 	      cipher_alg =
 		vec_elt_at_index (dcm->cipher_algs, sa0->crypto_alg);
diff --git a/src/plugins/dpdk/ipsec/ipsec.c b/src/plugins/dpdk/ipsec/ipsec.c
index 5d9e10b..e260ba7 100644
--- a/src/plugins/dpdk/ipsec/ipsec.c
+++ b/src/plugins/dpdk/ipsec/ipsec.c
@@ -325,7 +325,6 @@
 		    crypto_worker_main_t * cwm, u8 is_outbound)
 {
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
-  ipsec_main_t *im = &ipsec_main;
   crypto_data_t *data;
   ipsec_sa_t *sa;
   struct rte_crypto_sym_xform cipher_xform = { 0 };
@@ -334,8 +333,7 @@
   struct rte_cryptodev_sym_session **s;
   clib_error_t *error = 0;
 
-
-  sa = pool_elt_at_index (im->sad, sa_idx);
+  sa = ipsec_sa_get (sa_idx);
 
   if ((sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) |
       (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_192) |
diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c
index aaebf62..7c57f22 100644
--- a/src/plugins/ikev2/ikev2.c
+++ b/src/plugins/ikev2/ikev2.c
@@ -5074,7 +5074,6 @@
 		       vlib_frame_t * f)
 {
   ikev2_main_t *km = &ikev2_main;
-  ipsec_main_t *im = &ipsec_main;
   ikev2_profile_t *p;
   ikev2_child_sa_t *c;
   u32 *sai;
@@ -5148,9 +5147,10 @@
       /* process ipsec sas */
       ipsec_sa_t *sa;
       /* *INDENT-OFF* */
-      pool_foreach (sa, im->sad)  {
-        ikev2_mngr_process_ipsec_sa(sa);
-      }
+      pool_foreach (sa, ipsec_sa_pool)
+	{
+	  ikev2_mngr_process_ipsec_sa (sa);
+	}
       /* *INDENT-ON* */
 
       ikev2_process_pending_sa_init (km);
diff --git a/src/plugins/unittest/ipsec_test.c b/src/plugins/unittest/ipsec_test.c
index c40e954..0e98650 100644
--- a/src/plugins/unittest/ipsec_test.c
+++ b/src/plugins/unittest/ipsec_test.c
@@ -38,12 +38,11 @@
 
   if (~0 != sa_id)
     {
-      ipsec_main_t *im = &ipsec_main;
       ipsec_sa_t *sa;
       u32 sa_index;
 
       sa_index = ipsec_sa_find_and_lock (sa_id);
-      sa = pool_elt_at_index (im->sad, sa_index);
+      sa = ipsec_sa_get (sa_index);
 
       sa->seq = seq_num & 0xffffffff;
       sa->seq_hi = seq_num >> 32;
diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c
index a5e277e..d192fb6 100644
--- a/src/vnet/ipsec/ah_decrypt.c
+++ b/src/vnet/ipsec/ah_decrypt.c
@@ -169,7 +169,7 @@
 					     current_sa_pkts,
 					     current_sa_bytes);
 	  current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
-	  sa0 = pool_elt_at_index (im->sad, current_sa_index);
+	  sa0 = ipsec_sa_get (current_sa_index);
 
 	  current_sa_bytes = current_sa_pkts = 0;
 	  vlib_prefetch_combined_counter (&ipsec_sa_counters,
@@ -317,7 +317,7 @@
       if (next[0] < AH_DECRYPT_N_NEXT)
 	goto trace;
 
-      sa0 = vec_elt_at_index (im->sad, pd->sa_index);
+      sa0 = ipsec_sa_get (pd->sa_index);
 
       if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
 	{
@@ -399,8 +399,7 @@
     trace:
       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
 	{
-	  sa0 = pool_elt_at_index (im->sad,
-				   vnet_buffer (b[0])->ipsec.sad_index);
+	  sa0 = ipsec_sa_get (vnet_buffer (b[0])->ipsec.sad_index);
 	  ah_decrypt_trace_t *tr =
 	    vlib_add_trace (vm, node, b[0], sizeof (*tr));
 	  tr->integ_alg = sa0->integ_alg;
diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c
index a1f233c..c962ea9 100644
--- a/src/vnet/ipsec/ah_encrypt.c
+++ b/src/vnet/ipsec/ah_encrypt.c
@@ -176,7 +176,7 @@
 					     current_sa_pkts,
 					     current_sa_bytes);
 	  current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
-	  sa0 = pool_elt_at_index (im->sad, current_sa_index);
+	  sa0 = ipsec_sa_get (current_sa_index);
 
 	  current_sa_bytes = current_sa_pkts = 0;
 	}
@@ -387,7 +387,7 @@
     next:
       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
 	{
-	  sa0 = vec_elt_at_index (im->sad, pd->sa_index);
+	  sa0 = ipsec_sa_get (pd->sa_index);
 	  ah_encrypt_trace_t *tr =
 	    vlib_add_trace (vm, node, b[0], sizeof (*tr));
 	  tr->spi = sa0->spi;
diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c
index 274fbf8..80ce08b 100644
--- a/src/vnet/ipsec/esp_decrypt.c
+++ b/src/vnet/ipsec/esp_decrypt.c
@@ -750,8 +750,7 @@
 			 esp_decrypt_packet_data2_t * pd2, vlib_buffer_t * b,
 			 u16 * next, int is_ip6, int is_tun, int is_async)
 {
-  ipsec_main_t *im = &ipsec_main;
-  ipsec_sa_t *sa0 = vec_elt_at_index (im->sad, pd->sa_index);
+  ipsec_sa_t *sa0 = ipsec_sa_get (pd->sa_index);
   vlib_buffer_t *lb = b;
   const u8 esp_sz = sizeof (esp_header_t);
   const u8 tun_flags = IPSEC_SA_FLAG_IS_TUNNEL | IPSEC_SA_FLAG_IS_TUNNEL_V6;
@@ -1086,7 +1085,7 @@
 	  current_sa_bytes = current_sa_pkts = 0;
 
 	  current_sa_index = vnet_buffer (b[0])->ipsec.sad_index;
-	  sa0 = pool_elt_at_index (im->sad, current_sa_index);
+	  sa0 = ipsec_sa_get (current_sa_index);
 
 	  /* fetch the second cacheline ASAP */
 	  CLIB_PREFETCH (sa0->cacheline1, CLIB_CACHE_LINE_BYTES, LOAD);
@@ -1295,7 +1294,7 @@
 	{
 	  esp_decrypt_trace_t *tr;
 	  tr = vlib_add_trace (vm, node, b[0], sizeof (*tr));
-	  sa0 = pool_elt_at_index (im->sad, current_sa_index);
+	  sa0 = ipsec_sa_get (current_sa_index);
 	  tr->crypto_alg = sa0->crypto_alg;
 	  tr->integ_alg = sa0->integ_alg;
 	  tr->seq = pd->seq;
@@ -1325,7 +1324,6 @@
 			 vlib_node_runtime_t * node,
 			 vlib_frame_t * from_frame, int is_ip6, int is_tun)
 {
-  ipsec_main_t *im = &ipsec_main;
   u32 *from = vlib_frame_vector_args (from_frame);
   u32 n_left = from_frame->n_vectors;
   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
@@ -1355,12 +1353,12 @@
       /*trace: */
       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
 	{
-	  ipsec_sa_t *sa0 = pool_elt_at_index (im->sad, pd->sa_index);
+	  ipsec_sa_t *sa0 = ipsec_sa_get (pd->sa_index);
 	  esp_decrypt_trace_t *tr;
 	  esp_decrypt_packet_data_t *async_pd =
 	    &(esp_post_data (b[0]))->decrypt_data;
 	  tr = vlib_add_trace (vm, node, b[0], sizeof (*tr));
-	  sa0 = pool_elt_at_index (im->sad, async_pd->sa_index);
+	  sa0 = ipsec_sa_get (async_pd->sa_index);
 
 	  tr->crypto_alg = sa0->crypto_alg;
 	  tr->integ_alg = sa0->integ_alg;
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index 8251e82..16bca1d 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -646,7 +646,7 @@
 					     current_sa_bytes);
 	  current_sa_packets = current_sa_bytes = 0;
 
-	  sa0 = pool_elt_at_index (im->sad, sa_index0);
+	  sa0 = ipsec_sa_get (sa_index0);
 
 	  /* fetch the second cacheline ASAP */
 	  CLIB_PREFETCH (sa0->cacheline1, CLIB_CACHE_LINE_BYTES, LOAD);
diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c
index 84d2293..45ae5ac 100644
--- a/src/vnet/ipsec/ipsec.c
+++ b/src/vnet/ipsec/ipsec.c
@@ -246,10 +246,9 @@
 ipsec_rsc_in_use (ipsec_main_t * im)
 {
   /* return an error is crypto resource are in use */
-  if (pool_elts (im->sad) > 0)
-    return clib_error_return (0,
-			      "%d SA entries configured",
-			      pool_elts (im->sad));
+  if (pool_elts (ipsec_sa_pool) > 0)
+    return clib_error_return (0, "%d SA entries configured",
+			      pool_elts (ipsec_sa_pool));
 
   return (NULL);
 }
@@ -331,20 +330,20 @@
   ipsec_sa_t *sa;
 
   /* lock all SAs before change im->async_mode */
-  pool_foreach (sa, im->sad)
-  {
-    fib_node_lock (&sa->node);
-  }
+  pool_foreach (sa, ipsec_sa_pool)
+    {
+      fib_node_lock (&sa->node);
+    }
 
   im->async_mode = is_enabled;
 
   /* change SA crypto op data before unlock them */
-  pool_foreach (sa, im->sad)
-  {
-    sa->crypto_op_data = is_enabled ?
-      sa->async_op_data.data : sa->sync_op_data.data;
-    fib_node_unlock (&sa->node);
-  }
+  pool_foreach (sa, ipsec_sa_pool)
+    {
+      sa->crypto_op_data =
+	is_enabled ? sa->async_op_data.data : sa->sync_op_data.data;
+      fib_node_unlock (&sa->node);
+    }
 }
 
 static void
diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h
index 7e89768..7ca1586 100644
--- a/src/vnet/ipsec/ipsec.h
+++ b/src/vnet/ipsec/ipsec.h
@@ -108,8 +108,6 @@
 {
   /* pool of tunnel instances */
   ipsec_spd_t *spds;
-  /* Pool of security associations */
-  ipsec_sa_t *sad;
   /* pool of policies */
   ipsec_policy_t *policies;
 
@@ -230,7 +228,6 @@
 /*
  * functions
  */
-u8 *format_ipsec_replay_window (u8 * s, va_list * args);
 
 /*
  *  inline functions
@@ -274,12 +271,6 @@
 clib_error_t *ipsec_rsc_in_use (ipsec_main_t * im);
 void ipsec_set_async_mode (u32 is_enabled);
 
-always_inline ipsec_sa_t *
-ipsec_sa_get (u32 sa_index)
-{
-  return (pool_elt_at_index (ipsec_main.sad, sa_index));
-}
-
 extern void ipsec_register_udp_port (u16 udp_port);
 extern void ipsec_unregister_udp_port (u16 udp_port);
 
diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c
index a3e0545..45e4e6f 100644
--- a/src/vnet/ipsec/ipsec_api.c
+++ b/src/vnet/ipsec/ipsec_api.c
@@ -805,7 +805,6 @@
 {
   ipsec_dump_walk_ctx_t *ctx = arg;
   vl_api_ipsec_sa_details_t *mp;
-  ipsec_main_t *im = &ipsec_main;
 
   mp = vl_msg_api_alloc (sizeof (*mp));
   clib_memset (mp, 0, sizeof (*mp));
@@ -829,8 +828,8 @@
   if (ipsec_sa_is_set_IS_PROTECT (sa))
     {
       ipsec_sa_dump_match_ctx_t ctx = {
-        .sai = sa - im->sad,
-        .sw_if_index = ~0,
+	.sai = sa - ipsec_sa_pool,
+	.sw_if_index = ~0,
       };
       ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
 
@@ -894,7 +893,6 @@
 {
   ipsec_dump_walk_ctx_t *ctx = arg;
   vl_api_ipsec_sa_v2_details_t *mp;
-  ipsec_main_t *im = &ipsec_main;
 
   mp = vl_msg_api_alloc (sizeof (*mp));
   clib_memset (mp, 0, sizeof (*mp));
@@ -918,8 +916,8 @@
   if (ipsec_sa_is_set_IS_PROTECT (sa))
     {
       ipsec_sa_dump_match_ctx_t ctx = {
-        .sai = sa - im->sad,
-        .sw_if_index = ~0,
+	.sai = sa - ipsec_sa_pool,
+	.sw_if_index = ~0,
       };
       ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
 
@@ -987,7 +985,6 @@
 {
   ipsec_dump_walk_ctx_t *ctx = arg;
   vl_api_ipsec_sa_v3_details_t *mp;
-  ipsec_main_t *im = &ipsec_main;
 
   mp = vl_msg_api_alloc (sizeof (*mp));
   clib_memset (mp, 0, sizeof (*mp));
@@ -1010,7 +1007,7 @@
   if (ipsec_sa_is_set_IS_PROTECT (sa))
     {
       ipsec_sa_dump_match_ctx_t ctx = {
-	.sai = sa - im->sad,
+	.sai = sa - ipsec_sa_pool,
 	.sw_if_index = ~0,
       };
       ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
@@ -1120,7 +1117,7 @@
   vl_api_ipsec_select_backend_reply_t *rmp;
   ipsec_protocol_t protocol;
   int rv = 0;
-  if (pool_elts (im->sad) > 0)
+  if (pool_elts (ipsec_sa_pool) > 0)
     {
       rv = VNET_API_ERROR_INSTANCE_IN_USE;
       goto done;
diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c
index eed910e..bb80b32 100644
--- a/src/vnet/ipsec/ipsec_cli.c
+++ b/src/vnet/ipsec/ipsec_cli.c
@@ -414,10 +414,11 @@
   u32 sai;
 
   /* *INDENT-OFF* */
-  pool_foreach_index (sai, im->sad)  {
-    vlib_cli_output(vm, "%U", format_ipsec_sa, sai,
-                    (detail ? IPSEC_FORMAT_DETAIL : IPSEC_FORMAT_BRIEF));
-  }
+  pool_foreach_index (sai, ipsec_sa_pool)
+    {
+      vlib_cli_output (vm, "%U", format_ipsec_sa, sai,
+		       (detail ? IPSEC_FORMAT_DETAIL : IPSEC_FORMAT_BRIEF));
+    }
   /* *INDENT-ON* */
 }
 
@@ -521,7 +522,6 @@
 clear_ipsec_sa_command_fn (vlib_main_t * vm,
 			   unformat_input_t * input, vlib_cli_command_t * cmd)
 {
-  ipsec_main_t *im = &ipsec_main;
   u32 sai = ~0;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -535,14 +535,15 @@
   if (~0 == sai)
     {
       /* *INDENT-OFF* */
-      pool_foreach_index (sai, im->sad)  {
-        ipsec_sa_clear(sai);
-      }
+      pool_foreach_index (sai, ipsec_sa_pool)
+	{
+	  ipsec_sa_clear (sai);
+	}
       /* *INDENT-ON* */
     }
   else
     {
-      if (pool_is_free_index (im->sad, sai))
+      if (pool_is_free_index (ipsec_sa_pool, sai))
 	return clib_error_return (0, "unknown SA index: %d", sai);
       else
 	ipsec_sa_clear (sai);
diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c
index 001aa01..b67c11d 100644
--- a/src/vnet/ipsec/ipsec_format.c
+++ b/src/vnet/ipsec/ipsec_format.c
@@ -271,17 +271,16 @@
 {
   u32 sai = va_arg (*args, u32);
   ipsec_format_flags_t flags = va_arg (*args, ipsec_format_flags_t);
-  ipsec_main_t *im = &ipsec_main;
   vlib_counter_t counts;
   ipsec_sa_t *sa;
 
-  if (pool_is_free_index (im->sad, sai))
+  if (pool_is_free_index (ipsec_sa_pool, sai))
     {
       s = format (s, "No such SA index: %d", sai);
       goto done;
     }
 
-  sa = pool_elt_at_index (im->sad, sai);
+  sa = ipsec_sa_get (sai);
 
   s = format (s, "[%d] sa %u (0x%x) spi %u (0x%08x) protocol:%s flags:[%U]",
 	      sai, sa->id, sa->id, sa->spi, sa->spi,
diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c
index 2ebc6c5..15a0796 100644
--- a/src/vnet/ipsec/ipsec_input.c
+++ b/src/vnet/ipsec/ipsec_input.c
@@ -111,7 +111,7 @@
   vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT])
   {
     p = pool_elt_at_index (im->policies, *i);
-    s = pool_elt_at_index (im->sad, p->sa_index);
+    s = ipsec_sa_get (p->sa_index);
 
     if (spi != s->spi)
       continue;
@@ -167,7 +167,7 @@
   vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT])
   {
     p = pool_elt_at_index (im->policies, *i);
-    s = pool_elt_at_index (im->sad, p->sa_index);
+    s = ipsec_sa_get (p->sa_index);
 
     if (spi != s->spi)
       continue;
diff --git a/src/vnet/ipsec/ipsec_output.c b/src/vnet/ipsec/ipsec_output.c
index e6cf837..23a86de 100644
--- a/src/vnet/ipsec/ipsec_output.c
+++ b/src/vnet/ipsec/ipsec_output.c
@@ -297,7 +297,7 @@
 	    {
 	      ipsec_sa_t *sa = 0;
 	      nc_protect++;
-	      sa = pool_elt_at_index (im->sad, p0->sa_index);
+	      sa = ipsec_sa_get (p0->sa_index);
 	      if (sa->protocol == IPSEC_PROTOCOL_ESP)
 		if (is_ipv6)
 		  next_node_index = im->esp6_encrypt_node_index;
diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c
index 0a24aa2..7e2dc20 100644
--- a/src/vnet/ipsec/ipsec_sa.c
+++ b/src/vnet/ipsec/ipsec_sa.c
@@ -29,6 +29,7 @@
   .stat_segment_name = "/net/ipsec/sa",
 };
 
+ipsec_sa_t *ipsec_sa_pool;
 
 static clib_error_t *
 ipsec_call_add_del_callbacks (ipsec_main_t * im, ipsec_sa_t * sa,
@@ -184,11 +185,11 @@
   if (p)
     return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
 
-  pool_get_aligned_zero (im->sad, sa, CLIB_CACHE_LINE_BYTES);
+  pool_get_aligned_zero (ipsec_sa_pool, sa, CLIB_CACHE_LINE_BYTES);
 
   fib_node_init (&sa->node, FIB_NODE_TYPE_IPSEC_SA);
   fib_node_lock (&sa->node);
-  sa_index = sa - im->sad;
+  sa_index = sa - ipsec_sa_pool;
 
   vlib_validate_combined_counter (&ipsec_sa_counters, sa_index);
   vlib_zero_combined_counter (&ipsec_sa_counters, sa_index);
@@ -216,7 +217,7 @@
 					      (u8 *) ck->data, ck->len);
   if (~0 == sa->crypto_key_index)
     {
-      pool_put (im->sad, sa);
+      pool_put (ipsec_sa_pool, sa);
       return VNET_API_ERROR_KEY_LENGTH;
     }
 
@@ -228,7 +229,7 @@
 						 (u8 *) ik->data, ik->len);
       if (~0 == sa->integ_key_index)
 	{
-	  pool_put (im->sad, sa);
+	  pool_put (ipsec_sa_pool, sa);
 	  return VNET_API_ERROR_KEY_LENGTH;
 	}
     }
@@ -250,14 +251,14 @@
   if (err)
     {
       clib_warning ("%s", err->what);
-      pool_put (im->sad, sa);
+      pool_put (ipsec_sa_pool, sa);
       return VNET_API_ERROR_UNIMPLEMENTED;
     }
 
   err = ipsec_call_add_del_callbacks (im, sa, sa_index, 1);
   if (err)
     {
-      pool_put (im->sad, sa);
+      pool_put (ipsec_sa_pool, sa);
       return VNET_API_ERROR_SYSCALL_ERROR_1;
     }
 
@@ -269,7 +270,7 @@
 
       if (rv)
 	{
-	  pool_put (im->sad, sa);
+	  pool_put (ipsec_sa_pool, sa);
 	  return rv;
 	}
       ipsec_sa_stack (sa);
@@ -324,7 +325,7 @@
   ipsec_main_t *im = &ipsec_main;
   u32 sa_index;
 
-  sa_index = sa - im->sad;
+  sa_index = sa - ipsec_sa_pool;
   hash_unset (im->sa_index_by_sa_id, sa->id);
   tunnel_unresolve (&sa->tunnel);
 
@@ -339,19 +340,18 @@
   vnet_crypto_key_del (vm, sa->crypto_key_index);
   if (sa->integ_alg != IPSEC_INTEG_ALG_NONE)
     vnet_crypto_key_del (vm, sa->integ_key_index);
-  pool_put (im->sad, sa);
+  pool_put (ipsec_sa_pool, sa);
 }
 
 void
 ipsec_sa_unlock (index_t sai)
 {
-  ipsec_main_t *im = &ipsec_main;
   ipsec_sa_t *sa;
 
   if (INDEX_INVALID == sai)
     return;
 
-  sa = pool_elt_at_index (im->sad, sai);
+  sa = ipsec_sa_get (sai);
 
   fib_node_unlock (&sa->node);
 }
@@ -359,13 +359,12 @@
 void
 ipsec_sa_lock (index_t sai)
 {
-  ipsec_main_t *im = &ipsec_main;
   ipsec_sa_t *sa;
 
   if (INDEX_INVALID == sai)
     return;
 
-  sa = pool_elt_at_index (im->sad, sai);
+  sa = ipsec_sa_get (sai);
 
   fib_node_lock (&sa->node);
 }
@@ -382,7 +381,7 @@
   if (!p)
     return INDEX_INVALID;
 
-  sa = pool_elt_at_index (im->sad, p[0]);
+  sa = ipsec_sa_get (p[0]);
 
   fib_node_lock (&sa->node);
 
@@ -414,15 +413,14 @@
 void
 ipsec_sa_walk (ipsec_sa_walk_cb_t cb, void *ctx)
 {
-  ipsec_main_t *im = &ipsec_main;
   ipsec_sa_t *sa;
 
   /* *INDENT-OFF* */
-  pool_foreach (sa, im->sad)
-   {
-    if (WALK_CONTINUE != cb(sa, ctx))
-      break;
-  }
+  pool_foreach (sa, ipsec_sa_pool)
+    {
+      if (WALK_CONTINUE != cb (sa, ctx))
+	break;
+    }
   /* *INDENT-ON* */
 }
 
@@ -432,11 +430,9 @@
 static fib_node_t *
 ipsec_sa_fib_node_get (fib_node_index_t index)
 {
-  ipsec_main_t *im;
   ipsec_sa_t *sa;
 
-  im = &ipsec_main;
-  sa = pool_elt_at_index (im->sad, index);
+  sa = ipsec_sa_get (index);
 
   return (&sa->node);
 }
diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h
index a5756f5..705034e 100644
--- a/src/vnet/ipsec/ipsec_sa.h
+++ b/src/vnet/ipsec/ipsec_sa.h
@@ -223,6 +223,11 @@
 STATIC_ASSERT_OFFSET_OF (ipsec_sa_t, cacheline1, CLIB_CACHE_LINE_BYTES);
 STATIC_ASSERT_OFFSET_OF (ipsec_sa_t, cacheline2, 2 * CLIB_CACHE_LINE_BYTES);
 
+/**
+ * Pool of IPSec SAs
+ */
+extern ipsec_sa_t *ipsec_sa_pool;
+
 /*
  * Ensure that the IPsec data does not overlap with the IP data in
  * the buffer meta data
@@ -279,6 +284,7 @@
 typedef walk_rc_t (*ipsec_sa_walk_cb_t) (ipsec_sa_t * sa, void *ctx);
 extern void ipsec_sa_walk (ipsec_sa_walk_cb_t cd, void *ctx);
 
+extern u8 *format_ipsec_replay_window (u8 *s, va_list *args);
 extern u8 *format_ipsec_crypto_alg (u8 * s, va_list * args);
 extern u8 *format_ipsec_integ_alg (u8 * s, va_list * args);
 extern u8 *format_ipsec_sa (u8 * s, va_list * args);
@@ -508,6 +514,12 @@
 	  : (unix_time_now_nsec () % vlib_num_workers ()) + 1);
 }
 
+always_inline ipsec_sa_t *
+ipsec_sa_get (u32 sa_index)
+{
+  return (pool_elt_at_index (ipsec_sa_pool, sa_index));
+}
+
 #endif /* __IPSEC_SPD_SA_H__ */
 
 /*