summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ipsec_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ipsec/ipsec_if.c')
-rw-r--r--src/vnet/ipsec/ipsec_if.c147
1 files changed, 71 insertions, 76 deletions
diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c
index 0dfb6909e42..357d638d38b 100644
--- a/src/vnet/ipsec/ipsec_if.c
+++ b/src/vnet/ipsec/ipsec_if.c
@@ -250,6 +250,18 @@ ipsec_add_del_tunnel_if (ipsec_add_del_tunnel_args_t * args)
return 0;
}
+static u32
+ipsec_tun_mk_input_sa_id (u32 ti)
+{
+ return (0x80000000 | ti);
+}
+
+static u32
+ipsec_tun_mk_output_sa_id (u32 ti)
+{
+ return (0xc0000000 | ti);
+}
+
int
ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
ipsec_add_del_tunnel_args_t * args,
@@ -260,12 +272,13 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
vnet_hw_interface_t *hi = NULL;
u32 hw_if_index = ~0;
uword *p;
- ipsec_sa_t *sa;
u32 dev_instance;
u32 slot;
- u32 tx_fib_index = ~0;
+ ipsec_key_t crypto_key, integ_key;
+ ipsec_sa_flags_t flags;
+ int rv;
- u64 key = (u64) args->remote_ip.as_u32 << 32 | (u64) args->remote_spi;
+ u64 key = (u64) args->remote_ip.ip4.as_u32 << 32 | (u64) args->remote_spi;
p = hash_get (im->ipsec_if_pool_index_by_key, key);
if (args->is_add)
@@ -274,10 +287,6 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
if (p)
return VNET_API_ERROR_INVALID_VALUE;
- tx_fib_index = fib_table_find (FIB_PROTOCOL_IP4, args->tx_table_id);
- if (tx_fib_index == ~((u32) 0))
- return VNET_API_ERROR_NO_SUCH_FIB;
-
pool_get_aligned (im->tunnel_interfaces, t, CLIB_CACHE_LINE_BYTES);
clib_memset (t, 0, sizeof (*t));
@@ -296,59 +305,53 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
hash_set (im->ipsec_if_real_dev_by_show_dev, t->show_instance,
dev_instance);
- pool_get (im->sad, sa);
- clib_memset (sa, 0, sizeof (*sa));
- t->input_sa_index = sa - im->sad;
- sa->protocol = IPSEC_PROTOCOL_ESP;
- sa->spi = args->remote_spi;
- sa->tunnel_src_addr.ip4.as_u32 = args->remote_ip.as_u32;
- sa->tunnel_dst_addr.ip4.as_u32 = args->local_ip.as_u32;
- sa->is_tunnel = 1;
- sa->use_esn = args->esn;
- sa->use_anti_replay = args->anti_replay;
- sa->integ_alg = args->integ_alg;
- sa->udp_encap = args->udp_encap;
- sa->tx_fib_index = ~((u32) 0); /* Not used, but set for troubleshooting */
- if (args->remote_integ_key_len <= sizeof (args->remote_integ_key))
- {
- sa->integ_key_len = args->remote_integ_key_len;
- clib_memcpy (sa->integ_key, args->remote_integ_key,
- args->remote_integ_key_len);
- }
- sa->crypto_alg = args->crypto_alg;
- if (args->remote_crypto_key_len <= sizeof (args->remote_crypto_key))
- {
- sa->crypto_key_len = args->remote_crypto_key_len;
- clib_memcpy (sa->crypto_key, args->remote_crypto_key,
- args->remote_crypto_key_len);
- }
-
- pool_get (im->sad, sa);
- clib_memset (sa, 0, sizeof (*sa));
- t->output_sa_index = sa - im->sad;
- sa->protocol = IPSEC_PROTOCOL_ESP;
- sa->spi = args->local_spi;
- sa->tunnel_src_addr.ip4.as_u32 = args->local_ip.as_u32;
- sa->tunnel_dst_addr.ip4.as_u32 = args->remote_ip.as_u32;
- sa->is_tunnel = 1;
- sa->use_esn = args->esn;
- sa->use_anti_replay = args->anti_replay;
- sa->integ_alg = args->integ_alg;
- sa->udp_encap = args->udp_encap;
- sa->tx_fib_index = tx_fib_index;
- if (args->local_integ_key_len <= sizeof (args->local_integ_key))
- {
- sa->integ_key_len = args->local_integ_key_len;
- clib_memcpy (sa->integ_key, args->local_integ_key,
- args->local_integ_key_len);
- }
- sa->crypto_alg = args->crypto_alg;
- if (args->local_crypto_key_len <= sizeof (args->local_crypto_key))
- {
- sa->crypto_key_len = args->local_crypto_key_len;
- clib_memcpy (sa->crypto_key, args->local_crypto_key,
- args->local_crypto_key_len);
- }
+ flags = IPSEC_SA_FLAG_IS_TUNNEL;
+ if (args->udp_encap)
+ flags |= IPSEC_SA_FLAG_UDP_ENCAP;
+ if (args->esn)
+ flags |= IPSEC_SA_FLAG_USE_EXTENDED_SEQ_NUM;
+ if (args->anti_replay)
+ flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
+
+ ipsec_mk_key (&crypto_key,
+ args->remote_crypto_key, args->remote_crypto_key_len);
+ ipsec_mk_key (&integ_key,
+ args->remote_integ_key, args->remote_integ_key_len);
+
+ rv = ipsec_sa_add (ipsec_tun_mk_input_sa_id (dev_instance),
+ args->remote_spi,
+ IPSEC_PROTOCOL_ESP,
+ args->crypto_alg,
+ &crypto_key,
+ args->integ_alg,
+ &integ_key,
+ flags,
+ args->tx_table_id,
+ &args->remote_ip,
+ &args->local_ip, &t->input_sa_index);
+
+ if (rv)
+ return VNET_API_ERROR_UNIMPLEMENTED;
+
+ ipsec_mk_key (&crypto_key,
+ args->local_crypto_key, args->local_crypto_key_len);
+ ipsec_mk_key (&integ_key,
+ args->local_integ_key, args->local_integ_key_len);
+
+ rv = ipsec_sa_add (ipsec_tun_mk_output_sa_id (dev_instance),
+ args->local_spi,
+ IPSEC_PROTOCOL_ESP,
+ args->crypto_alg,
+ &crypto_key,
+ args->integ_alg,
+ &integ_key,
+ flags,
+ args->tx_table_id,
+ &args->local_ip,
+ &args->remote_ip, &t->output_sa_index);
+
+ if (rv)
+ return VNET_API_ERROR_UNIMPLEMENTED;
hash_set (im->ipsec_if_pool_index_by_key, key,
t - im->tunnel_interfaces);
@@ -392,18 +395,14 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
vnet_delete_hw_interface (vnm, t->hw_if_index);
- /* delete input and output SA */
-
- sa = pool_elt_at_index (im->sad, t->input_sa_index);
- pool_put (im->sad, sa);
-
- sa = pool_elt_at_index (im->sad, t->output_sa_index);
- pool_put (im->sad, sa);
-
hash_unset (im->ipsec_if_pool_index_by_key, key);
hash_unset (im->ipsec_if_real_dev_by_show_dev, t->show_instance);
pool_put (im->tunnel_interfaces, t);
+
+ /* delete input and output SA */
+ ipsec_sa_del (ipsec_tun_mk_input_sa_id (p[0]));
+ ipsec_sa_del (ipsec_tun_mk_output_sa_id (p[0]));
}
if (sw_if_index)
@@ -493,29 +492,25 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index,
{
sa = pool_elt_at_index (im->sad, t->output_sa_index);
sa->crypto_alg = alg;
- sa->crypto_key_len = vec_len (key);
- clib_memcpy (sa->crypto_key, key, vec_len (key));
+ ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
}
else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG)
{
sa = pool_elt_at_index (im->sad, t->output_sa_index);
sa->integ_alg = alg;
- sa->integ_key_len = vec_len (key);
- clib_memcpy (sa->integ_key, key, vec_len (key));
+ ipsec_mk_key (&sa->integ_key, key, vec_len (key));
}
else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO)
{
sa = pool_elt_at_index (im->sad, t->input_sa_index);
sa->crypto_alg = alg;
- sa->crypto_key_len = vec_len (key);
- clib_memcpy (sa->crypto_key, key, vec_len (key));
+ ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
}
else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG)
{
sa = pool_elt_at_index (im->sad, t->input_sa_index);
sa->integ_alg = alg;
- sa->integ_key_len = vec_len (key);
- clib_memcpy (sa->integ_key, key, vec_len (key));
+ ipsec_mk_key (&sa->integ_key, key, vec_len (key));
}
else
return VNET_API_ERROR_INVALID_VALUE;