sa = ipsec_sa_get (it->output_sa_index);
+ /* *INDENT-OFF* */
fib_prefix_t pfx = {
.fp_addr = sa->tunnel_dst_addr,
- .fp_len = (sa->is_tunnel_ip6 ? 128 : 32),
- .fp_proto = (sa->is_tunnel_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
+ .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ? 128 : 32),
+ .fp_proto = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ?
+ FIB_PROTOCOL_IP6 :
+ FIB_PROTOCOL_IP4),
};
+ /* *INDENT-ON* */
adj_midchain_delegate_stack (ai, sa->tx_fib_index, &pfx);
}
return (0xc0000000 | ti);
}
+static void
+ipsec_tunnel_feature_set (ipsec_tunnel_if_t * t, u8 enable)
+{
+ vnet_feature_enable_disable ("ip4-output",
+ "esp4-encrypt-tun",
+ t->sw_if_index, enable,
+ &t->output_sa_index,
+ sizeof (t->output_sa_index));
+ vnet_feature_enable_disable ("ip6-output",
+ "esp6-encrypt-tun",
+ t->sw_if_index, enable,
+ &t->output_sa_index,
+ sizeof (t->output_sa_index));
+}
+
int
ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm,
ipsec_add_del_tunnel_args_t * args,
if (args->udp_encap)
flags |= IPSEC_SA_FLAG_UDP_ENCAP;
if (args->esn)
- flags |= IPSEC_SA_FLAG_USE_EXTENDED_SEQ_NUM;
+ flags |= IPSEC_SA_FLAG_USE_ESN;
if (args->anti_replay)
flags |= IPSEC_SA_FLAG_USE_ANTI_REPLAY;
&crypto_key,
args->integ_alg,
&integ_key,
- flags,
+ (flags | IPSEC_SA_FLAG_IS_INBOUND),
args->tx_table_id,
+ args->salt,
&args->remote_ip,
&args->local_ip, &t->input_sa_index);
&integ_key,
flags,
args->tx_table_id,
+ args->salt,
&args->local_ip,
&args->remote_ip, &t->output_sa_index);
t->hw_if_index = hw_if_index;
t->sw_if_index = hi->sw_if_index;
+ /* Standard default jumbo MTU. */
+ vnet_sw_interface_set_mtu (vnm, t->sw_if_index, 9000);
+
/* Add the new tunnel to the DB of tunnels per sw_if_index ... */
vec_validate_init_empty (im->ipsec_if_by_sw_if_index, t->sw_if_index,
~0);
im->ipsec_if_by_sw_if_index[t->sw_if_index] = dev_instance;
- vnet_feature_enable_disable ("ip4-output",
- "esp4-encrypt-tun",
- t->sw_if_index, 1,
- &t->output_sa_index,
- sizeof (t->output_sa_index));
- vnet_feature_enable_disable ("ip6-output",
- "esp6-encrypt-tun",
- t->sw_if_index, 1,
- &t->output_sa_index,
- sizeof (t->output_sa_index));
+ ipsec_tunnel_feature_set (t, 1);
/*1st interface, register protocol */
if (pool_elts (im->tunnel_interfaces) == 1)
hi = vnet_get_hw_interface (vnm, t->hw_if_index);
vnet_sw_interface_set_flags (vnm, hi->sw_if_index, 0); /* admin down */
- vnet_feature_enable_disable ("ip4-output",
- "esp4-encrypt-tun",
- hi->sw_if_index, 0,
- &t->output_sa_index,
- sizeof (t->output_sa_index));
- vnet_feature_enable_disable ("ip6-output",
- "esp6-encrypt-tun",
- hi->sw_if_index, 0,
- &t->output_sa_index,
- sizeof (t->output_sa_index));
+ ipsec_tunnel_feature_set (t, 0);
vnet_delete_hw_interface (vnm, t->hw_if_index);
if (is_ip6)
int
ipsec_add_del_ipsec_gre_tunnel (vnet_main_t * vnm,
- ipsec_add_del_ipsec_gre_tunnel_args_t * args)
+ const ipsec_gre_tunnel_add_del_args_t * args)
{
ipsec_tunnel_if_t *t = 0;
ipsec_main_t *im = &ipsec_main;
p = hash_get (im->sa_index_by_sa_id, args->local_sa_id);
if (!p)
return VNET_API_ERROR_INVALID_VALUE;
- isa = p[0];
+ osa = p[0];
+ sa = pool_elt_at_index (im->sad, p[0]);
+ ipsec_sa_set_IS_GRE (sa);
p = hash_get (im->sa_index_by_sa_id, args->remote_sa_id);
if (!p)
return VNET_API_ERROR_INVALID_VALUE;
- osa = p[0];
+ isa = p[0];
sa = pool_elt_at_index (im->sad, p[0]);
+ ipsec_sa_set_IS_GRE (sa);
+ /* we form the key from the input/remote SA whose tunnel is srouce
+ * at the remote end */
if (ipsec_sa_is_set_IS_TUNNEL (sa))
{
- key.remote_ip = sa->tunnel_dst_addr.ip4.as_u32;
+ key.remote_ip = sa->tunnel_src_addr.ip4.as_u32;
key.spi = clib_host_to_net_u32 (sa->spi);
}
else
{
- key.remote_ip = args->remote_ip.as_u32;
+ key.remote_ip = args->src.as_u32;
key.spi = clib_host_to_net_u32 (sa->spi);
}
ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index,
ipsec_if_set_key_type_t type, u8 alg, u8 * key)
{
+ vlib_main_t *vm = vlib_get_main ();
ipsec_main_t *im = &ipsec_main;
vnet_hw_interface_t *hi;
ipsec_tunnel_if_t *t;
sa = pool_elt_at_index (im->sad, t->output_sa_index);
ipsec_sa_set_crypto_alg (sa, alg);
ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
+ sa->crypto_calg = im->crypto_algs[alg].alg;
+ vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg,
+ 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);
ipsec_sa_set_integ_alg (sa, alg);
ipsec_mk_key (&sa->integ_key, key, vec_len (key));
+ sa->integ_calg = im->integ_algs[alg].alg;
+ vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg,
+ 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);
ipsec_sa_set_crypto_alg (sa, alg);
ipsec_mk_key (&sa->crypto_key, key, vec_len (key));
+ sa->crypto_calg = im->crypto_algs[alg].alg;
+ vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg,
+ 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);
ipsec_sa_set_integ_alg (sa, alg);
ipsec_mk_key (&sa->integ_key, key, vec_len (key));
+ sa->integ_calg = im->integ_algs[alg].alg;
+ vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg,
+ key, vec_len (key));
}
else
return VNET_API_ERROR_INVALID_VALUE;
return VNET_API_ERROR_INVALID_VALUE;
}
+ /*
+ * re-enable the feature to get the new SA in
+ * the workers are stopped so no packets are sent in the clear
+ */
+ ipsec_tunnel_feature_set (t, 0);
t->output_sa_index = sa_index;
+ ipsec_tunnel_feature_set (t, 1);
}
/* remove sa_id to sa_index mapping on old SA */
clib_warning ("IPsec backend add/del callback returned error");
return VNET_API_ERROR_SYSCALL_ERROR_1;
}
- pool_put (im->sad, old_sa);
+ ipsec_sa_del (old_sa->id);
return 0;
}