hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0);
t0 = pool_elt_at_index (im->tunnel_interfaces, hi0->dev_instance);
vnet_buffer (b0)->ipsec.sad_index = t0->output_sa_index;
- next0 = IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT;
+
+ /* 0, tx-node next[0] was added by vlib_node_add_next_with_slot */
+ next0 = 0;
len0 = vlib_buffer_length_in_chain (vm, b0);
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,
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) clib_host_to_net_u32 (args->remote_spi));
p = hash_get (im->ipsec_if_pool_index_by_key, key);
if (args->is_add)
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));
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->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->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);
t - im->tunnel_interfaces);
hi = vnet_get_hw_interface (vnm, hw_if_index);
+ /* add esp4 as the next-node-index of this tx-node */
slot = vlib_node_add_next_with_slot
- (vnm->vlib_main, hi->tx_node_index, im->esp4_encrypt_node_index,
- IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT);
+ (vnm->vlib_main, hi->tx_node_index, im->esp4_encrypt_node_index, 0);
- ASSERT (slot == IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT);
+ ASSERT (slot == 0);
t->hw_if_index = hw_if_index;
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)
sa = pool_elt_at_index (im->sad, p[0]);
if (sa->is_tunnel)
- key = (u64) sa->tunnel_dst_addr.ip4.as_u32 << 32 | (u64) sa->spi;
+ key = ((u64) sa->tunnel_dst_addr.ip4.as_u32 << 32 |
+ (u64) clib_host_to_net_u32 (sa->spi));
else
- key = (u64) args->remote_ip.as_u32 << 32 | (u64) sa->spi;
+ key = ((u64) args->remote_ip.as_u32 << 32 |
+ (u64) clib_host_to_net_u32 (sa->spi));
p = hash_get (im->ipsec_if_pool_index_by_key, key);
{
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;
old_sa = pool_elt_at_index (im->sad, old_sa_index);
/* unset old inbound hash entry. packets should stop arriving */
- key =
- (u64) old_sa->tunnel_src_addr.ip4.as_u32 << 32 | (u64) old_sa->spi;
+ key = ((u64) old_sa->tunnel_src_addr.ip4.as_u32 << 32 |
+ (u64) clib_host_to_net_u32 (old_sa->spi));
p = hash_get (im->ipsec_if_pool_index_by_key, key);
if (p)
hash_unset (im->ipsec_if_pool_index_by_key, key);
/* set new inbound SA, then set new hash entry */
t->input_sa_index = sa_index;
- key = (u64) sa->tunnel_src_addr.ip4.as_u32 << 32 | (u64) sa->spi;
+ key = ((u64) sa->tunnel_src_addr.ip4.as_u32 << 32 |
+ (u64) clib_host_to_net_u32 (sa->spi));
hash_set (im->ipsec_if_pool_index_by_key, key, hi->dev_instance);
}
else
if (ipsec_get_sa_index_by_sa_id (old_sa->id) == old_sa_index)
hash_unset (im->sa_index_by_sa_id, old_sa->id);
- if (!ipsec_add_del_sa_sess_cb (im, old_sa_index, 0))
+ if (ipsec_add_del_sa_sess_cb (im, old_sa_index, 0))
{
clib_warning ("IPsec backend add/del callback returned error");
return VNET_API_ERROR_SYSCALL_ERROR_1;