ikev2_delete_sa(ikev2_sa_t *sa)
{
ikev2_main_t * km = &ikev2_main;
+ u32 cpu_index = os_get_cpu_number();
uword * p;
ikev2_sa_free_all_vec(sa);
- p = hash_get(km->sa_by_rspi, sa->rspi);
+ p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi);
if (p)
{
- hash_unset(km->sa_by_rspi, sa->rspi);
- pool_put(km->sas, sa);
+ hash_unset(km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi);
+ pool_put(km->per_thread_data[cpu_index].sas, sa);
}
}
ikev2_sa_t * tmp;
u32 i, * delete = 0;
ikev2_child_sa_t * c;
+ u32 cpu_index = os_get_cpu_number();
if (!sa->initial_contact)
return;
/* find old IKE SAs with the same authenticated identity */
- pool_foreach (tmp, km->sas, ({
+ pool_foreach (tmp, km->per_thread_data[cpu_index].sas, ({
if (tmp->i_id.type != sa->i_id.type ||
vec_len(tmp->i_id.data) != vec_len(sa->i_id.data) ||
memcmp(sa->i_id.data, tmp->i_id.data, vec_len(sa->i_id.data)))
continue;
if (sa->rspi != tmp->rspi)
- vec_add1(delete, tmp - km->sas);
+ vec_add1(delete, tmp - km->per_thread_data[cpu_index].sas);
}));
for (i = 0; i < vec_len(delete); i++)
{
- tmp = pool_elt_at_index(km->sas, delete[i]);
+ tmp = pool_elt_at_index(km->per_thread_data[cpu_index].sas, delete[i]);
vec_foreach(c, tmp->childs)
ikev2_delete_tunnel_interface(km->vnet_main, tmp, c);
ikev2_delete_sa(tmp);
{
ipsec_add_del_tunnel_args_t a;
ikev2_sa_transform_t * tr;
- u32 hw_if_index;
u8 encr_type = 0;
if (!child->r_proposals)
return 1;
}
+ memset(&a, 0, sizeof(a));
a.is_add = 1;
a.local_ip.as_u32 = sa->raddr.as_u32;
a.remote_ip.as_u32 = sa->iaddr.as_u32;
return 1;
}
- hw_if_index = ipsec_add_del_tunnel_if(vnm, &a);
- if (hw_if_index == VNET_API_ERROR_INVALID_VALUE)
- {
- clib_warning("create tunnel interface failed remote-ip %U remote-spi %u",
- format_ip4_address, &sa->raddr, child->r_proposals[0].spi);
- ikev2_set_state(sa, IKEV2_STATE_DELETED);
- return hw_if_index;
- }
-
ikev2_calc_child_keys(sa, child);
- ipsec_set_interface_key(vnm, hw_if_index,
- IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO,
- encr_type,
- child->sk_er);
-
- ipsec_set_interface_key(vnm, hw_if_index,
- IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO,
- encr_type,
- child->sk_ei);
+ a.integ_alg = IPSEC_INTEG_ALG_SHA1_96;
+ a.local_integ_key_len = vec_len(child->sk_ar);
+ clib_memcpy(a.local_integ_key, child->sk_ar, a.local_integ_key_len);
+ a.remote_integ_key_len = vec_len(child->sk_ai);
+ clib_memcpy(a.remote_integ_key, child->sk_ai, a.remote_integ_key_len);
- ipsec_set_interface_key(vnm, hw_if_index,
- IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG,
- IPSEC_INTEG_ALG_SHA1_96,
- child->sk_ar);
+ a.crypto_alg = encr_type;
+ a.local_crypto_key_len = vec_len(child->sk_er);
+ clib_memcpy(a.local_crypto_key, child->sk_er, a.local_crypto_key_len);
+ a.remote_crypto_key_len = vec_len(child->sk_ei);
+ clib_memcpy(a.remote_crypto_key, child->sk_ei, a.remote_crypto_key_len);
- ipsec_set_interface_key(vnm, hw_if_index,
- IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG,
- IPSEC_INTEG_ALG_SHA1_96,
- child->sk_ai);
+ ipsec_add_del_tunnel_if(&a);
return 0;
}
a.local_spi = child->i_proposals[0].spi;
a.remote_spi = child->r_proposals[0].spi;
- return ipsec_add_del_tunnel_if(vnm, &a);
+ ipsec_add_del_tunnel_if(&a);
+ return 0;
}
static u32
{
ikev2_main_t * km = &ikev2_main;
ikev2_sa_t * sa;
+ u32 cpu_index = os_get_cpu_number();
- pool_foreach (sa, km->sas, ({
+ pool_foreach (sa, km->per_thread_data[cpu_index].sas, ({
if (sa->ispi == clib_net_to_host_u64(ike->ispi) &&
sa->iaddr.as_u32 == iaddr.as_u32 &&
sa->raddr.as_u32 == raddr.as_u32)
u32 n_left_from, * from, * to_next;
ikev2_next_t next_index;
ikev2_main_t * km = &ikev2_main;
+ u32 cpu_index = os_get_cpu_number();
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
if (sa0->state == IKEV2_STATE_SA_INIT)
{
/* add SA to the pool */
- pool_get (km->sas, sa0);
+ pool_get (km->per_thread_data[cpu_index].sas, sa0);
clib_memcpy(sa0, &sa, sizeof(*sa0));
- hash_set (km->sa_by_rspi, sa0->rspi, sa0 - km->sas);
+ hash_set (km->per_thread_data[cpu_index].sa_by_rspi,
+ sa0->rspi,
+ sa0 - km->per_thread_data[cpu_index].sas);
}
else
{
else if (ike0->exchange == IKEV2_EXCHANGE_IKE_AUTH)
{
uword * p;
- p = hash_get(km->sa_by_rspi, clib_net_to_host_u64(ike0->rspi));
+ p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi,
+ clib_net_to_host_u64(ike0->rspi));
if (p)
{
- sa0 = pool_elt_at_index (km->sas, p[0]);
+ sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas,
+ p[0]);
r = ikev2_retransmit_resp(sa0, ike0);
if (r == 1)
else if (ike0->exchange == IKEV2_EXCHANGE_INFORMATIONAL)
{
uword * p;
- p = hash_get(km->sa_by_rspi, clib_net_to_host_u64(ike0->rspi));
+ p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi,
+ clib_net_to_host_u64(ike0->rspi));
if (p)
{
- sa0 = pool_elt_at_index (km->sas, p[0]);
+ sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas,
+ p[0]);
r = ikev2_retransmit_resp(sa0, ike0);
if (r == 1)
else if (ike0->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA)
{
uword * p;
- p = hash_get(km->sa_by_rspi, clib_net_to_host_u64(ike0->rspi));
+ p = hash_get(km->per_thread_data[cpu_index].sa_by_rspi,
+ clib_net_to_host_u64(ike0->rspi));
if (p)
{
- sa0 = pool_elt_at_index (km->sas, p[0]);
+ sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas,
+ p[0]);
r = ikev2_retransmit_resp(sa0, ike0);
if (r == 1)
{
ikev2_main_t * km = &ikev2_main;
clib_error_t * error;
+ vlib_thread_main_t * tm = vlib_get_thread_main();
+ int thread_id;
memset (km, 0, sizeof (ikev2_main_t));
km->vnet_main = vnet_get_main();
ikev2_crypto_init(km);
- km->sa_by_rspi = hash_create (0, sizeof (uword));
mhash_init_vec_string (&km->profile_index_by_name, sizeof (uword));
+ vec_validate(km->per_thread_data, tm->n_vlib_mains-1);
+ for (thread_id = 0; thread_id < tm->n_vlib_mains - 1; thread_id++)
+ {
+ km->per_thread_data[thread_id].sa_by_rspi =
+ hash_create (0, sizeof (uword));
+ }
+
if ((error = vlib_call_init_function (vm, ikev2_cli_init)))
return error;
vlib_cli_command_t * cmd)
{
ikev2_main_t * km = &ikev2_main;
+ ikev2_main_per_thread_data_t * tkm;
ikev2_sa_t * sa;
ikev2_ts_t * ts;
ikev2_child_sa_t * child;
ikev2_sa_transform_t * tr;
- pool_foreach (sa, km->sas, ({
- u8 * s = 0;
- vlib_cli_output(vm, " iip %U ispi %lx rip %U rspi %lx",
- format_ip4_address, &sa->iaddr, sa->ispi,
- format_ip4_address, &sa->raddr, sa->rspi);
-
- tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- vlib_cli_output(vm, " %v", s);
- vec_free(s);
-
- vlib_cli_output(vm, " nonce i:%U\n r:%U",
- format_hex_bytes, sa->i_nonce, vec_len(sa->i_nonce),
- format_hex_bytes, sa->r_nonce, vec_len(sa->r_nonce));
-
- vlib_cli_output(vm, " SK_d %U",
- format_hex_bytes, sa->sk_d, vec_len(sa->sk_d));
- vlib_cli_output(vm, " SK_a i:%U\n r:%U",
- format_hex_bytes, sa->sk_ai, vec_len(sa->sk_ai),
- format_hex_bytes, sa->sk_ar, vec_len(sa->sk_ar));
- vlib_cli_output(vm, " SK_e i:%U\n r:%U",
- format_hex_bytes, sa->sk_ei, vec_len(sa->sk_ei),
- format_hex_bytes, sa->sk_er, vec_len(sa->sk_er));
- vlib_cli_output(vm, " SK_p i:%U\n r:%U",
- format_hex_bytes, sa->sk_pi, vec_len(sa->sk_pi),
- format_hex_bytes, sa->sk_pr, vec_len(sa->sk_pr));
-
- vlib_cli_output(vm, " identifier (i) %U",
- format_ikev2_id_type_and_data, &sa->i_id);
- vlib_cli_output(vm, " identifier (r) %U",
- format_ikev2_id_type_and_data, &sa->r_id);
-
- vec_foreach(child, sa->childs)
- {
- vlib_cli_output(vm, " child sa %u:", child - sa->childs);
-
- tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN);
- s = format(s, "%U ", format_ikev2_sa_transform, tr);
-
- vlib_cli_output(vm, " %v", s);
- vec_free(s);
-
- vlib_cli_output(vm, " spi(i) %lx spi(r) %lx",
- child->i_proposals ? child->i_proposals[0].spi : 0,
- child->r_proposals ? child->r_proposals[0].spi : 0);
-
- vlib_cli_output(vm, " SK_e i:%U\n r:%U",
- format_hex_bytes, child->sk_ei, vec_len(child->sk_ei),
- format_hex_bytes, child->sk_er, vec_len(child->sk_er));
- vlib_cli_output(vm, " SK_a i:%U\n r:%U",
- format_hex_bytes, child->sk_ai, vec_len(child->sk_ai),
- format_hex_bytes, child->sk_ar, vec_len(child->sk_ar));
- vlib_cli_output(vm, " traffic selectors (i):");
- vec_foreach(ts, child->tsi)
- {
- vlib_cli_output(vm, " %u type %u protocol_id %u addr "
- "%U - %U port %u - %u",
- ts - child->tsi,
- ts->ts_type, ts->protocol_id,
- format_ip4_address, &ts->start_addr,
- format_ip4_address, &ts->end_addr,
- clib_net_to_host_u16( ts->start_port),
- clib_net_to_host_u16( ts->end_port));
- }
- vlib_cli_output(vm, " traffic selectors (r):");
- vec_foreach(ts, child->tsr)
- {
- vlib_cli_output(vm, " %u type %u protocol_id %u addr "
- "%U - %U port %u - %u",
- ts - child->tsr,
- ts->ts_type, ts->protocol_id,
- format_ip4_address, &ts->start_addr,
- format_ip4_address, &ts->end_addr,
- clib_net_to_host_u16( ts->start_port),
- clib_net_to_host_u16( ts->end_port));
- }
- }
- vlib_cli_output(vm, "");
- }));
+ vec_foreach(tkm, km->per_thread_data) {
+ pool_foreach (sa, tkm->sas, ({
+ u8 * s = 0;
+ vlib_cli_output(vm, " iip %U ispi %lx rip %U rspi %lx",
+ format_ip4_address, &sa->iaddr, sa->ispi,
+ format_ip4_address, &sa->raddr, sa->rspi);
+
+ tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ tr = ikev2_sa_get_td_for_type(sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ vlib_cli_output(vm, " %v", s);
+ vec_free(s);
+
+ vlib_cli_output(vm, " nonce i:%U\n r:%U",
+ format_hex_bytes, sa->i_nonce, vec_len(sa->i_nonce),
+ format_hex_bytes, sa->r_nonce, vec_len(sa->r_nonce));
+
+ vlib_cli_output(vm, " SK_d %U",
+ format_hex_bytes, sa->sk_d, vec_len(sa->sk_d));
+ vlib_cli_output(vm, " SK_a i:%U\n r:%U",
+ format_hex_bytes, sa->sk_ai, vec_len(sa->sk_ai),
+ format_hex_bytes, sa->sk_ar, vec_len(sa->sk_ar));
+ vlib_cli_output(vm, " SK_e i:%U\n r:%U",
+ format_hex_bytes, sa->sk_ei, vec_len(sa->sk_ei),
+ format_hex_bytes, sa->sk_er, vec_len(sa->sk_er));
+ vlib_cli_output(vm, " SK_p i:%U\n r:%U",
+ format_hex_bytes, sa->sk_pi, vec_len(sa->sk_pi),
+ format_hex_bytes, sa->sk_pr, vec_len(sa->sk_pr));
+
+ vlib_cli_output(vm, " identifier (i) %U",
+ format_ikev2_id_type_and_data, &sa->i_id);
+ vlib_cli_output(vm, " identifier (r) %U",
+ format_ikev2_id_type_and_data, &sa->r_id);
+
+ vec_foreach(child, sa->childs)
+ {
+ vlib_cli_output(vm, " child sa %u:", child - sa->childs);
+
+ tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ tr = ikev2_sa_get_td_for_type(child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN);
+ s = format(s, "%U ", format_ikev2_sa_transform, tr);
+
+ vlib_cli_output(vm, " %v", s);
+ vec_free(s);
+
+ vlib_cli_output(vm, " spi(i) %lx spi(r) %lx",
+ child->i_proposals ? child->i_proposals[0].spi : 0,
+ child->r_proposals ? child->r_proposals[0].spi : 0);
+
+ vlib_cli_output(vm, " SK_e i:%U\n r:%U",
+ format_hex_bytes, child->sk_ei, vec_len(child->sk_ei),
+ format_hex_bytes, child->sk_er, vec_len(child->sk_er));
+ vlib_cli_output(vm, " SK_a i:%U\n r:%U",
+ format_hex_bytes, child->sk_ai, vec_len(child->sk_ai),
+ format_hex_bytes, child->sk_ar, vec_len(child->sk_ar));
+ vlib_cli_output(vm, " traffic selectors (i):");
+ vec_foreach(ts, child->tsi)
+ {
+ vlib_cli_output(vm, " %u type %u protocol_id %u addr "
+ "%U - %U port %u - %u",
+ ts - child->tsi,
+ ts->ts_type, ts->protocol_id,
+ format_ip4_address, &ts->start_addr,
+ format_ip4_address, &ts->end_addr,
+ clib_net_to_host_u16( ts->start_port),
+ clib_net_to_host_u16( ts->end_port));
+ }
+ vlib_cli_output(vm, " traffic selectors (r):");
+ vec_foreach(ts, child->tsr)
+ {
+ vlib_cli_output(vm, " %u type %u protocol_id %u addr "
+ "%U - %U port %u - %u",
+ ts - child->tsr,
+ ts->ts_type, ts->protocol_id,
+ format_ip4_address, &ts->start_addr,
+ format_ip4_address, &ts->end_addr,
+ clib_net_to_host_u16( ts->start_port),
+ clib_net_to_host_u16( ts->end_port));
+ }
+ }
+ vlib_cli_output(vm, "");
+ }));
+ }
return 0;
}