summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ipsec/ipsec_tun.c')
-rw-r--r--src/vnet/ipsec/ipsec_tun.c119
1 files changed, 117 insertions, 2 deletions
diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c
index 7864cba08be..ca0091b3545 100644
--- a/src/vnet/ipsec/ipsec_tun.c
+++ b/src/vnet/ipsec/ipsec_tun.c
@@ -148,6 +148,7 @@ ipsec_tun_protect_config (ipsec_main_t * im,
ipsec_tun_protect_t * itp, u32 sa_out, u32 * sas_in)
{
ipsec_sa_t *sa;
+ index_t sai;
u32 ii;
itp->itp_n_sa_in = vec_len (sas_in);
@@ -155,7 +156,13 @@ ipsec_tun_protect_config (ipsec_main_t * im,
itp->itp_in_sas[ii] = sas_in[ii];
itp->itp_out_sa = sa_out;
+ ipsec_sa_lock (itp->itp_out_sa);
+
/* *INDENT-OFF* */
+ FOR_EACH_IPSEC_PROTECT_INPUT_SAI(itp, sai,
+ ({
+ ipsec_sa_lock(sai);
+ }));
FOR_EACH_IPSEC_PROTECT_INPUT_SA(itp, sa,
({
if (ipsec_sa_is_set_IS_TUNNEL (sa))
@@ -183,7 +190,6 @@ ipsec_tun_protect_config (ipsec_main_t * im,
* enable the encrypt feature for egress.
*/
ipsec_tun_protect_feature_set (itp, 1);
-
}
static void
@@ -221,10 +227,116 @@ ipsec_tun_protect_find (u32 sw_if_index)
}
int
+ipsec_tun_protect_update_one (u32 sw_if_index, u32 sa_out, u32 sa_in)
+{
+ u32 *sas_in = NULL;
+ int rv;
+
+ vec_add1 (sas_in, sa_in);
+ rv = ipsec_tun_protect_update (sw_if_index, sa_out, sas_in);
+
+ return (rv);
+}
+
+int
+ipsec_tun_protect_update_out (u32 sw_if_index, u32 sa_out)
+{
+ u32 itpi, *sas_in, sai, *saip;
+ ipsec_tun_protect_t *itp;
+ ipsec_main_t *im;
+ int rv;
+
+ sas_in = NULL;
+ rv = 0;
+ im = &ipsec_main;
+ vec_validate_init_empty (ipsec_protect_db.tunnels, sw_if_index,
+ INDEX_INVALID);
+ itpi = ipsec_protect_db.tunnels[sw_if_index];
+
+ if (INDEX_INVALID == itpi)
+ {
+ return (VNET_API_ERROR_INVALID_INTERFACE);
+ }
+
+ itp = pool_elt_at_index (ipsec_protect_pool, itpi);
+
+ /* *INDENT-0FF* */
+ FOR_EACH_IPSEC_PROTECT_INPUT_SAI (itp, sai, (
+ {
+ ipsec_sa_lock (sai);
+ vec_add1 (sas_in, sai);
+ }
+ ));
+ /* *INDENT-ON* */
+
+ sa_out = ipsec_sa_find_and_lock (sa_out);
+
+ if (~0 == sa_out)
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto out;
+ }
+
+ ipsec_tun_protect_unconfig (im, itp);
+ ipsec_tun_protect_config (im, itp, sa_out, sas_in);
+
+ ipsec_sa_unlock (sa_out);
+ vec_foreach (saip, sas_in) ipsec_sa_unlock (*saip);
+
+out:
+ vec_free (sas_in);
+ return (rv);
+}
+
+int
+ipsec_tun_protect_update_in (u32 sw_if_index, u32 sa_in)
+{
+ u32 itpi, *sas_in, sa_out;
+ ipsec_tun_protect_t *itp;
+ ipsec_main_t *im;
+ int rv;
+
+ sas_in = NULL;
+ rv = 0;
+ im = &ipsec_main;
+ vec_validate_init_empty (ipsec_protect_db.tunnels, sw_if_index,
+ INDEX_INVALID);
+ itpi = ipsec_protect_db.tunnels[sw_if_index];
+
+ if (INDEX_INVALID == itpi)
+ {
+ return (VNET_API_ERROR_INVALID_INTERFACE);
+ }
+
+ sa_in = ipsec_sa_find_and_lock (sa_in);
+
+ if (~0 == sa_in)
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto out;
+ }
+ vec_add1 (sas_in, sa_in);
+
+ itp = pool_elt_at_index (ipsec_protect_pool, itpi);
+ sa_out = itp->itp_out_sa;
+
+ ipsec_sa_lock (sa_out);
+
+ ipsec_tun_protect_unconfig (im, itp);
+ ipsec_tun_protect_config (im, itp, sa_out, sas_in);
+
+ ipsec_sa_unlock (sa_out);
+ ipsec_sa_unlock (sa_in);
+out:
+ vec_free (sas_in);
+ return (rv);
+}
+
+int
ipsec_tun_protect_update (u32 sw_if_index, u32 sa_out, u32 * sas_in)
{
- u32 itpi, ii;
ipsec_tun_protect_t *itp;
+ u32 itpi, ii, *saip;
ipsec_main_t *im;
int rv;
@@ -330,7 +442,10 @@ ipsec_tun_protect_update (u32 sw_if_index, u32 sa_out, u32 * sas_in)
ipsec_tun_protect_config (im, itp, sa_out, sas_in);
}
+ ipsec_sa_unlock (sa_out);
+ vec_foreach (saip, sas_in) ipsec_sa_unlock (*saip);
vec_free (sas_in);
+
out:
return (rv);
}