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.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c
index 9b76d311bc2..fb530c8dc9f 100644
--- a/src/vnet/ipsec/ipsec_tun.c
+++ b/src/vnet/ipsec/ipsec_tun.c
@@ -16,6 +16,7 @@
*/
#include <vnet/ipsec/ipsec_tun.h>
+#include <vnet/ipsec/ipsec_itf.h>
#include <vnet/ipsec/esp.h>
#include <vnet/udp/udp.h>
#include <vnet/adj/adj_delegate.h>
@@ -126,14 +127,20 @@ ipsec_tun_protect_from_const_base (const adj_delegate_t * ad)
}
static u32
-ipsec_tun_protect_get_adj_next (const ipsec_tun_protect_t * itp)
+ipsec_tun_protect_get_adj_next (vnet_link_t linkt,
+ const ipsec_tun_protect_t * itp)
{
ipsec_main_t *im;
ipsec_sa_t *sa;
bool is_ip4;
u32 next;
- is_ip4 = ip46_address_is_ip4 (&itp->itp_tun.src);
+
+ if (itp->itp_flags & IPSEC_PROTECT_ITF)
+ is_ip4 = linkt == VNET_LINK_IP4;
+ else
+ is_ip4 = ip46_address_is_ip4 (&itp->itp_tun.src);
+
sa = ipsec_sa_get (itp->itp_out_sa);
im = &ipsec_main;
@@ -169,7 +176,7 @@ ipsec_tun_protect_add_adj (adj_index_t ai, const ipsec_tun_protect_t * itp)
{
ipsec_tun_protect_sa_by_adj_index[ai] = itp->itp_out_sa;
adj_nbr_midchain_update_next_node
- (ai, ipsec_tun_protect_get_adj_next (itp));
+ (ai, ipsec_tun_protect_get_adj_next (adj_get_link_type (ai), itp));
}
}
@@ -249,6 +256,9 @@ ipsec_tun_protect_adj_add (adj_index_t ai, void *arg)
itp - ipsec_tun_protect_pool);
ipsec_tun_protect_add_adj (ai, itp);
+ if (itp->itp_flags & IPSEC_PROTECT_ITF)
+ ipsec_itf_adj_stack (ai, itp->itp_out_sa);
+
return (ADJ_WALK_RC_CONTINUE);
}
@@ -349,9 +359,14 @@ ipsec_tun_protect_rx_db_remove (ipsec_main_t * im,
static adj_walk_rc_t
ipsec_tun_protect_adj_remove (adj_index_t ai, void *arg)
{
+ ipsec_tun_protect_t *itp = arg;
+
adj_delegate_remove (ai, ipsec_tun_adj_delegate_type);
ipsec_tun_protect_add_adj (ai, NULL);
+ if (itp->itp_flags & IPSEC_PROTECT_ITF)
+ ipsec_itf_adj_unstack (ai);
+
return (ADJ_WALK_RC_CONTINUE);
}
@@ -404,8 +419,11 @@ ipsec_tun_protect_set_crypto_addr (ipsec_tun_protect_t * itp)
{
itp->itp_crypto.src = sa->tunnel_dst_addr;
itp->itp_crypto.dst = sa->tunnel_src_addr;
- ipsec_sa_set_IS_PROTECT (sa);
- itp->itp_flags |= IPSEC_PROTECT_ENCAPED;
+ if (!(itp->itp_flags & IPSEC_PROTECT_ITF))
+ {
+ ipsec_sa_set_IS_PROTECT (sa);
+ itp->itp_flags |= IPSEC_PROTECT_ENCAPED;
+ }
}
else
{
@@ -657,6 +675,7 @@ ipsec_tun_protect_update (u32 sw_if_index,
pool_get_zero (ipsec_tun_protect_pool, itp);
itp->itp_sw_if_index = sw_if_index;
+ itp->itp_ai = ADJ_INDEX_INVALID;
itp->itp_n_sa_in = vec_len (sas_in);
for (ii = 0; ii < itp->itp_n_sa_in; ii++)
@@ -673,7 +692,24 @@ ipsec_tun_protect_update (u32 sw_if_index,
if (rv)
goto out;
- if (ip46_address_is_zero (&itp->itp_tun.dst))
+ if (ip46_address_is_zero (&itp->itp_tun.src))
+ {
+ /* must be one of thos pesky ipsec interfaces that has no encap.
+ * the encap then MUST comefrom the tunnel mode SA.
+ */
+ ipsec_sa_t *sa;
+
+ sa = ipsec_sa_get (itp->itp_out_sa);
+
+ if (!ipsec_sa_is_set_IS_TUNNEL (sa))
+ {
+ rv = VNET_API_ERROR_INVALID_DST_ADDRESS;
+ goto out;
+ }
+
+ itp->itp_flags |= IPSEC_PROTECT_ITF;
+ }
+ else if (ip46_address_is_zero (&itp->itp_tun.dst))
{
/* tunnel has no destination address, presumably because it's p2mp
in which case we use the nh that this is protection for */
@@ -690,7 +726,7 @@ ipsec_tun_protect_update (u32 sw_if_index,
/*
* add to the tunnel DB for ingress
- * - if the SA is in trasnport mode, then the packates will arrivw
+ * - if the SA is in trasnport mode, then the packates will arrive
* with the IP src,dst of the protected tunnel, in which case we can
* simply strip the IP header and hand the payload to the protocol
* appropriate input handler
@@ -752,6 +788,9 @@ ipsec_tun_protect_del (u32 sw_if_index, const ip_address_t * nh)
itp = ipsec_tun_protect_get (itpi);
ipsec_tun_protect_unconfig (im, itp);
+ if (ADJ_INDEX_INVALID != itp->itp_ai)
+ adj_unlock (itp->itp_ai);
+
clib_mem_free (itp->itp_key);
pool_put (ipsec_tun_protect_pool, itp);
@@ -828,13 +867,7 @@ ipsec_tun_protect_adj_delegate_adj_created (adj_index_t ai)
itpi = ipsec_tun_protect_find (adj->rewrite_header.sw_if_index, &ip);
if (INDEX_INVALID != itpi)
- {
- const ipsec_tun_protect_t *itp;
-
- itp = ipsec_tun_protect_get (itpi);
- adj_delegate_add (adj_get (ai), ipsec_tun_adj_delegate_type, itpi);
- ipsec_tun_protect_add_adj (ai, itp);
- }
+ ipsec_tun_protect_adj_add (ai, ipsec_tun_protect_get (itpi));
}
static u8 *