Add API call to set keys on IPsec tunnel intf
There was already a CLI command and a libvnet function to set the keys on an existing IPsec tunnel interface. Expose this via the API. Change-Id: I226a9616f680fc022f04447177a2e8232690657f Signed-off-by: Matthew Smith <mgsmith@netgate.com>
This commit is contained in:
committed by
Damjan Marion
parent
054c03ac9c
commit
75d856096f
@@ -5077,6 +5077,7 @@ _(ipsec_spd_add_del_entry_reply) \
|
||||
_(ipsec_sad_add_del_entry_reply) \
|
||||
_(ipsec_sa_set_key_reply) \
|
||||
_(ipsec_tunnel_if_add_del_reply) \
|
||||
_(ipsec_tunnel_if_set_key_reply) \
|
||||
_(ikev2_profile_add_del_reply) \
|
||||
_(ikev2_profile_set_auth_reply) \
|
||||
_(ikev2_profile_set_id_reply) \
|
||||
@@ -5310,6 +5311,7 @@ _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
|
||||
_(IPSEC_SA_DETAILS, ipsec_sa_details) \
|
||||
_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
|
||||
_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply) \
|
||||
_(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply) \
|
||||
_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
|
||||
_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
|
||||
_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
|
||||
@@ -14284,6 +14286,79 @@ api_ipsec_sa_dump (vat_main_t * vam)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
api_ipsec_tunnel_if_set_key (vat_main_t * vam)
|
||||
{
|
||||
unformat_input_t *i = vam->input;
|
||||
vl_api_ipsec_tunnel_if_set_key_t *mp;
|
||||
u32 sw_if_index = ~0;
|
||||
u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
|
||||
u8 *key = 0;
|
||||
u32 alg = ~0;
|
||||
int ret;
|
||||
|
||||
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
|
||||
;
|
||||
else
|
||||
if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
|
||||
key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
|
||||
else
|
||||
if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
|
||||
key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
|
||||
else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
|
||||
key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
|
||||
else
|
||||
if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
|
||||
key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
|
||||
else if (unformat (i, "%U", unformat_hex_string, &key))
|
||||
;
|
||||
else
|
||||
{
|
||||
clib_warning ("parse error '%U'", format_unformat_error, i);
|
||||
return -99;
|
||||
}
|
||||
}
|
||||
|
||||
if (sw_if_index == ~0)
|
||||
{
|
||||
errmsg ("interface must be specified");
|
||||
return -99;
|
||||
}
|
||||
|
||||
if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
|
||||
{
|
||||
errmsg ("key type must be specified");
|
||||
return -99;
|
||||
}
|
||||
|
||||
if (alg == ~0)
|
||||
{
|
||||
errmsg ("algorithm must be specified");
|
||||
return -99;
|
||||
}
|
||||
|
||||
if (vec_len (key) == 0)
|
||||
{
|
||||
errmsg ("key must be specified");
|
||||
return -99;
|
||||
}
|
||||
|
||||
M (IPSEC_TUNNEL_IF_SET_KEY, mp);
|
||||
|
||||
mp->sw_if_index = htonl (sw_if_index);
|
||||
mp->alg = alg;
|
||||
mp->key_type = key_type;
|
||||
mp->key_len = vec_len (key);
|
||||
clib_memcpy (mp->key, key, vec_len (key));
|
||||
|
||||
S (mp);
|
||||
W (ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
api_ikev2_profile_add_del (vat_main_t * vam)
|
||||
{
|
||||
@@ -21547,6 +21622,8 @@ _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n" \
|
||||
" integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n" \
|
||||
" local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n") \
|
||||
_(ipsec_sa_dump, "[sa_id <n>]") \
|
||||
_(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n" \
|
||||
" <alg> <hex>\n") \
|
||||
_(ikev2_profile_add_del, "name <profile_name> [del]") \
|
||||
_(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n" \
|
||||
"(auth_data 0x<data> | auth_data <data>)") \
|
||||
|
||||
@@ -615,6 +615,25 @@ define ipsec_sa_details {
|
||||
u64 total_data_size;
|
||||
};
|
||||
|
||||
/** \brief Set key on IPsec interface
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - index of tunnel interface
|
||||
@param key_type - type of key being set
|
||||
@param alg - algorithm used with key
|
||||
@param key_len - length key in bytes
|
||||
@param key - key
|
||||
*/
|
||||
autoreply define ipsec_tunnel_if_set_key {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 sw_if_index;
|
||||
u8 key_type;
|
||||
u8 alg;
|
||||
u8 key_len;
|
||||
u8 key[128];
|
||||
};
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
|
||||
@@ -56,6 +56,7 @@ _(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \
|
||||
_(IPSEC_SA_DUMP, ipsec_sa_dump) \
|
||||
_(IPSEC_SPD_DUMP, ipsec_spd_dump) \
|
||||
_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
|
||||
_(IPSEC_TUNNEL_IF_SET_KEY, ipsec_tunnel_if_set_key) \
|
||||
_(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \
|
||||
_(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \
|
||||
_(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \
|
||||
@@ -509,6 +510,61 @@ vl_api_ipsec_sa_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vl_api_ipsec_tunnel_if_set_key_t_handler (vl_api_ipsec_tunnel_if_set_key_t *
|
||||
mp)
|
||||
{
|
||||
vl_api_ipsec_tunnel_if_set_key_reply_t *rmp;
|
||||
ipsec_main_t *im = &ipsec_main;
|
||||
vnet_main_t *vnm = im->vnet_main;
|
||||
vnet_sw_interface_t *sw;
|
||||
u8 *key = 0;
|
||||
int rv;
|
||||
|
||||
#if WITH_LIBSSL > 0
|
||||
sw = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
|
||||
|
||||
switch (mp->key_type)
|
||||
{
|
||||
case IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO:
|
||||
case IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO:
|
||||
if (mp->alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
|
||||
mp->alg > IPSEC_CRYPTO_N_ALG)
|
||||
{
|
||||
rv = VNET_API_ERROR_UNIMPLEMENTED;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG:
|
||||
case IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG:
|
||||
if (mp->alg > IPSEC_INTEG_N_ALG)
|
||||
{
|
||||
rv = VNET_API_ERROR_UNIMPLEMENTED;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case IPSEC_IF_SET_KEY_TYPE_NONE:
|
||||
default:
|
||||
rv = VNET_API_ERROR_UNIMPLEMENTED;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
key = vec_new (u8, mp->key_len);
|
||||
clib_memcpy (key, mp->key, mp->key_len);
|
||||
|
||||
rv = ipsec_set_interface_key (vnm, sw->hw_if_index, mp->key_type, mp->alg,
|
||||
key);
|
||||
vec_free (key);
|
||||
#else
|
||||
clib_warning ("unimplemented");
|
||||
#endif
|
||||
|
||||
out:
|
||||
REPLY_MACRO (VL_API_IPSEC_TUNNEL_IF_SET_KEY_REPLY);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user