summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ipsec')
-rw-r--r--src/vnet/ipsec/esp_encrypt.c162
-rw-r--r--src/vnet/ipsec/ipsec.c4
-rw-r--r--src/vnet/ipsec/ipsec.h8
-rw-r--r--src/vnet/ipsec/ipsec_itf.c8
-rw-r--r--src/vnet/ipsec/ipsec_itf.h1
-rw-r--r--src/vnet/ipsec/ipsec_sa.h3
-rw-r--r--src/vnet/ipsec/ipsec_tun.c128
-rw-r--r--src/vnet/ipsec/ipsec_tun.h1
8 files changed, 123 insertions, 192 deletions
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index 33484e9cf43..0d29604e61f 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -50,7 +50,9 @@ typedef enum
_ (SEQ_CYCLED, "sequence number cycled (packet dropped)") \
_ (CRYPTO_ENGINE_ERROR, "crypto engine error (packet dropped)") \
_ (CRYPTO_QUEUE_FULL, "crypto queue full (packet dropped)") \
- _ (NO_BUFFERS, "no buffers (packet dropped)")
+ _ (NO_BUFFERS, "no buffers (packet dropped)") \
+ _ (NO_PROTECTION, "no protecting SA (packet dropped)") \
+ _ (NO_ENCRYPTION, "no Encrypting SA (packet dropped)")
typedef enum
{
@@ -640,6 +642,14 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
vnet_buffer (b[0])->ipsec.sad_index =
sa_index0 = ipsec_tun_protect_get_sa_out
(vnet_buffer (b[0])->ip.adj_index[VLIB_TX]);
+
+ if (PREDICT_FALSE (INDEX_INVALID == sa_index0))
+ {
+ err = ESP_ENCRYPT_ERROR_NO_PROTECTION;
+ esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
+ drop_next);
+ goto trace;
+ }
}
else
sa_index0 = vnet_buffer (b[0])->ipsec.sad_index;
@@ -655,6 +665,15 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
sa0 = ipsec_sa_get (sa_index0);
+ if (PREDICT_FALSE ((sa0->crypto_alg == IPSEC_CRYPTO_ALG_NONE &&
+ sa0->integ_alg == IPSEC_INTEG_ALG_NONE) &&
+ !ipsec_sa_is_set_NO_ALGO_NO_DROP (sa0)))
+ {
+ err = ESP_ENCRYPT_ERROR_NO_ENCRYPTION;
+ esp_set_next_index (b[0], node, err, n_noop, noop_nexts,
+ drop_next);
+ goto trace;
+ }
/* fetch the second cacheline ASAP */
clib_prefetch_load (sa0->cacheline1);
@@ -970,13 +989,19 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
{
esp_encrypt_trace_t *tr = vlib_add_trace (vm, node, b[0],
sizeof (*tr));
- tr->sa_index = sa_index0;
- tr->spi = sa0->spi;
- tr->seq = sa0->seq;
- tr->sa_seq_hi = sa0->seq_hi;
- tr->udp_encap = ipsec_sa_is_set_UDP_ENCAP (sa0);
- tr->crypto_alg = sa0->crypto_alg;
- tr->integ_alg = sa0->integ_alg;
+ if (INDEX_INVALID == sa_index0)
+ clib_memset_u8 (tr, 0xff, sizeof (*tr));
+ else
+ {
+ tr->sa_index = sa_index0;
+ tr->spi = sa0->spi;
+ tr->spi = sa0->spi;
+ tr->seq = sa0->seq;
+ tr->sa_seq_hi = sa0->seq_hi;
+ tr->udp_encap = ipsec_sa_is_set_UDP_ENCAP (sa0);
+ tr->crypto_alg = sa0->crypto_alg;
+ tr->integ_alg = sa0->integ_alg;
+ }
}
/* next */
@@ -1002,9 +1027,10 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
b += 1;
}
- vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
- current_sa_index, current_sa_packets,
- current_sa_bytes);
+ if (INDEX_INVALID != current_sa_index)
+ vlib_increment_combined_counter (&ipsec_sa_counters, thread_index,
+ current_sa_index, current_sa_packets,
+ current_sa_bytes);
if (n_sync)
{
esp_process_ops (vm, node, ptd->crypto_ops, sync_bufs, sync_nexts,
@@ -1368,120 +1394,6 @@ VLIB_REGISTER_NODE (esp_mpls_encrypt_tun_post_node) = {
.error_strings = esp_encrypt_error_strings,
};
-typedef struct
-{
- u32 sa_index;
-} esp_no_crypto_trace_t;
-
-static u8 *
-format_esp_no_crypto_trace (u8 * s, va_list * args)
-{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- esp_no_crypto_trace_t *t = va_arg (*args, esp_no_crypto_trace_t *);
-
- s = format (s, "esp-no-crypto: sa-index %u", t->sa_index);
-
- return s;
-}
-
-enum
-{
- ESP_NO_CRYPTO_NEXT_DROP,
- ESP_NO_CRYPTO_N_NEXT,
-};
-
-enum
-{
- ESP_NO_CRYPTO_ERROR_RX_PKTS,
-};
-
-static char *esp_no_crypto_error_strings[] = {
- "Outbound ESP packets received",
-};
-
-always_inline uword
-esp_no_crypto_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
- u32 *from = vlib_frame_vector_args (frame);
- u32 n_left = frame->n_vectors;
-
- vlib_get_buffers (vm, from, b, n_left);
-
- while (n_left > 0)
- {
- u32 sa_index0;
-
- /* packets are always going to be dropped, but get the sa_index */
- sa_index0 = ipsec_tun_protect_get_sa_out
- (vnet_buffer (b[0])->ip.adj_index[VLIB_TX]);
-
- if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
- {
- esp_no_crypto_trace_t *tr = vlib_add_trace (vm, node, b[0],
- sizeof (*tr));
- tr->sa_index = sa_index0;
- }
-
- n_left -= 1;
- b += 1;
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- ESP_NO_CRYPTO_ERROR_RX_PKTS, frame->n_vectors);
-
- vlib_buffer_enqueue_to_single_next (vm, node, from,
- ESP_NO_CRYPTO_NEXT_DROP,
- frame->n_vectors);
-
- return frame->n_vectors;
-}
-
-VLIB_NODE_FN (esp4_no_crypto_tun_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
-{
- return esp_no_crypto_inline (vm, node, from_frame);
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (esp4_no_crypto_tun_node) =
-{
- .name = "esp4-no-crypto",
- .vector_size = sizeof (u32),
- .format_trace = format_esp_no_crypto_trace,
- .n_errors = ARRAY_LEN(esp_no_crypto_error_strings),
- .error_strings = esp_no_crypto_error_strings,
- .n_next_nodes = ESP_NO_CRYPTO_N_NEXT,
- .next_nodes = {
- [ESP_NO_CRYPTO_NEXT_DROP] = "ip4-drop",
- },
-};
-
-VLIB_NODE_FN (esp6_no_crypto_tun_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
-{
- return esp_no_crypto_inline (vm, node, from_frame);
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (esp6_no_crypto_tun_node) =
-{
- .name = "esp6-no-crypto",
- .vector_size = sizeof (u32),
- .format_trace = format_esp_no_crypto_trace,
- .n_errors = ARRAY_LEN(esp_no_crypto_error_strings),
- .error_strings = esp_no_crypto_error_strings,
- .n_next_nodes = ESP_NO_CRYPTO_N_NEXT,
- .next_nodes = {
- [ESP_NO_CRYPTO_NEXT_DROP] = "ip6-drop",
- },
-};
-/* *INDENT-ON* */
-
#ifndef CLIB_MARCH_VARIANT
static clib_error_t *
diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c
index 30774ec10ff..5cc8044e3d4 100644
--- a/src/vnet/ipsec/ipsec.c
+++ b/src/vnet/ipsec/ipsec.c
@@ -25,6 +25,7 @@
#include <vnet/ipsec/esp.h>
#include <vnet/ipsec/ah.h>
#include <vnet/ipsec/ipsec_tun.h>
+#include <vnet/ipsec/ipsec_itf.h>
/* Flow cache is sized for 1 million flows with a load factor of .25.
*/
@@ -254,6 +255,9 @@ ipsec_rsc_in_use (ipsec_main_t * im)
if (pool_elts (ipsec_sa_pool) > 0)
return clib_error_return (0, "%d SA entries configured",
pool_elts (ipsec_sa_pool));
+ if (ipsec_itf_count () > 0)
+ return clib_error_return (0, "%d IPSec interface configured",
+ ipsec_itf_count ());
return (NULL);
}
diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h
index 968d377cea0..38feaed6f77 100644
--- a/src/vnet/ipsec/ipsec.h
+++ b/src/vnet/ipsec/ipsec.h
@@ -181,14 +181,6 @@ typedef struct
u32 ah6_encrypt_next_index;
u32 ah6_decrypt_next_index;
- /* tun nodes to drop packets when no crypto alg set on outbound SA */
- u32 esp4_no_crypto_tun_node_index;
- u32 esp6_no_crypto_tun_node_index;
-
- /* tun nodes for encrypt on L2 interfaces */
- u32 esp4_encrypt_l2_tun_node_index;
- u32 esp6_encrypt_l2_tun_node_index;
-
/* pool of ah backends */
ipsec_ah_backend_t *ah_backends;
/* pool of esp backends */
diff --git a/src/vnet/ipsec/ipsec_itf.c b/src/vnet/ipsec/ipsec_itf.c
index 532d5be4c07..fc0bf85a517 100644
--- a/src/vnet/ipsec/ipsec_itf.c
+++ b/src/vnet/ipsec/ipsec_itf.c
@@ -36,6 +36,12 @@ ipsec_itf_get (index_t ii)
return (pool_elt_at_index (ipsec_itf_pool, ii));
}
+u32
+ipsec_itf_count (void)
+{
+ return (pool_elts (ipsec_itf_pool));
+}
+
static ipsec_itf_t *
ipsec_itf_find_by_sw_if_index (u32 sw_if_index)
{
@@ -336,6 +342,8 @@ ipsec_itf_delete (u32 sw_if_index)
if (ipsec_itf_instance_free (hw->dev_instance) < 0)
return VNET_API_ERROR_INVALID_SW_IF_INDEX;
+ vnet_reset_interface_l3_output_node (vnm->vlib_main, sw_if_index);
+
vnet_delete_hw_interface (vnm, hw->hw_if_index);
pool_put (ipsec_itf_pool, ipsec_itf);
diff --git a/src/vnet/ipsec/ipsec_itf.h b/src/vnet/ipsec/ipsec_itf.h
index 4958d102b65..7de02745b81 100644
--- a/src/vnet/ipsec/ipsec_itf.h
+++ b/src/vnet/ipsec/ipsec_itf.h
@@ -109,6 +109,7 @@ extern void ipsec_itf_adj_unstack (adj_index_t ai);
extern u8 *format_ipsec_itf (u8 * s, va_list * a);
extern ipsec_itf_t *ipsec_itf_get (index_t ii);
+extern u32 ipsec_itf_count (void);
typedef walk_rc_t (*ipsec_itf_walk_cb_t) (ipsec_itf_t *itf, void *ctx);
extern void ipsec_itf_walk (ipsec_itf_walk_cb_t cd, void *ctx);
diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h
index 2cc64e19546..ec5ca11b179 100644
--- a/src/vnet/ipsec/ipsec_sa.h
+++ b/src/vnet/ipsec/ipsec_sa.h
@@ -102,7 +102,8 @@ typedef struct ipsec_key_t_
_ (64, IS_INBOUND, "inbound") \
_ (128, IS_AEAD, "aead") \
_ (256, IS_CTR, "ctr") \
- _ (512, IS_ASYNC, "async")
+ _ (512, IS_ASYNC, "async") \
+ _ (1024, NO_ALGO_NO_DROP, "no-algo-no-drop")
typedef enum ipsec_sad_flags_t_
{
diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c
index 1a9a25783ae..ef84d13a373 100644
--- a/src/vnet/ipsec/ipsec_tun.c
+++ b/src/vnet/ipsec/ipsec_tun.c
@@ -22,6 +22,7 @@
#include <vnet/adj/adj_delegate.h>
#include <vnet/adj/adj_midchain.h>
#include <vnet/teib/teib.h>
+#include <vnet/mpls/mpls.h>
/* instantiate the bihash functions */
#include <vppinfra/bihash_8_16.h>
@@ -137,12 +138,14 @@ ipsec_tun_protect_from_const_base (const adj_delegate_t * ad)
static u32
ipsec_tun_protect_get_adj_next (vnet_link_t linkt,
- const ipsec_tun_protect_t * itp)
+ const ipsec_tun_protect_t *itp)
{
ipsec_main_t *im;
- ipsec_sa_t *sa;
u32 next;
+ im = &ipsec_main;
+ next = 0;
+
if (!(itp->itp_flags & IPSEC_PROTECT_ITF))
{
if (ip46_address_is_ip4 (&itp->itp_tun.src))
@@ -151,42 +154,48 @@ ipsec_tun_protect_get_adj_next (vnet_link_t linkt,
linkt = VNET_LINK_IP6;
}
- sa = ipsec_sa_get (itp->itp_out_sa);
- im = &ipsec_main;
- next = 0;
-
- if ((sa->crypto_alg == IPSEC_CRYPTO_ALG_NONE &&
- sa->integ_alg == IPSEC_INTEG_ALG_NONE) &&
- !(itp->itp_flags & IPSEC_PROTECT_ITF))
- next = (VNET_LINK_IP4 == linkt ? im->esp4_no_crypto_tun_node_index :
- im->esp6_no_crypto_tun_node_index);
- else if (itp->itp_flags & IPSEC_PROTECT_L2)
- next = (VNET_LINK_IP4 == linkt ? im->esp4_encrypt_l2_tun_node_index :
- im->esp6_encrypt_l2_tun_node_index);
- else
+ switch (linkt)
{
- switch (linkt)
- {
- case VNET_LINK_IP4:
- next = im->esp4_encrypt_tun_node_index;
- break;
- case VNET_LINK_IP6:
- next = im->esp6_encrypt_tun_node_index;
- break;
- case VNET_LINK_MPLS:
- next = im->esp_mpls_encrypt_tun_node_index;
- break;
- case VNET_LINK_ARP:
- case VNET_LINK_NSH:
- case VNET_LINK_ETHERNET:
- ASSERT (0);
- break;
- }
+ case VNET_LINK_IP4:
+ next = im->esp4_encrypt_tun_node_index;
+ break;
+ case VNET_LINK_IP6:
+ next = im->esp6_encrypt_tun_node_index;
+ break;
+ case VNET_LINK_MPLS:
+ next = im->esp_mpls_encrypt_tun_node_index;
+ break;
+ case VNET_LINK_ARP:
+ case VNET_LINK_NSH:
+ case VNET_LINK_ETHERNET:
+ ASSERT (0);
+ break;
}
+
return (next);
}
static void
+ipsec_tun_reset_tx_nodes (u32 sw_if_index)
+{
+ vnet_reset_interface_l3_output_node (vlib_get_main (), sw_if_index);
+}
+
+static void
+ipsec_tun_setup_tx_nodes (u32 sw_if_index, const ipsec_tun_protect_t *itp)
+{
+ vnet_feature_modify_end_node (
+ ip4_main.lookup_main.output_feature_arc_index, sw_if_index,
+ ipsec_tun_protect_get_adj_next (VNET_LINK_IP4, itp));
+ vnet_feature_modify_end_node (
+ ip6_main.lookup_main.output_feature_arc_index, sw_if_index,
+ ipsec_tun_protect_get_adj_next (VNET_LINK_IP6, itp));
+ vnet_feature_modify_end_node (
+ mpls_main.output_feature_arc_index, sw_if_index,
+ ipsec_tun_protect_get_adj_next (VNET_LINK_MPLS, itp));
+}
+
+static void
ipsec_tun_protect_add_adj (adj_index_t ai, const ipsec_tun_protect_t * itp)
{
vec_validate_init_empty (ipsec_tun_protect_sa_by_adj_index, ai,
@@ -200,8 +209,8 @@ ipsec_tun_protect_add_adj (adj_index_t ai, const ipsec_tun_protect_t * itp)
else
{
ipsec_tun_protect_sa_by_adj_index[ai] = itp->itp_out_sa;
- adj_nbr_midchain_update_next_node
- (ai, ipsec_tun_protect_get_adj_next (adj_get_link_type (ai), itp));
+ adj_nbr_midchain_update_next_node (
+ ai, ipsec_tun_protect_get_adj_next (adj_get_link_type (ai), itp));
}
}
@@ -329,7 +338,7 @@ ipsec_tun_protect_tx_db_add (ipsec_tun_protect_t * itp)
{
if (INDEX_INVALID == idi->id_itp)
{
- // ipsec_tun_protect_feature_set (itp, 1);
+ ipsec_tun_setup_tx_nodes (itp->itp_sw_if_index, itp);
}
idi->id_itp = itp - ipsec_tun_protect_pool;
@@ -347,7 +356,7 @@ ipsec_tun_protect_tx_db_add (ipsec_tun_protect_t * itp)
* enable the encrypt feature for egress if this is the first addition
* on this interface
*/
- // ipsec_tun_protect_feature_set (itp, 1);
+ ipsec_tun_setup_tx_nodes (itp->itp_sw_if_index, itp);
}
hash_set_mem (idi->id_hash, itp->itp_key, itp - ipsec_tun_protect_pool);
@@ -435,7 +444,7 @@ ipsec_tun_protect_tx_db_remove (ipsec_tun_protect_t * itp)
if (vnet_sw_interface_is_p2p (vnet_get_main (), itp->itp_sw_if_index))
{
- // ipsec_tun_protect_feature_set (itp, 0);
+ ipsec_tun_reset_tx_nodes (itp->itp_sw_if_index);
idi->id_itp = INDEX_INVALID;
FOR_EACH_FIB_IP_PROTOCOL (nh_proto)
@@ -451,7 +460,7 @@ ipsec_tun_protect_tx_db_remove (ipsec_tun_protect_t * itp)
if (0 == hash_elts (idi->id_hash))
{
- // ipsec_tun_protect_feature_set (itp, 0);
+ ipsec_tun_reset_tx_nodes (itp->itp_sw_if_index);
hash_free (idi->id_hash);
idi->id_hash = NULL;
}
@@ -502,6 +511,9 @@ ipsec_tun_protect_config (ipsec_main_t * im,
ipsec_sa_lock (itp->itp_out_sa);
+ if (itp->itp_flags & IPSEC_PROTECT_ITF)
+ ipsec_sa_set_NO_ALGO_NO_DROP (ipsec_sa_get (itp->itp_out_sa));
+
/* *INDENT-OFF* */
FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
({
@@ -534,6 +546,7 @@ ipsec_tun_protect_unconfig (ipsec_main_t * im, ipsec_tun_protect_t * itp)
ipsec_tun_protect_rx_db_remove (im, itp);
ipsec_tun_protect_tx_db_remove (itp);
+ ipsec_sa_unset_NO_ALGO_NO_DROP (ipsec_sa_get (itp->itp_out_sa));
ipsec_sa_unlock(itp->itp_out_sa);
FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
@@ -802,19 +815,27 @@ ipsec_tun_feature_update (u32 sw_if_index, u8 arc_index, u8 is_enable,
ipsec_main.esp4_decrypt_tun_node_index :
ipsec_main.esp6_decrypt_tun_node_index;
- vnet_feature_modify_end_node (
- feature_main.device_input_feature_arc_index, sw_if_index, decrypt_tun);
- itp->itp_flags |= IPSEC_PROTECT_FEAT;
+ if (!(itp->itp_flags & IPSEC_PROTECT_FEAT))
+ {
+ itp->itp_flags |= IPSEC_PROTECT_FEAT;
+ vnet_feature_modify_end_node (
+ feature_main.device_input_feature_arc_index, sw_if_index,
+ decrypt_tun);
+ }
}
else
{
- u32 eth_in =
- vlib_get_node_by_name (vlib_get_main (), (u8 *) "ethernet-input")
- ->index;
+ if (itp->itp_flags & IPSEC_PROTECT_FEAT)
+ {
+ itp->itp_flags &= ~IPSEC_PROTECT_FEAT;
+
+ u32 eth_in =
+ vlib_get_node_by_name (vlib_get_main (), (u8 *) "ethernet-input")
+ ->index;
- vnet_feature_modify_end_node (
- feature_main.device_input_feature_arc_index, sw_if_index, eth_in);
- itp->itp_flags &= ~IPSEC_PROTECT_FEAT;
+ vnet_feature_modify_end_node (
+ feature_main.device_input_feature_arc_index, sw_if_index, eth_in);
+ }
}
/* Propagate flag change into lookup entries */
@@ -848,6 +869,9 @@ ipsec_tun_protect_adj_delegate_adj_created (adj_index_t ai)
if (!adj_is_midchain (ai))
return;
+ vec_validate_init_empty (ipsec_tun_protect_sa_by_adj_index, ai,
+ INDEX_INVALID);
+
adj = adj_get (ai);
ip_address_from_46 (&adj->sub_type.midchain.next_hop,
@@ -956,16 +980,6 @@ ipsec_tunnel_protect_init (vlib_main_t *vm)
IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS,
IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE);
- /* set up feature nodes to drop outbound packets with no crypto alg set */
- im->esp4_no_crypto_tun_node_index =
- vlib_get_node_by_name (vm, (u8 *) "esp4-no-crypto")->index;
- im->esp6_no_crypto_tun_node_index =
- vlib_get_node_by_name (vm, (u8 *) "esp6-no-crypto")->index;
- im->esp6_encrypt_l2_tun_node_index =
- vlib_get_node_by_name (vm, (u8 *) "esp6-encrypt-tun")->index;
- im->esp4_encrypt_l2_tun_node_index =
- vlib_get_node_by_name (vm, (u8 *) "esp4-encrypt-tun")->index;
-
ipsec_tun_adj_delegate_type =
adj_delegate_register_new_type (&ipsec_tun_adj_delegate_vft);
diff --git a/src/vnet/ipsec/ipsec_tun.h b/src/vnet/ipsec/ipsec_tun.h
index f452fa4354c..9d8a124443d 100644
--- a/src/vnet/ipsec/ipsec_tun.h
+++ b/src/vnet/ipsec/ipsec_tun.h
@@ -182,7 +182,6 @@ always_inline index_t
ipsec_tun_protect_get_sa_out (adj_index_t ai)
{
ASSERT (vec_len (ipsec_tun_protect_sa_by_adj_index) > ai);
- ASSERT (INDEX_INVALID != ipsec_tun_protect_sa_by_adj_index[ai]);
return (ipsec_tun_protect_sa_by_adj_index[ai]);
}