ipsec_tun_protect_feature_set (ipsec_tun_protect_t * itp, u8 enable)
{
u32 sai = itp->itp_out_sa;
- int is_ip4, is_l2, rv;
+ int rv;
- is_ip4 = ip46_address_is_ip4 (&itp->itp_tun.src);
- is_l2 = itp->itp_flags & IPSEC_PROTECT_L2;
+ const char *enc_node = (ip46_address_is_ip4 (&itp->itp_tun.src) ?
+ "esp4-encrypt-tun" : "esp6-encrypt-tun");
- if (is_ip4)
+ if (itp->itp_flags & IPSEC_PROTECT_L2)
{
- if (is_l2)
- rv = vnet_feature_enable_disable ("ethernet-output",
- "esp4-encrypt-tun",
- itp->itp_sw_if_index, enable,
- &sai, sizeof (sai));
- else
- rv = vnet_feature_enable_disable ("ip4-output",
- "esp4-encrypt-tun",
- itp->itp_sw_if_index, enable,
- &sai, sizeof (sai));
+ rv = vnet_feature_enable_disable ("ethernet-output",
+ enc_node,
+ itp->itp_sw_if_index, enable,
+ &sai, sizeof (sai));
}
else
{
- if (is_l2)
- rv = vnet_feature_enable_disable ("ethernet-output",
- "esp6-encrypt-tun",
- itp->itp_sw_if_index, enable,
- &sai, sizeof (sai));
- else
- rv = vnet_feature_enable_disable ("ip6-output",
- "esp6-encrypt-tun",
- itp->itp_sw_if_index, enable,
- &sai, sizeof (sai));
+ rv = vnet_feature_enable_disable ("ip4-output",
+ enc_node,
+ itp->itp_sw_if_index, enable,
+ &sai, sizeof (sai));
+ rv = vnet_feature_enable_disable ("ip6-output",
+ enc_node,
+ itp->itp_sw_if_index, enable,
+ &sai, sizeof (sai));
}
-
ASSERT (!rv);
return (rv);
}
if (ip46_address_is_ip4 (&itp->itp_crypto.dst))
{
ipsec4_tunnel_key_t key = {
- .remote_ip = itp->itp_crypto.dst.ip4.as_u32,
+ .remote_ip = itp->itp_crypto.dst.ip4,
.spi = clib_host_to_net_u32 (sa->spi),
};
hash_set (im->tun4_protect_by_key, key.as_u64, res.as_u64);
+ if (1 == hash_elts(im->tun4_protect_by_key))
+ udp_register_dst_port (vlib_get_main(),
+ UDP_DST_PORT_ipsec,
+ ipsec4_tun_input_node.index, 1);
}
else
{
if (ip46_address_is_ip4 (&itp->itp_crypto.dst))
{
ipsec4_tunnel_key_t key = {
- .remote_ip = itp->itp_crypto.dst.ip4.as_u32,
+ .remote_ip = itp->itp_crypto.dst.ip4,
.spi = clib_host_to_net_u32 (sa->spi),
};
hash_unset (im->tun4_protect_by_key, &key);
+ if (0 == hash_elts(im->tun4_protect_by_key))
+ udp_unregister_dst_port (vlib_get_main(),
+ UDP_DST_PORT_ipsec,
+ 1);
}
else
{
ipsec_tun_protect_unconfig (ipsec_main_t * im, ipsec_tun_protect_t * itp)
{
ipsec_sa_t *sa;
+ index_t sai;
ipsec_tun_protect_feature_set (itp, 0);
({
ipsec_sa_unset_IS_PROTECT (sa);
}));
- /* *INDENT-ON* */
ipsec_tun_protect_db_remove (im, itp);
+
+ ipsec_sa_unlock(itp->itp_out_sa);
+
+ FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
+ ({
+ ipsec_sa_unlock(sai);
+ }));
+ /* *INDENT-ON* */
}
index_t
vec_foreach_index (ii, sas_in)
{
- sas_in[ii] = ipsec_get_sa_index_by_sa_id (sas_in[ii]);
+ sas_in[ii] = ipsec_sa_find_and_lock (sas_in[ii]);
if (~0 == sas_in[ii])
{
rv = VNET_API_ERROR_INVALID_VALUE;
}
}
- sa_out = ipsec_get_sa_index_by_sa_id (sa_out);
+ sa_out = ipsec_sa_find_and_lock (sa_out);
if (~0 == sa_out)
{
pool_put (ipsec_protect_pool, itp);
- /* if (0 == hash_elts (im->tun4_protect_by_key)) */
- /* ip4_unregister_protocol (IP_PROTOCOL_IPSEC_ESP); */
- /* if (0 == hash_elts (im->tun6_protect_by_key)) */
- /* ip6_unregister_protocol (IP_PROTOCOL_IPSEC_ESP); */
+ if (0 == hash_elts (im->tun4_protect_by_key))
+ ip4_unregister_protocol (IP_PROTOCOL_IPSEC_ESP);
+ if (0 == hash_elts (im->tun6_protect_by_key))
+ ip6_unregister_protocol (IP_PROTOCOL_IPSEC_ESP);
return (0);
}