summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/ipsec/ipsec_if.c
diff options
context:
space:
mode:
authorMatthew Smith <mgsmith@netgate.com>2016-06-21 16:05:09 -0500
committerDamjan Marion <damarion@cisco.com>2016-06-29 09:18:43 +0000
commit2838a2355a130b951ef5e3ebbf630f6d2c65b120 (patch)
tree341df8fcee0c3a301ff4632604c1a762a16052d3 /vnet/vnet/ipsec/ipsec_if.c
parent816f3e1b879b43802ea8035d6a3f1cbf5db76825 (diff)
VPP-158: VPP crashes in IKEv2 code when running multithreaded
Change tunnel interface creation to be done from the main thread instead of a worker thread by calling vl_api_rpc_call_main_thread. Make per-thread copies of volatile elements in ikev2_main. Change-Id: I4cda8aaa392a04c2aea2d50a52a07933cf40c016 Signed-off-by: Matthew Smith <mgsmith@netgate.com>
Diffstat (limited to 'vnet/vnet/ipsec/ipsec_if.c')
-rw-r--r--vnet/vnet/ipsec/ipsec_if.c52
1 files changed, 50 insertions, 2 deletions
diff --git a/vnet/vnet/ipsec/ipsec_if.c b/vnet/vnet/ipsec/ipsec_if.c
index 30631b60587..7a85fb16781 100644
--- a/vnet/vnet/ipsec/ipsec_if.c
+++ b/vnet/vnet/ipsec/ipsec_if.c
@@ -21,6 +21,8 @@
#include <vnet/ipsec/ipsec.h>
+void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
+
static u8 * format_ipsec_name (u8 * s, va_list * args)
{
u32 dev_instance = va_arg (*args, u32);
@@ -46,8 +48,30 @@ VNET_HW_INTERFACE_CLASS (ipsec_hw_class) = {
.name = "IPSec",
};
-u32
-ipsec_add_del_tunnel_if (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args)
+
+static int
+ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
+ ipsec_add_del_tunnel_args_t * args);
+
+static int
+ipsec_add_del_tunnel_if_rpc_callback (ipsec_add_del_tunnel_args_t *a)
+{
+ vnet_main_t * vnm = vnet_get_main();
+ ASSERT(os_get_cpu_number() == 0);
+
+ return ipsec_add_del_tunnel_if_internal(vnm, a);
+}
+
+int
+ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args)
+{
+ vl_api_rpc_call_main_thread (ipsec_add_del_tunnel_if_rpc_callback,
+ (u8 *) args, sizeof(*args));
+ return 0;
+}
+
+int
+ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args)
{
ipsec_tunnel_if_t * t;
ipsec_main_t * im = &ipsec_main;
@@ -77,6 +101,18 @@ ipsec_add_del_tunnel_if (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args)
sa->is_tunnel = 1;
sa->use_esn = args->esn;
sa->use_anti_replay = args->anti_replay;
+ sa->integ_alg = args->integ_alg;
+ if (args->remote_integ_key_len <= sizeof(args->remote_integ_key))
+ {
+ sa->integ_key_len = args->remote_integ_key_len;
+ clib_memcpy(sa->integ_key, args->remote_integ_key, args->remote_integ_key_len);
+ }
+ sa->crypto_alg = args->crypto_alg;
+ if (args->remote_crypto_key_len <= sizeof(args->remote_crypto_key))
+ {
+ sa->crypto_key_len = args->remote_crypto_key_len;
+ clib_memcpy(sa->crypto_key, args->remote_crypto_key, args->remote_crypto_key_len);
+ }
pool_get (im->sad, sa);
memset (sa, 0, sizeof (*sa));
@@ -88,6 +124,18 @@ ipsec_add_del_tunnel_if (vnet_main_t * vnm, ipsec_add_del_tunnel_args_t * args)
sa->seq = 1;
sa->use_esn = args->esn;
sa->use_anti_replay = args->anti_replay;
+ sa->integ_alg = args->integ_alg;
+ if (args->local_integ_key_len <= sizeof(args->local_integ_key))
+ {
+ sa->integ_key_len = args->local_integ_key_len;
+ clib_memcpy(sa->integ_key, args->local_integ_key, args->local_integ_key_len);
+ }
+ sa->crypto_alg = args->crypto_alg;
+ if (args->local_crypto_key_len <= sizeof(args->local_crypto_key))
+ {
+ sa->crypto_key_len = args->local_crypto_key_len;
+ clib_memcpy(sa->crypto_key, args->local_crypto_key, args->local_crypto_key_len);
+ }
hash_set (im->ipsec_if_pool_index_by_key, key, t - im->tunnel_interfaces);