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:
Matthew Smith
2017-10-05 19:03:05 -05:00
committed by Damjan Marion
parent 054c03ac9c
commit 75d856096f
3 changed files with 152 additions and 0 deletions
+77
View File
@@ -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>)") \
+19
View File
@@ -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
View File
@@ -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)
{