diff options
Diffstat (limited to 'src/vnet/ipsec/ipsec_tun.c')
-rw-r--r-- | src/vnet/ipsec/ipsec_tun.c | 119 |
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); } |