aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_if.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-07-12 09:15:26 +0000
committerDave Barach <openvpp@barachs.net>2019-07-12 12:24:55 +0000
commit495d7ffbc82823edccabab960fc81a909f80075d (patch)
treed4244f743b7406bbdc4235e6accdfc4899a88b83 /src/vnet/ipsec/ipsec_if.c
parentdef35a2352c9a54f748d301ffa47a446d25a83e0 (diff)
ipsec: Reference count the SAs
- this remove the need to iterate through all state when deleting an SA - and ensures that if the SA is deleted by the client is remains for use in any state until that state is also removed. Type: feature Change-Id: I438cb67588cb65c701e49a7a9518f88641925419 Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/ipsec/ipsec_if.c')
-rw-r--r--src/vnet/ipsec/ipsec_if.c75
1 files changed, 35 insertions, 40 deletions
diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c
index 8e4f3f1359d..5fc49e1af4e 100644
--- a/src/vnet/ipsec/ipsec_if.c
+++ b/src/vnet/ipsec/ipsec_if.c
@@ -321,18 +321,18 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
ipsec_mk_key (&integ_key,
args->remote_integ_key, args->remote_integ_key_len);
- rv = ipsec_sa_add (ipsec_tun_mk_input_sa_id (dev_instance),
- args->remote_spi,
- IPSEC_PROTOCOL_ESP,
- args->crypto_alg,
- &crypto_key,
- args->integ_alg,
- &integ_key,
- (flags | IPSEC_SA_FLAG_IS_INBOUND),
- args->tx_table_id,
- args->salt,
- &args->remote_ip,
- &args->local_ip, &t->input_sa_index);
+ rv = ipsec_sa_add_and_lock (ipsec_tun_mk_input_sa_id (dev_instance),
+ args->remote_spi,
+ IPSEC_PROTOCOL_ESP,
+ args->crypto_alg,
+ &crypto_key,
+ args->integ_alg,
+ &integ_key,
+ (flags | IPSEC_SA_FLAG_IS_INBOUND),
+ args->tx_table_id,
+ args->salt,
+ &args->remote_ip,
+ &args->local_ip, &t->input_sa_index);
if (rv)
return rv;
@@ -342,18 +342,18 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
ipsec_mk_key (&integ_key,
args->local_integ_key, args->local_integ_key_len);
- rv = ipsec_sa_add (ipsec_tun_mk_output_sa_id (dev_instance),
- args->local_spi,
- IPSEC_PROTOCOL_ESP,
- args->crypto_alg,
- &crypto_key,
- args->integ_alg,
- &integ_key,
- flags,
- args->tx_table_id,
- args->salt,
- &args->local_ip,
- &args->remote_ip, &t->output_sa_index);
+ rv = ipsec_sa_add_and_lock (ipsec_tun_mk_output_sa_id (dev_instance),
+ args->local_spi,
+ IPSEC_PROTOCOL_ESP,
+ args->crypto_alg,
+ &crypto_key,
+ args->integ_alg,
+ &integ_key,
+ flags,
+ args->tx_table_id,
+ args->salt,
+ &args->local_ip,
+ &args->remote_ip, &t->output_sa_index);
if (rv)
return rv;
@@ -420,11 +420,11 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
hash_unset (im->ipsec_if_real_dev_by_show_dev, t->show_instance);
im->ipsec_if_by_sw_if_index[t->sw_if_index] = ~0;
- pool_put (im->tunnel_interfaces, t);
-
/* delete input and output SA */
- ipsec_sa_del (ipsec_tun_mk_input_sa_id (ti));
- ipsec_sa_del (ipsec_tun_mk_output_sa_id (ti));
+ ipsec_sa_unlock (t->input_sa_index);
+ ipsec_sa_unlock (t->output_sa_index);
+
+ pool_put (im->tunnel_interfaces, t);
}
if (sw_if_index)
@@ -447,17 +447,12 @@ ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index, u32 sa_id,
hi = vnet_get_hw_interface (vnm, hw_if_index);
t = pool_elt_at_index (im->tunnel_interfaces, hi->dev_instance);
- sa_index = ipsec_get_sa_index_by_sa_id (sa_id);
- if (sa_index == ~0)
- {
- clib_warning ("SA with ID %u not found", sa_id);
- return VNET_API_ERROR_INVALID_VALUE;
- }
+ sa_index = ipsec_sa_find_and_lock (sa_id);
- if (ipsec_is_sa_used (sa_index))
+ if (INDEX_INVALID == sa_index)
{
- clib_warning ("SA with ID %u is already in use", sa_id);
- return VNET_API_ERROR_INVALID_VALUE;
+ clib_warning ("SA with ID %u not found", sa_id);
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
}
sa = pool_elt_at_index (im->sad, sa_index);
@@ -537,15 +532,15 @@ ipsec_set_interface_sa (vnet_main_t * vnm, u32 hw_if_index, u32 sa_id,
}
/* remove sa_id to sa_index mapping on old SA */
- if (ipsec_get_sa_index_by_sa_id (old_sa->id) == old_sa_index)
- hash_unset (im->sa_index_by_sa_id, old_sa->id);
+ hash_unset (im->sa_index_by_sa_id, old_sa->id);
if (ipsec_add_del_sa_sess_cb (im, old_sa_index, 0))
{
clib_warning ("IPsec backend add/del callback returned error");
return VNET_API_ERROR_SYSCALL_ERROR_1;
}
- ipsec_sa_del (old_sa->id);
+
+ ipsec_sa_unlock (old_sa_index);
return 0;
}