u32 tx_table_id,
u32 salt,
const ip46_address_t * tun_src,
- const ip46_address_t * tun_dst, u32 * sa_out_index)
+ const ip46_address_t * tun_dst, u32 * sa_out_index,
+ u16 dst_port)
{
vlib_main_t *vm = vlib_get_main ();
ipsec_main_t *im = &ipsec_main;
sa->protocol = proto;
sa->flags = flags;
sa->salt = salt;
- ipsec_sa_set_integ_alg (sa, integ_alg);
- clib_memcpy (&sa->integ_key, ik, sizeof (sa->integ_key));
+ sa->encrypt_thread_index = (vlib_num_workers ())? ~0 : 0;
+ sa->decrypt_thread_index = (vlib_num_workers ())? ~0 : 0;
+ if (integ_alg != IPSEC_INTEG_ALG_NONE)
+ {
+ ipsec_sa_set_integ_alg (sa, integ_alg);
+ clib_memcpy (&sa->integ_key, ik, sizeof (sa->integ_key));
+ }
ipsec_sa_set_crypto_alg (sa, crypto_alg);
clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
ip46_address_copy (&sa->tunnel_src_addr, tun_src);
return VNET_API_ERROR_KEY_LENGTH;
}
- sa->integ_key_index = vnet_crypto_key_add (vm,
- im->integ_algs[integ_alg].alg,
- (u8 *) ik->data, ik->len);
- if (~0 == sa->integ_key_index)
+ if (integ_alg != IPSEC_INTEG_ALG_NONE)
{
- pool_put (im->sad, sa);
- return VNET_API_ERROR_KEY_LENGTH;
+ sa->integ_key_index = vnet_crypto_key_add (vm,
+ im->
+ integ_algs[integ_alg].alg,
+ (u8 *) ik->data, ik->len);
+ if (~0 == sa->integ_key_index)
+ {
+ pool_put (im->sad, sa);
+ return VNET_API_ERROR_KEY_LENGTH;
+ }
}
err = ipsec_check_support_cb (im, sa);
if (ipsec_sa_is_set_UDP_ENCAP (sa))
{
- sa->udp_hdr.src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
- sa->udp_hdr.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+ if (dst_port == IPSEC_UDP_PORT_NONE)
+ {
+ sa->udp_hdr.src_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+ sa->udp_hdr.dst_port = clib_host_to_net_u16 (UDP_DST_PORT_ipsec);
+ }
+ else
+ {
+ sa->udp_hdr.src_port = clib_host_to_net_u16 (dst_port);
+ sa->udp_hdr.dst_port = clib_host_to_net_u16 (dst_port);
+ }
}
hash_set (im->sa_index_by_sa_id, sa->id, sa_index);
dpo_reset (&sa->dpo);
}
vnet_crypto_key_del (vm, sa->crypto_key_index);
- vnet_crypto_key_del (vm, sa->integ_key_index);
+ if (sa->integ_alg != IPSEC_INTEG_ALG_NONE)
+ vnet_crypto_key_del (vm, sa->integ_key_index);
pool_put (im->sad, sa);
}
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);
+
+ fib_node_lock (&sa->node);
+}
+
index_t
ipsec_sa_find_and_lock (u32 id)
{