+
+ itpi = ipsec_tun_protect_find (sw_if_index, nh);
+
+ if (INDEX_INVALID == itpi)
+ {
+ return (VNET_API_ERROR_INVALID_INTERFACE);
+ }
+
+ itp = pool_elt_at_index (ipsec_tun_protect_pool, itpi);
+
+ /* *INDENT-OFF* */
+ 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,
+ const ip_address_t * nh, 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;
+ itpi = ipsec_tun_protect_find (sw_if_index, nh);
+
+ 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_tun_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);
+}
+
+static void
+ipsec_tun_protect_update_from_teib (ipsec_tun_protect_t * itp,
+ const teib_entry_t * ne)
+{
+ if (NULL != ne)
+ {
+ const fib_prefix_t *pfx;
+
+ pfx = teib_entry_get_nh (ne);
+
+ ip46_address_copy (&itp->itp_tun.dst, &pfx->fp_addr);
+ }
+ else
+ ip46_address_reset (&itp->itp_tun.dst);
+}
+
+int
+ipsec_tun_protect_update (u32 sw_if_index,
+ const ip_address_t * nh, u32 sa_out, u32 * sas_in)
+{
+ ipsec_tun_protect_t *itp;
+ u32 itpi, ii, *saip;
+ ipsec_main_t *im;
+ int rv;
+
+ ITP_DBG2 ("update: %U/%U",
+ format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index,
+ format_ip_address, nh);
+
+ rv = 0;
+ im = &ipsec_main;
+ if (NULL == nh)
+ nh = &IP_ADDR_ALL_0;
+ itpi = ipsec_tun_protect_find (sw_if_index, nh);