.name = "SA",
.stat_segment_name = "/net/ipsec/sa",
};
+vlib_simple_counter_main_t ipsec_sa_lost_counters = {
+ .name = "SA-lost",
+ .stat_segment_name = "/net/ipsec/sa/lost",
+};
+ipsec_sa_t *ipsec_sa_pool;
static clib_error_t *
ipsec_call_add_del_callbacks (ipsec_main_t * im, ipsec_sa_t * sa,
sa->crypto_calg = im->crypto_algs[crypto_alg].alg;
ASSERT (sa->crypto_iv_size <= ESP_MAX_IV_SIZE);
ASSERT (sa->esp_block_align <= ESP_MAX_BLOCK_SIZE);
- if (IPSEC_CRYPTO_ALG_IS_GCM (crypto_alg))
+ if (IPSEC_CRYPTO_ALG_IS_GCM (crypto_alg) ||
+ IPSEC_CRYPTO_ALG_CTR_AEAD_OTHERS (crypto_alg))
{
sa->integ_icv_size = im->crypto_algs[crypto_alg].icv_size;
ipsec_sa_set_IS_CTR (sa);
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);
+ vlib_validate_simple_counter (&ipsec_sa_lost_counters, sa_index);
+ vlib_zero_simple_counter (&ipsec_sa_lost_counters, sa_index);
tunnel_copy (tun, &sa->tunnel);
sa->id = id;
(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;
}
(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;
}
}
if (im->async_mode)
sa->crypto_op_data = sa->async_op_data.data;
else
- sa->crypto_op_data = sa->sync_op_data.data;
+ {
+ if (ipsec_sa_is_set_IS_ASYNC (sa))
+ {
+ vnet_crypto_request_async_mode (1);
+ sa->crypto_op_data = sa->async_op_data.data;
+ }
+ else
+ sa->crypto_op_data = sa->sync_op_data.data;
+ }
err = ipsec_check_support_cb (im, sa);
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;
}
+ if (ipsec_sa_is_set_IS_TUNNEL (sa) &&
+ AF_IP6 == ip_addr_version (&tun->t_src))
+ ipsec_sa_set_IS_TUNNEL_V6 (sa);
+
if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
{
sa->tunnel_flags = sa->tunnel.t_encap_decap_flags;
if (rv)
{
- pool_put (im->sad, sa);
+ pool_put (ipsec_sa_pool, sa);
return rv;
}
ipsec_sa_stack (sa);
sa->udp_hdr.src_port = clib_host_to_net_u16 (src_port);
if (ipsec_sa_is_set_IS_INBOUND (sa))
- ipsec_register_udp_port (clib_host_to_net_u16 (sa->udp_hdr.dst_port));
+ ipsec_register_udp_port (clib_host_to_net_u16 (sa->udp_hdr.dst_port),
+ !ipsec_sa_is_set_IS_TUNNEL_V6 (sa));
}
hash_set (im->sa_index_by_sa_id, sa->id, sa_index);
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);
/* no recovery possible when deleting an SA */
(void) ipsec_call_add_del_callbacks (im, sa, sa_index, 0);
+ if (ipsec_sa_is_set_IS_ASYNC (sa))
+ vnet_crypto_request_async_mode (0);
if (ipsec_sa_is_set_UDP_ENCAP (sa) && ipsec_sa_is_set_IS_INBOUND (sa))
- ipsec_unregister_udp_port (clib_net_to_host_u16 (sa->udp_hdr.dst_port));
+ ipsec_unregister_udp_port (clib_net_to_host_u16 (sa->udp_hdr.dst_port),
+ !ipsec_sa_is_set_IS_TUNNEL_V6 (sa));
if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
dpo_reset (&sa->dpo);
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);
}
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);
}
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);
ipsec_sa_clear (index_t sai)
{
vlib_zero_combined_counter (&ipsec_sa_counters, sai);
+ vlib_zero_simple_counter (&ipsec_sa_lost_counters, sai);
}
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* */
}
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);
}