ikev2: Configure a profile with an existing interface
Type: feature ... rather than always creating a new interface. Change-Id: If8a22ad5a8a3a4e511bea7cab7d8bbf7e6af9433 Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
committed by
Damjan Marion
parent
bdfa4d3781
commit
44476c6b27
@@ -146,6 +146,22 @@ autoreply define ikev2_set_local_key
|
||||
option vat_help = "file <absolute_file_path>";
|
||||
};
|
||||
|
||||
/** \brief IKEv2: Set the tunnel interface which will be protected by IKE
|
||||
If this API is not called, a new tunnel will be created
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param name - IKEv2 profile name
|
||||
@param sw_if_index - Of an existing tunnel
|
||||
*/
|
||||
autoreply define ikev2_set_tunnel_interface
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
string name[64];
|
||||
|
||||
vl_api_interface_index_t sw_if_index;
|
||||
};
|
||||
|
||||
/** \brief IKEv2: Set IKEv2 responder interface and IP address
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
|
||||
+77
-30
@@ -389,6 +389,8 @@ ikev2_complete_sa_data (ikev2_sa_t * sa, ikev2_sa_t * sai)
|
||||
sa->i_id.type = sai->i_id.type;
|
||||
sa->profile_index = sai->profile_index;
|
||||
sa->is_profile_index_set = sai->is_profile_index_set;
|
||||
sa->tun_itf = sai->tun_itf;
|
||||
sa->is_tun_itf_set = sai->is_tun_itf_set;
|
||||
sa->i_id.data = _(sai->i_id.data);
|
||||
sa->i_auth.method = sai->i_auth.method;
|
||||
sa->i_auth.hex = sai->i_auth.hex;
|
||||
@@ -1478,6 +1480,7 @@ ikev2_mk_remote_sa_id (u32 sai, u32 ci, u32 ti)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
u32 salt_local;
|
||||
u32 salt_remote;
|
||||
u32 local_sa_id;
|
||||
@@ -1497,21 +1500,26 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
|
||||
{
|
||||
ikev2_main_t *km = &ikev2_main;
|
||||
u32 sw_if_index;
|
||||
int rv;
|
||||
uword *p = 0;
|
||||
int rv = 0;
|
||||
|
||||
rv = ipip_add_tunnel (IPIP_TRANSPORT_IP4, ~0,
|
||||
&a->local_ip, &a->remote_ip, 0,
|
||||
TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0,
|
||||
TUNNEL_MODE_P2P, &sw_if_index);
|
||||
|
||||
if (rv == VNET_API_ERROR_IF_ALREADY_EXISTS)
|
||||
if (~0 == a->sw_if_index)
|
||||
{
|
||||
p = hash_get (km->sw_if_indices, sw_if_index);
|
||||
if (p)
|
||||
/* interface is managed by IKE; proceed with updating SAs */
|
||||
rv = 0;
|
||||
/* no tunnel associated with the SA/profile - create a new one */
|
||||
rv = ipip_add_tunnel (IPIP_TRANSPORT_IP4, ~0,
|
||||
&a->local_ip, &a->remote_ip, 0,
|
||||
TUNNEL_ENCAP_DECAP_FLAG_NONE, IP_DSCP_CS0,
|
||||
TUNNEL_MODE_P2P, &sw_if_index);
|
||||
|
||||
if (rv == VNET_API_ERROR_IF_ALREADY_EXISTS)
|
||||
{
|
||||
if (hash_get (km->sw_if_indices, sw_if_index))
|
||||
/* interface is managed by IKE; proceed with updating SAs */
|
||||
rv = 0;
|
||||
}
|
||||
hash_set1 (km->sw_if_indices, sw_if_index);
|
||||
}
|
||||
else
|
||||
sw_if_index = a->sw_if_index;
|
||||
|
||||
if (rv)
|
||||
{
|
||||
@@ -1537,7 +1545,6 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
|
||||
u32 *sas_in = NULL;
|
||||
vec_add1 (sas_in, a->remote_sa_id);
|
||||
rv |= ipsec_tun_protect_update (sw_if_index, a->local_sa_id, sas_in);
|
||||
hash_set1 (km->sw_if_indices, sw_if_index);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1739,6 +1746,7 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm,
|
||||
child->remote_sa_id =
|
||||
a.remote_sa_id =
|
||||
ikev2_mk_remote_sa_id (sa_index, child_index, thread_index);
|
||||
a.sw_if_index = (sa->is_tun_itf_set ? sa->tun_itf : ~0);
|
||||
|
||||
vl_api_rpc_call_main_thread (ikev2_add_tunnel_from_main,
|
||||
(u8 *) & a, sizeof (a));
|
||||
@@ -1751,32 +1759,48 @@ typedef struct
|
||||
ip46_address_t remote_ip;
|
||||
u32 remote_sa_id;
|
||||
u32 local_sa_id;
|
||||
u32 sw_if_index;
|
||||
} ikev2_del_ipsec_tunnel_args_t;
|
||||
|
||||
static void
|
||||
ikev2_del_tunnel_from_main (ikev2_del_ipsec_tunnel_args_t * a)
|
||||
{
|
||||
ikev2_main_t *km = &ikev2_main;
|
||||
/* *INDENT-OFF* */
|
||||
ipip_tunnel_key_t key = {
|
||||
.src = a->local_ip,
|
||||
.dst = a->remote_ip,
|
||||
.transport = IPIP_TRANSPORT_IP4,
|
||||
.fib_index = 0,
|
||||
};
|
||||
ipip_tunnel_t *ipip;
|
||||
/* *INDENT-ON* */
|
||||
ipip_tunnel_t *ipip = NULL;
|
||||
u32 sw_if_index;
|
||||
|
||||
ipip = ipip_tunnel_db_find (&key);
|
||||
if (~0 == a->sw_if_index)
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
ipip_tunnel_key_t key = {
|
||||
.src = a->local_ip,
|
||||
.dst = a->remote_ip,
|
||||
.transport = IPIP_TRANSPORT_IP4,
|
||||
.fib_index = 0,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
ipip = ipip_tunnel_db_find (&key);
|
||||
|
||||
if (ipip)
|
||||
{
|
||||
sw_if_index = ipip->sw_if_index;
|
||||
hash_unset (km->sw_if_indices, ipip->sw_if_index);
|
||||
}
|
||||
else
|
||||
sw_if_index = ~0;
|
||||
}
|
||||
else
|
||||
sw_if_index = a->sw_if_index;
|
||||
|
||||
if (~0 != sw_if_index)
|
||||
ipsec_tun_protect_del (sw_if_index);
|
||||
|
||||
ipsec_sa_unlock_id (a->remote_sa_id);
|
||||
ipsec_sa_unlock_id (a->local_sa_id);
|
||||
|
||||
if (ipip)
|
||||
{
|
||||
hash_unset (km->sw_if_indices, ipip->sw_if_index);
|
||||
ipsec_tun_protect_del (ipip->sw_if_index);
|
||||
ipsec_sa_unlock_id (a->remote_sa_id);
|
||||
ipsec_sa_unlock_id (a->local_sa_id);
|
||||
ipip_del_tunnel (ipip->sw_if_index);
|
||||
}
|
||||
ipip_del_tunnel (ipip->sw_if_index);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1800,6 +1824,7 @@ ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa,
|
||||
|
||||
a.remote_sa_id = child->remote_sa_id;
|
||||
a.local_sa_id = child->local_sa_id;
|
||||
a.sw_if_index = (sa->is_tun_itf_set ? sa->tun_itf : ~0);
|
||||
|
||||
vl_api_rpc_call_main_thread (ikev2_del_tunnel_from_main, (u8 *) & a,
|
||||
sizeof (a));
|
||||
@@ -3044,6 +3069,26 @@ ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
clib_error_t *
|
||||
ikev2_set_profile_tunnel_interface (vlib_main_t * vm,
|
||||
u8 * name, u32 sw_if_index)
|
||||
{
|
||||
ikev2_profile_t *p;
|
||||
clib_error_t *r;
|
||||
|
||||
p = ikev2_profile_index_by_name (name);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
r = clib_error_return (0, "unknown profile %v", name);
|
||||
return r;
|
||||
}
|
||||
|
||||
p->tun_itf = sw_if_index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
clib_error_t *
|
||||
ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name,
|
||||
u64 lifetime, u32 jitter, u32 handover,
|
||||
@@ -3127,6 +3172,8 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
|
||||
sa.profile_index = km->profiles - p;
|
||||
sa.is_profile_index_set = 1;
|
||||
sa.state = IKEV2_STATE_SA_INIT;
|
||||
sa.tun_itf = p->tun_itf;
|
||||
sa.is_tun_itf_set = 1;
|
||||
ikev2_generate_sa_init_data (&sa);
|
||||
ikev2_payload_add_ke (chain, sa.dh_group, sa.i_dh_data);
|
||||
ikev2_payload_add_nonce (chain, sa.i_nonce);
|
||||
|
||||
@@ -392,6 +392,8 @@ clib_error_t *ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name,
|
||||
clib_error_t *ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name,
|
||||
u64 lifetime, u32 jitter,
|
||||
u32 handover, u64 maxdata);
|
||||
clib_error_t *ikev2_set_profile_tunnel_interface (vlib_main_t * vm, u8 * name,
|
||||
u32 sw_if_index);
|
||||
clib_error_t *ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name);
|
||||
clib_error_t *ikev2_initiate_delete_child_sa (vlib_main_t * vm, u32 ispi);
|
||||
clib_error_t *ikev2_initiate_delete_ike_sa (vlib_main_t * vm, u64 ispi);
|
||||
|
||||
@@ -289,6 +289,33 @@ vl_api_ikev2_set_sa_lifetime_t_handler (vl_api_ikev2_set_sa_lifetime_t * mp)
|
||||
REPLY_MACRO (VL_API_IKEV2_SET_SA_LIFETIME_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_ikev2_set_tunnel_interface_t_handler
|
||||
(vl_api_ikev2_set_tunnel_interface_t * mp)
|
||||
{
|
||||
vl_api_ikev2_set_tunnel_interface_reply_t *rmp;
|
||||
int rv = 0;
|
||||
|
||||
VALIDATE_SW_IF_INDEX (mp);
|
||||
|
||||
#if WITH_LIBSSL > 0
|
||||
u8 *tmp = format (0, "%s", mp->name);
|
||||
clib_error_t *error;
|
||||
|
||||
error = ikev2_set_profile_tunnel_interface (vlib_get_main (), tmp,
|
||||
ntohl (mp->sw_if_index));
|
||||
|
||||
if (error)
|
||||
rv = VNET_API_ERROR_UNSPECIFIED;
|
||||
vec_free (tmp);
|
||||
#else
|
||||
rv = VNET_API_ERROR_UNIMPLEMENTED;
|
||||
#endif
|
||||
|
||||
BAD_SW_IF_INDEX_LABEL;
|
||||
REPLY_MACRO (VL_API_IKEV2_SET_TUNNEL_INTERFACE_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_ikev2_initiate_sa_init_t_handler (vl_api_ikev2_initiate_sa_init_t * mp)
|
||||
{
|
||||
|
||||
@@ -184,6 +184,7 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
|
||||
ip4_address_t ip4;
|
||||
ip4_address_t end_addr;
|
||||
u32 responder_sw_if_index = (u32) ~ 0;
|
||||
u32 tun_sw_if_index = (u32) ~ 0;
|
||||
ip4_address_t responder_ip4;
|
||||
ikev2_transform_encr_type_t crypto_alg;
|
||||
ikev2_transform_integ_type_t integ_alg;
|
||||
@@ -326,6 +327,13 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
|
||||
responder_ip4);
|
||||
goto done;
|
||||
}
|
||||
else if (unformat (line_input, "set %U tunnel %U",
|
||||
unformat_token, valid_chars, &name,
|
||||
unformat_vnet_sw_interface, vnm, &tun_sw_if_index))
|
||||
{
|
||||
r = ikev2_set_profile_tunnel_interface (vm, name, tun_sw_if_index);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
if (unformat
|
||||
(line_input,
|
||||
@@ -384,6 +392,7 @@ VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = {
|
||||
"ikev2 profile set <id> auth [rsa-sig|shared-key-mic] [cert-file|string|hex]"
|
||||
" <data>\n"
|
||||
"ikev2 profile set <id> id <local|remote> <type> <data>\n"
|
||||
"ikev2 profile set <id> tunnel <interface>\n"
|
||||
"ikev2 profile set <id> traffic-selector <local|remote> ip-range "
|
||||
"<start-addr> - <end-addr> port-range <start-port> - <end-port> "
|
||||
"protocol <protocol-number>\n"
|
||||
|
||||
@@ -358,6 +358,8 @@ typedef struct
|
||||
u64 lifetime_maxdata;
|
||||
u32 lifetime_jitter;
|
||||
u32 handover;
|
||||
|
||||
u32 tun_itf;
|
||||
} ikev2_profile_t;
|
||||
|
||||
typedef struct
|
||||
@@ -418,6 +420,8 @@ typedef struct
|
||||
u32 last_init_msg_id;
|
||||
u8 is_profile_index_set;
|
||||
u32 profile_index;
|
||||
u8 is_tun_itf_set;
|
||||
u32 tun_itf;
|
||||
|
||||
ikev2_child_sa_t *childs;
|
||||
} ikev2_sa_t;
|
||||
|
||||
@@ -406,6 +406,12 @@ api_ikev2_set_local_key (vat_main_t * vam)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
api_ikev2_set_tunnel_interface (vat_main_t * vam)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
api_ikev2_set_responder (vat_main_t * vam)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user