diff options
-rw-r--r-- | vnet/Makefile.am | 13 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec.api | 457 | ||||
-rw-r--r-- | vnet/vnet/ipsec/ipsec_api.c | 537 | ||||
-rw-r--r-- | vnet/vnet/vnet_all_api_h.h | 1 | ||||
-rw-r--r-- | vpp-api/java/Makefile.am | 4 | ||||
-rw-r--r-- | vpp/vpp-api/api.c | 449 | ||||
-rw-r--r-- | vpp/vpp-api/vpe.api | 437 |
7 files changed, 1008 insertions, 890 deletions
diff --git a/vnet/Makefile.am b/vnet/Makefile.am index 592acc8f645..15b01e36a46 100644 --- a/vnet/Makefile.am +++ b/vnet/Makefile.am @@ -43,7 +43,9 @@ BUILT_SOURCES = \ vnet/vxlan-gpe/vxlan_gpe.api.h \ vnet/vxlan-gpe/vxlan_gpe.api.json \ vnet/bfd/bfd.api.h \ - vnet/bfd/bfd.api.json + vnet/bfd/bfd.api.json \ + vnet/ipsec/ipsec.api.h \ + vnet/ipsec/ipsec.api.json libvnet_la_SOURCES = libvnetplugin_la_SOURCES = @@ -403,7 +405,8 @@ libvnet_la_SOURCES += \ vnet/ipsec/ikev2_crypto.c \ vnet/ipsec/ikev2_cli.c \ vnet/ipsec/ikev2_payload.c \ - vnet/ipsec/ikev2_format.c + vnet/ipsec/ikev2_format.c \ + vnet/ipsec/ipsec_api.c if WITH_DPDK_CRYPTO libvnet_la_SOURCES += \ vnet/devices/dpdk/ipsec/esp_encrypt.c \ @@ -421,7 +424,8 @@ nobase_include_HEADERS += \ vnet/ipsec/ipsec.h \ vnet/ipsec/esp.h \ vnet/ipsec/ikev2.h \ - vnet/ipsec/ikev2_priv.h + vnet/ipsec/ikev2_priv.h \ + vnet/ipsec/ipsec.api.h if WITH_DPDK_CRYPTO nobase_include_HEADERS += \ vnet/devices/dpdk/ipsec/ipsec.h \ @@ -978,7 +982,8 @@ api_DATA = \ vnet/unix/tap.api.json \ vnet/vxlan/vxlan.api.json \ vnet/vxlan-gpe/vxlan_gpe.api.json \ - vnet/bfd/bfd.api.json + vnet/bfd/bfd.api.json \ + vnet/ipsec/ipsec.api.json # The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk # and requires a symbolic link at the top of the vnet source tree diff --git a/vnet/vnet/ipsec/ipsec.api b/vnet/vnet/ipsec/ipsec.api new file mode 100644 index 00000000000..178bb757168 --- /dev/null +++ b/vnet/vnet/ipsec/ipsec.api @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2015-2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \brief IPsec: Add/delete Security Policy Database + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add SPD if non-zero, else delete + @param spd_id - SPD instance id (control plane allocated) +*/ + +define ipsec_spd_add_del +{ + u32 client_index; + u32 context; + u8 is_add; + u32 spd_id; +}; + +/** \brief Reply for IPsec: Add/delete Security Policy Database entry + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ + +define ipsec_spd_add_del_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IPsec: Add/delete SPD from interface + + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add security mode if non-zero, else delete + @param sw_if_index - index of the interface + @param spd_id - SPD instance id to use for lookups +*/ + + +define ipsec_interface_add_del_spd +{ + u32 client_index; + u32 context; + + u8 is_add; + u32 sw_if_index; + u32 spd_id; +}; + +/** \brief Reply for IPsec: Add/delete SPD from interface + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ + +define ipsec_interface_add_del_spd_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IPsec: Add/delete Security Policy Database entry + + See RFC 4301, 4.4.1.1 on how to match packet to selectors + + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add SPD if non-zero, else delete + @param spd_id - SPD instance id (control plane allocated) + @param priority - priority of SPD entry (non-unique value). Used to order SPD matching - higher priorities match before lower + @param is_outbound - entry applies to outbound traffic if non-zero, otherwise applies to inbound traffic + @param is_ipv6 - remote/local address are IPv6 if non-zero, else IPv4 + @param remote_address_start - start of remote address range to match + @param remote_address_stop - end of remote address range to match + @param local_address_start - start of local address range to match + @param local_address_stop - end of local address range to match + @param protocol - protocol type to match [0 means any] + @param remote_port_start - start of remote port range to match ... + @param remote_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] + @param local_port_start - start of local port range to match ... + @param local_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] + @param policy - 0 = bypass (no IPsec processing), 1 = discard (discard packet with ICMP processing), 2 = resolve (send request to control plane for SA resolving, and discard without ICMP processing), 3 = protect (apply IPsec policy using following parameters) + @param sa_id - SAD instance id (control plane allocated) + +*/ + +define ipsec_spd_add_del_entry +{ + u32 client_index; + u32 context; + u8 is_add; + + u32 spd_id; + i32 priority; + u8 is_outbound; + + // Selector + u8 is_ipv6; + u8 is_ip_any; + u8 remote_address_start[16]; + u8 remote_address_stop[16]; + u8 local_address_start[16]; + u8 local_address_stop[16]; + + u8 protocol; + + u16 remote_port_start; + u16 remote_port_stop; + u16 local_port_start; + u16 local_port_stop; + + // Policy + u8 policy; + u32 sa_id; +}; + +/** \brief Reply for IPsec: Add/delete Security Policy Database entry + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ + +define ipsec_spd_add_del_entry_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IPsec: Add/delete Security Association Database entry + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add SAD entry if non-zero, else delete + + @param sad_id - sad id + + @param spi - security parameter index + + @param protocol - 0 = AH, 1 = ESP + + @param crypto_algorithm - 0 = Null, 1 = AES-CBC-128, 2 = AES-CBC-192, 3 = AES-CBC-256, 4 = 3DES-CBC + @param crypto_key_length - length of crypto_key in bytes + @param crypto_key - crypto keying material + + @param integrity_algorithm - 0 = None, 1 = MD5-96, 2 = SHA1-96, 3 = SHA-256, 4 = SHA-384, 5=SHA-512 + @param integrity_key_length - length of integrity_key in bytes + @param integrity_key - integrity keying material + + @param use_extended_sequence_number - use ESN when non-zero + + @param is_tunnel - IPsec tunnel mode if non-zero, else transport mode + @param is_tunnel_ipv6 - IPsec tunnel mode is IPv6 if non-zero, else IPv4 tunnel only valid if is_tunnel is non-zero + @param tunnel_src_address - IPsec tunnel source address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero + @param tunnel_dst_address - IPsec tunnel destination address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero + + To be added: + Anti-replay + IPsec tunnel address copy mode (to support GDOI) + */ + +define ipsec_sad_add_del_entry +{ + u32 client_index; + u32 context; + u8 is_add; + + u32 sad_id; + + u32 spi; + + u8 protocol; + + u8 crypto_algorithm; + u8 crypto_key_length; + u8 crypto_key[128]; + + u8 integrity_algorithm; + u8 integrity_key_length; + u8 integrity_key[128]; + + u8 use_extended_sequence_number; + + u8 is_tunnel; + u8 is_tunnel_ipv6; + u8 tunnel_src_address[16]; + u8 tunnel_dst_address[16]; +}; + +/** \brief Reply for IPsec: Add/delete Security Association Database entry + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ + +define ipsec_sad_add_del_entry_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IPsec: Update Security Association keys + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + + @param sa_id - sa id + + @param crypto_key_length - length of crypto_key in bytes + @param crypto_key - crypto keying material + + @param integrity_key_length - length of integrity_key in bytes + @param integrity_key - integrity keying material +*/ + +define ipsec_sa_set_key +{ + u32 client_index; + u32 context; + + u32 sa_id; + + u8 crypto_key_length; + u8 crypto_key[128]; + + u8 integrity_key_length; + u8 integrity_key[128]; +}; + +/** \brief Reply for IPsec: Update Security Association keys + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ + +define ipsec_sa_set_key_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IKEv2: Add/delete profile + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + + @param name - IKEv2 profile name + @param is_add - Add IKEv2 profile if non-zero, else delete +*/ +define ikev2_profile_add_del +{ + u32 client_index; + u32 context; + + u8 name[64]; + u8 is_add; +}; + +/** \brief Reply for IKEv2: Add/delete profile + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define ikev2_profile_add_del_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IKEv2: Set IKEv2 profile authentication method + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + + @param name - IKEv2 profile name + @param auth_method - IKEv2 authentication method (shared-key-mic/rsa-sig) + @param is_hex - Authentication data in hex format if non-zero, else string + @param data_len - Authentication data length + @param data - Authentication data (for rsa-sig cert file path) +*/ +define ikev2_profile_set_auth +{ + u32 client_index; + u32 context; + + u8 name[64]; + u8 auth_method; + u8 is_hex; + u32 data_len; + u8 data[0]; +}; + +/** \brief Reply for IKEv2: Set IKEv2 profile authentication method + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define ikev2_profile_set_auth_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IKEv2: Set IKEv2 profile local/remote identification + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + + @param name - IKEv2 profile name + @param is_local - Identification is local if non-zero, else remote + @param id_type - Identification type + @param data_len - Identification data length + @param data - Identification data +*/ +define ikev2_profile_set_id +{ + u32 client_index; + u32 context; + + u8 name[64]; + u8 is_local; + u8 id_type; + u32 data_len; + u8 data[0]; +}; + +/** \brief Reply for IKEv2: + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define ikev2_profile_set_id_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IKEv2: Set IKEv2 profile traffic selector parameters + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + + @param name - IKEv2 profile name + @param is_local - Traffic selector is local if non-zero, else remote + @param proto - Traffic selector IP protocol (if zero not relevant) + @param start_port - The smallest port number allowed by traffic selector + @param end_port - The largest port number allowed by traffic selector + @param start_addr - The smallest address included in traffic selector + @param end_addr - The largest address included in traffic selector +*/ +define ikev2_profile_set_ts +{ + u32 client_index; + u32 context; + + u8 name[64]; + u8 is_local; + u8 proto; + u16 start_port; + u16 end_port; + u32 start_addr; + u32 end_addr; +}; + +/** \brief Reply for IKEv2: Set IKEv2 profile traffic selector parameters + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define ikev2_profile_set_ts_reply +{ + u32 context; + i32 retval; +}; + +/** \brief IKEv2: Set IKEv2 local RSA private key + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + + @param key_file - Key file absolute path +*/ +define ikev2_set_local_key +{ + u32 client_index; + u32 context; + + u8 key_file[256]; +}; + +/** \brief Reply for IKEv2: Set IKEv2 local key + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define ikev2_set_local_key_reply +{ + u32 context; + i32 retval; +}; + +/** \brief Dump ipsec policy database data + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param spd_id - SPD instance id + @param sa_id - SA id, optional, set to ~0 to see all policies in SPD +*/ +define ipsec_spd_dump { + u32 client_index; + u32 context; + u32 spd_id; + u32 sa_id; +}; + +/** \brief IPsec policy database response + @param context - sender context which was passed in the request + @param spd_id - SPD instance id + @param priority - numeric value to control policy evaluation order + @param is_outbound - [1|0] to indicate if direction is [out|in]bound + @param is_ipv6 - [1|0] to indicate if address family is ipv[6|4] + @param local_start_addr - first address in local traffic selector range + @param local_stop_addr - last address in local traffic selector range + @param local_start_port - first port in local traffic selector range + @param local_stop_port - last port in local traffic selector range + @param remote_start_addr - first address in remote traffic selector range + @param remote_stop_addr - last address in remote traffic selector range + @param remote_start_port - first port in remote traffic selector range + @param remote_stop_port - last port in remote traffic selector range + @param protocol - traffic selector protocol + @param policy - policy action + @param sa_id - SA id + @param bytes - byte count of packets matching this policy + @param packets - count of packets matching this policy +*/ + +define ipsec_spd_details { + u32 context; + u32 spd_id; + i32 priority; + u8 is_outbound; + u8 is_ipv6; + u8 local_start_addr[16]; + u8 local_stop_addr[16]; + u16 local_start_port; + u16 local_stop_port; + u8 remote_start_addr[16]; + u8 remote_stop_addr[16]; + u16 remote_start_port; + u16 remote_stop_port; + u8 protocol; + u8 policy; + u32 sa_id; + u64 bytes; + u64 packets; +}; + +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ +
\ No newline at end of file diff --git a/vnet/vnet/ipsec/ipsec_api.c b/vnet/vnet/ipsec/ipsec_api.c new file mode 100644 index 00000000000..30cc5bd2421 --- /dev/null +++ b/vnet/vnet/ipsec/ipsec_api.c @@ -0,0 +1,537 @@ +/* + *------------------------------------------------------------------ + * ipsec_api.c - ipsec api + * + * Copyright (c) 2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------ + */ + +#include <vnet/vnet.h> +#include <vlibmemory/api.h> + +#include <vnet/interface.h> +#include <vnet/api_errno.h> +#include <vnet/ip/ip.h> + +#include <vnet/vnet_msg_enum.h> + +#if IPSEC > 0 +#include <vnet/ipsec/ipsec.h> +#include <vnet/ipsec/ikev2.h> +#endif /* IPSEC */ + +#define vl_typedefs /* define message structures */ +#include <vnet/vnet_all_api_h.h> +#undef vl_typedefs + +#define vl_endianfun /* define message structures */ +#include <vnet/vnet_all_api_h.h> +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_printfun +#include <vnet/vnet_all_api_h.h> +#undef vl_printfun + +#include <vlibapi/api_helper_macros.h> + +#define foreach_vpe_api_msg \ +_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \ +_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \ +_(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \ +_(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \ +_(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \ +_(IPSEC_SPD_DUMP, ipsec_spd_dump) \ +_(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \ +_(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \ +_(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \ +_(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \ +_(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) + +static void vl_api_ipsec_spd_add_del_t_handler + (vl_api_ipsec_spd_add_del_t * mp) +{ +#if IPSEC == 0 + clib_warning ("unimplemented"); +#else + + vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); + vl_api_ipsec_spd_add_del_reply_t *rmp; + int rv; + +#if DPDK > 0 + rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add); +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY); +#endif +} + +static void vl_api_ipsec_interface_add_del_spd_t_handler + (vl_api_ipsec_interface_add_del_spd_t * mp) +{ + vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); + vl_api_ipsec_interface_add_del_spd_reply_t *rmp; + int rv; + u32 sw_if_index __attribute__ ((unused)); + u32 spd_id __attribute__ ((unused)); + + sw_if_index = ntohl (mp->sw_if_index); + spd_id = ntohl (mp->spd_id); + + VALIDATE_SW_IF_INDEX (mp); + +#if IPSEC > 0 + rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add); +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY); +} + +static void vl_api_ipsec_spd_add_del_entry_t_handler + (vl_api_ipsec_spd_add_del_entry_t * mp) +{ + vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); + vl_api_ipsec_spd_add_del_entry_reply_t *rmp; + int rv; + +#if IPSEC > 0 + ipsec_policy_t p; + + memset (&p, 0, sizeof (p)); + + p.id = ntohl (mp->spd_id); + p.priority = ntohl (mp->priority); + p.is_outbound = mp->is_outbound; + p.is_ipv6 = mp->is_ipv6; + + if (mp->is_ipv6 || mp->is_ip_any) + { + clib_memcpy (&p.raddr.start, mp->remote_address_start, 16); + clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16); + clib_memcpy (&p.laddr.start, mp->local_address_start, 16); + clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16); + } + else + { + clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4); + clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4); + clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4); + clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4); + } + p.protocol = mp->protocol; + p.rport.start = ntohs (mp->remote_port_start); + p.rport.stop = ntohs (mp->remote_port_stop); + p.lport.start = ntohs (mp->local_port_start); + p.lport.stop = ntohs (mp->local_port_stop); + /* policy action resolve unsupported */ + if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE) + { + clib_warning ("unsupported action: 'resolve'"); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } + p.policy = mp->policy; + p.sa_id = ntohl (mp->sa_id); + + rv = ipsec_add_del_policy (vm, &p, mp->is_add); + if (rv) + goto out; + + if (mp->is_ip_any) + { + p.is_ipv6 = 1; + rv = ipsec_add_del_policy (vm, &p, mp->is_add); + } +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; +#endif + +out: + REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY); +} + +static void vl_api_ipsec_sad_add_del_entry_t_handler + (vl_api_ipsec_sad_add_del_entry_t * mp) +{ + vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); + vl_api_ipsec_sad_add_del_entry_reply_t *rmp; + int rv; +#if IPSEC > 0 + ipsec_sa_t sa; + + memset (&sa, 0, sizeof (sa)); + + sa.id = ntohl (mp->sad_id); + sa.spi = ntohl (mp->spi); + /* security protocol AH unsupported */ + if (mp->protocol == IPSEC_PROTOCOL_AH) + { + clib_warning ("unsupported security protocol 'AH'"); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } + sa.protocol = mp->protocol; + /* check for unsupported crypto-alg */ + if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 || + mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG) + { + clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg, + mp->crypto_algorithm); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } + sa.crypto_alg = mp->crypto_algorithm; + sa.crypto_key_len = mp->crypto_key_length; + clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); + /* check for unsupported integ-alg */ +#if DPDK_CRYPTO==1 + if (mp->integrity_algorithm < IPSEC_INTEG_ALG_NONE || +#else + if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 || +#endif + mp->integrity_algorithm >= IPSEC_INTEG_N_ALG) + { + clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg, + mp->integrity_algorithm); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } + +#if DPDK_CRYPTO==1 + /*Special cases, aes-gcm-128 encryption */ + if (mp->crypto_algorithm == IPSEC_CRYPTO_ALG_AES_GCM_128) + { + if (mp->integrity_algorithm != IPSEC_INTEG_ALG_NONE + && mp->integrity_algorithm != IPSEC_INTEG_ALG_AES_GCM_128) + { + clib_warning + ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg"); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } + else /*set integ-alg internally to aes-gcm-128 */ + mp->integrity_algorithm = IPSEC_INTEG_ALG_AES_GCM_128; + } + else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_AES_GCM_128) + { + clib_warning ("unsupported integ-alg: aes-gcm-128"); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } + else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_NONE) + { + clib_warning ("unsupported integ-alg: none"); + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; + } +#endif + + sa.integ_alg = mp->integrity_algorithm; + sa.integ_key_len = mp->integrity_key_length; + clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); + sa.use_esn = mp->use_extended_sequence_number; + sa.is_tunnel = mp->is_tunnel; + sa.is_tunnel_ip6 = mp->is_tunnel_ipv6; + if (sa.is_tunnel_ip6) + { + clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16); + clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16); + } + else + { + clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4); + clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4); + } + + rv = ipsec_add_del_sa (vm, &sa, mp->is_add); +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; + goto out; +#endif + +out: + REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY); +} + +static void +send_ipsec_spd_details (ipsec_policy_t * p, unix_shared_memory_queue_t * q, + u32 context) +{ + vl_api_ipsec_spd_details_t *mp; + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS); + mp->context = context; + + mp->spd_id = htonl (p->id); + mp->priority = htonl (p->priority); + mp->is_outbound = p->is_outbound; + mp->is_ipv6 = p->is_ipv6; + if (p->is_ipv6) + { + memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16); + memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16); + memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16); + memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16); + } + else + { + memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4); + memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4); + memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4); + memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4); + } + mp->local_start_port = htons (p->lport.start); + mp->local_stop_port = htons (p->lport.stop); + mp->remote_start_port = htons (p->rport.start); + mp->remote_stop_port = htons (p->rport.stop); + mp->protocol = p->protocol; + mp->policy = p->policy; + mp->sa_id = htonl (p->sa_id); + mp->bytes = clib_host_to_net_u64 (p->counter.bytes); + mp->packets = clib_host_to_net_u64 (p->counter.packets); + + vl_msg_api_send_shmem (q, (u8 *) & mp); +} + +static void +vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp) +{ + unix_shared_memory_queue_t *q; + ipsec_main_t *im = &ipsec_main; + ipsec_policy_t *policy; + ipsec_spd_t *spd; + uword *p; + u32 spd_index; +#if IPSEC > 0 + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id)); + if (!p) + return; + + spd_index = p[0]; + spd = pool_elt_at_index (im->spds, spd_index); + + /* *INDENT-OFF* */ + pool_foreach (policy, spd->policies, + ({ + if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id) + send_ipsec_spd_details (policy, q, + mp->context);} + )); + /* *INDENT-ON* */ +#else + clib_warning ("unimplemented"); +#endif +} + +static void +vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp) +{ + vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); + vl_api_ipsec_sa_set_key_reply_t *rmp; + int rv; +#if IPSEC > 0 + ipsec_sa_t sa; + sa.id = ntohl (mp->sa_id); + sa.crypto_key_len = mp->crypto_key_length; + clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); + sa.integ_key_len = mp->integrity_key_length; + clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); + + rv = ipsec_set_sa_key (vm, &sa); +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IPSEC_SA_SET_KEY_REPLY); +} + +static void +vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp) +{ + vl_api_ikev2_profile_add_del_reply_t *rmp; + int rv = 0; + +#if IPSEC > 0 + vlib_main_t *vm = vlib_get_main (); + clib_error_t *error; + u8 *tmp = format (0, "%s", mp->name); + error = ikev2_add_del_profile (vm, tmp, mp->is_add); + vec_free (tmp); + if (error) + rv = VNET_API_ERROR_UNSPECIFIED; +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY); +} + +static void + vl_api_ikev2_profile_set_auth_t_handler + (vl_api_ikev2_profile_set_auth_t * mp) +{ + vl_api_ikev2_profile_set_auth_reply_t *rmp; + int rv = 0; + +#if IPSEC > 0 + vlib_main_t *vm = vlib_get_main (); + clib_error_t *error; + u8 *tmp = format (0, "%s", mp->name); + u8 *data = vec_new (u8, mp->data_len); + clib_memcpy (data, mp->data, mp->data_len); + error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex); + vec_free (tmp); + vec_free (data); + if (error) + rv = VNET_API_ERROR_UNSPECIFIED; +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY); +} + +static void +vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp) +{ + vl_api_ikev2_profile_add_del_reply_t *rmp; + int rv = 0; + +#if IPSEC > 0 + vlib_main_t *vm = vlib_get_main (); + clib_error_t *error; + u8 *tmp = format (0, "%s", mp->name); + u8 *data = vec_new (u8, mp->data_len); + clib_memcpy (data, mp->data, mp->data_len); + error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local); + vec_free (tmp); + vec_free (data); + if (error) + rv = VNET_API_ERROR_UNSPECIFIED; +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY); +} + +static void +vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp) +{ + vl_api_ikev2_profile_set_ts_reply_t *rmp; + int rv = 0; + +#if IPSEC > 0 + vlib_main_t *vm = vlib_get_main (); + clib_error_t *error; + u8 *tmp = format (0, "%s", mp->name); + error = ikev2_set_profile_ts (vm, tmp, mp->proto, mp->start_port, + mp->end_port, (ip4_address_t) mp->start_addr, + (ip4_address_t) mp->end_addr, mp->is_local); + vec_free (tmp); + if (error) + rv = VNET_API_ERROR_UNSPECIFIED; +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY); +} + +static void +vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp) +{ + vl_api_ikev2_profile_set_ts_reply_t *rmp; + int rv = 0; + +#if IPSEC > 0 + vlib_main_t *vm = vlib_get_main (); + clib_error_t *error; + + error = ikev2_set_local_key (vm, mp->key_file); + if (error) + rv = VNET_API_ERROR_UNSPECIFIED; +#else + rv = VNET_API_ERROR_UNIMPLEMENTED; +#endif + + REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY); +} + +/* + * ipsec_api_hookup + * Add vpe's API message handlers to the table. + * vlib has alread mapped shared memory and + * added the client registration handlers. + * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() + */ +#define vl_msg_name_crc_list +#include <vnet/vnet_all_api_h.h> +#undef vl_msg_name_crc_list + +static void +setup_message_id_table (api_main_t * am) +{ +#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); + foreach_vl_msg_name_crc_ipsec; +#undef _ +} + +static clib_error_t * +ipsec_api_hookup (vlib_main_t * vm) +{ + api_main_t *am = &api_main; + +#define _(N,n) \ + vl_msg_api_set_handlers(VL_API_##N, #n, \ + vl_api_##n##_t_handler, \ + vl_noop_handler, \ + vl_api_##n##_t_endian, \ + vl_api_##n##_t_print, \ + sizeof(vl_api_##n##_t), 1); + foreach_vpe_api_msg; +#undef _ + + /* + * Set up the (msg_name, crc, message-id) table + */ + setup_message_id_table (am); + + return 0; +} + +VLIB_API_INIT_FUNCTION (ipsec_api_hookup); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vnet/vnet/vnet_all_api_h.h b/vnet/vnet/vnet_all_api_h.h index 88f14a1164a..2210222da76 100644 --- a/vnet/vnet/vnet_all_api_h.h +++ b/vnet/vnet/vnet_all_api_h.h @@ -43,6 +43,7 @@ #include <vnet/vxlan/vxlan.api.h> #include <vnet/vxlan-gpe/vxlan_gpe.api.h> #include <vnet/bfd/bfd.api.h> +#include <vnet/ipsec/ipsec.api.h> /* * fd.io coding-style-patch-verification: ON diff --git a/vpp-api/java/Makefile.am b/vpp-api/java/Makefile.am index 26407402fbb..db6a0082dd9 100644 --- a/vpp-api/java/Makefile.am +++ b/vpp-api/java/Makefile.am @@ -96,7 +96,8 @@ jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: \ $(prefix)/../vnet/vnet/vxlan.api.json \ $(prefix)/../vnet/vnet/vxlan_gpe.api.json \ $(prefix)/../vnet/vnet/tap.api.json \ - $(prefix)/../vnet/vnet/bfd.api.json + $(prefix)/../vnet/vnet/bfd.api.json \ + $(prefix)/../vnet/vnet/ipsec.api.json cp -rf @srcdir@/jvpp-core/* -t jvpp-core/ mkdir -p jvpp-core/target cd jvpp-core \ @@ -117,6 +118,7 @@ jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: \ $(prefix)/../vnet/vnet/vxlan.api.json \ $(prefix)/../vnet/vnet/vxlan_gpe.api.json \ $(prefix)/../vnet/vnet/bfd.api.json \ + $(prefix)/../vnet/vnet/ipsec.api.json \ && cp -rf types dto future callfacade callback notification *.java -t $(packagedir_jvpp_core) \ && rm -rf types dto future callfacade callback notification *.java diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index 37079ce32c0..ec2618184c3 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -95,23 +95,15 @@ #include <vnet/devices/dpdk/dpdk.h> #endif -#if IPSEC > 0 -#include <vnet/ipsec/ipsec.h> -#include <vnet/ipsec/ikev2.h> -#endif /* IPSEC */ - #include <stats/stats.h> #include <oam/oam.h> - #include <vnet/ethernet/ethernet.h> #include <vnet/ethernet/arp_packet.h> #include <vnet/interface.h> - #include <vnet/l2/l2_fib.h> #include <vnet/l2/l2_bd.h> #include <vpp-api/vpe_msg_enum.h> #include <vnet/span/span.h> - #include <vnet/fib/ip6_fib.h> #include <vnet/fib/ip4_fib.h> #include <vnet/fib/fib_api.h> @@ -120,23 +112,18 @@ #include <vnet/dpo/lookup_dpo.h> #include <vnet/dpo/classify_dpo.h> #include <vnet/dpo/ip_null_dpo.h> - #define vl_typedefs /* define message structures */ #include <vpp-api/vpe_all_api_h.h> #undef vl_typedefs - #define vl_endianfun /* define message structures */ #include <vpp-api/vpe_all_api_h.h> #undef vl_endianfun - /* instantiate all the print functions we know about */ #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #define vl_printfun #include <vpp-api/vpe_all_api_h.h> #undef vl_printfun - #include <vlibapi/api_helper_macros.h> - #define foreach_vpe_api_msg \ _(WANT_OAM_EVENTS, want_oam_events) \ _(OAM_ADD_DEL, oam_add_del) \ @@ -195,16 +182,6 @@ _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \ _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \ _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \ _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \ -_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \ -_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \ -_(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \ -_(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \ -_(IPSEC_SA_SET_KEY, ipsec_sa_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) \ -_(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \ -_(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \ _(DELETE_LOOPBACK, delete_loopback) \ _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \ _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \ @@ -280,12 +257,10 @@ _(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \ _(PUNT, punt) \ _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \ _(FLOW_CLASSIFY_DUMP, flow_classify_dump) \ -_(IPSEC_SPD_DUMP, ipsec_spd_dump) \ _(FEATURE_ENABLE_DISABLE, feature_enable_disable) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) - typedef enum { RESOLVE_IP4_ADD_DEL_ROUTE = 1, @@ -4545,354 +4520,6 @@ static void vl_api_input_acl_set_interface_t_handler REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY); } -static void vl_api_ipsec_spd_add_del_t_handler - (vl_api_ipsec_spd_add_del_t * mp) -{ -#if IPSEC == 0 - clib_warning ("unimplemented"); -#else - - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_spd_add_del_reply_t *rmp; - int rv; - -#if DPDK > 0 - rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add); -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY); -#endif -} - -static void vl_api_ipsec_interface_add_del_spd_t_handler - (vl_api_ipsec_interface_add_del_spd_t * mp) -{ - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_interface_add_del_spd_reply_t *rmp; - int rv; - u32 sw_if_index __attribute__ ((unused)); - u32 spd_id __attribute__ ((unused)); - - sw_if_index = ntohl (mp->sw_if_index); - spd_id = ntohl (mp->spd_id); - - VALIDATE_SW_IF_INDEX (mp); - -#if IPSEC > 0 - rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add); -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY); -} - -static void vl_api_ipsec_spd_add_del_entry_t_handler - (vl_api_ipsec_spd_add_del_entry_t * mp) -{ - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_spd_add_del_entry_reply_t *rmp; - int rv; - -#if IPSEC > 0 - ipsec_policy_t p; - - memset (&p, 0, sizeof (p)); - - p.id = ntohl (mp->spd_id); - p.priority = ntohl (mp->priority); - p.is_outbound = mp->is_outbound; - p.is_ipv6 = mp->is_ipv6; - - if (mp->is_ipv6 || mp->is_ip_any) - { - clib_memcpy (&p.raddr.start, mp->remote_address_start, 16); - clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16); - clib_memcpy (&p.laddr.start, mp->local_address_start, 16); - clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16); - } - else - { - clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4); - clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4); - clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4); - clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4); - } - p.protocol = mp->protocol; - p.rport.start = ntohs (mp->remote_port_start); - p.rport.stop = ntohs (mp->remote_port_stop); - p.lport.start = ntohs (mp->local_port_start); - p.lport.stop = ntohs (mp->local_port_stop); - /* policy action resolve unsupported */ - if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE) - { - clib_warning ("unsupported action: 'resolve'"); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - p.policy = mp->policy; - p.sa_id = ntohl (mp->sa_id); - - rv = ipsec_add_del_policy (vm, &p, mp->is_add); - if (rv) - goto out; - - if (mp->is_ip_any) - { - p.is_ipv6 = 1; - rv = ipsec_add_del_policy (vm, &p, mp->is_add); - } -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; -#endif - -out: - REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY); -} - -static void vl_api_ipsec_sad_add_del_entry_t_handler - (vl_api_ipsec_sad_add_del_entry_t * mp) -{ - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_sad_add_del_entry_reply_t *rmp; - int rv; -#if IPSEC > 0 - ipsec_sa_t sa; - - memset (&sa, 0, sizeof (sa)); - - sa.id = ntohl (mp->sad_id); - sa.spi = ntohl (mp->spi); - /* security protocol AH unsupported */ - if (mp->protocol == IPSEC_PROTOCOL_AH) - { - clib_warning ("unsupported security protocol 'AH'"); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - sa.protocol = mp->protocol; - /* check for unsupported crypto-alg */ - if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 || - mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG) - { - clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg, - mp->crypto_algorithm); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - sa.crypto_alg = mp->crypto_algorithm; - sa.crypto_key_len = mp->crypto_key_length; - clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); - /* check for unsupported integ-alg */ -#if DPDK_CRYPTO==1 - if (mp->integrity_algorithm < IPSEC_INTEG_ALG_NONE || -#else - if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 || -#endif - mp->integrity_algorithm >= IPSEC_INTEG_N_ALG) - { - clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg, - mp->integrity_algorithm); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - -#if DPDK_CRYPTO==1 - /*Special cases, aes-gcm-128 encryption */ - if (mp->crypto_algorithm == IPSEC_CRYPTO_ALG_AES_GCM_128) - { - if (mp->integrity_algorithm != IPSEC_INTEG_ALG_NONE - && mp->integrity_algorithm != IPSEC_INTEG_ALG_AES_GCM_128) - { - clib_warning - ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg"); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - else /*set integ-alg internally to aes-gcm-128 */ - mp->integrity_algorithm = IPSEC_INTEG_ALG_AES_GCM_128; - } - else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_AES_GCM_128) - { - clib_warning ("unsupported integ-alg: aes-gcm-128"); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } - else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_NONE) - { - clib_warning ("unsupported integ-alg: none"); - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; - } -#endif - - sa.integ_alg = mp->integrity_algorithm; - sa.integ_key_len = mp->integrity_key_length; - clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); - sa.use_esn = mp->use_extended_sequence_number; - sa.is_tunnel = mp->is_tunnel; - sa.is_tunnel_ip6 = mp->is_tunnel_ipv6; - if (sa.is_tunnel_ip6) - { - clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16); - clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16); - } - else - { - clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4); - clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4); - } - - rv = ipsec_add_del_sa (vm, &sa, mp->is_add); -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; - goto out; -#endif - -out: - REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY); -} - -static void -vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp) -{ - vl_api_ikev2_profile_add_del_reply_t *rmp; - int rv = 0; - -#if IPSEC > 0 - vlib_main_t *vm = vlib_get_main (); - clib_error_t *error; - u8 *tmp = format (0, "%s", mp->name); - error = ikev2_add_del_profile (vm, tmp, mp->is_add); - vec_free (tmp); - if (error) - rv = VNET_API_ERROR_UNSPECIFIED; -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY); -} - -static void - vl_api_ikev2_profile_set_auth_t_handler - (vl_api_ikev2_profile_set_auth_t * mp) -{ - vl_api_ikev2_profile_set_auth_reply_t *rmp; - int rv = 0; - -#if IPSEC > 0 - vlib_main_t *vm = vlib_get_main (); - clib_error_t *error; - u8 *tmp = format (0, "%s", mp->name); - u8 *data = vec_new (u8, mp->data_len); - clib_memcpy (data, mp->data, mp->data_len); - error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex); - vec_free (tmp); - vec_free (data); - if (error) - rv = VNET_API_ERROR_UNSPECIFIED; -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY); -} - -static void -vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp) -{ - vl_api_ikev2_profile_add_del_reply_t *rmp; - int rv = 0; - -#if IPSEC > 0 - vlib_main_t *vm = vlib_get_main (); - clib_error_t *error; - u8 *tmp = format (0, "%s", mp->name); - u8 *data = vec_new (u8, mp->data_len); - clib_memcpy (data, mp->data, mp->data_len); - error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local); - vec_free (tmp); - vec_free (data); - if (error) - rv = VNET_API_ERROR_UNSPECIFIED; -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY); -} - -static void -vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp) -{ - vl_api_ikev2_profile_set_ts_reply_t *rmp; - int rv = 0; - -#if IPSEC > 0 - vlib_main_t *vm = vlib_get_main (); - clib_error_t *error; - u8 *tmp = format (0, "%s", mp->name); - error = ikev2_set_profile_ts (vm, tmp, mp->proto, mp->start_port, - mp->end_port, (ip4_address_t) mp->start_addr, - (ip4_address_t) mp->end_addr, mp->is_local); - vec_free (tmp); - if (error) - rv = VNET_API_ERROR_UNSPECIFIED; -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY); -} - -static void -vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp) -{ - vl_api_ikev2_profile_set_ts_reply_t *rmp; - int rv = 0; - -#if IPSEC > 0 - vlib_main_t *vm = vlib_get_main (); - clib_error_t *error; - - error = ikev2_set_local_key (vm, mp->key_file); - if (error) - rv = VNET_API_ERROR_UNSPECIFIED; -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY); -} - -static void -vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp) -{ - vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); - vl_api_ipsec_sa_set_key_reply_t *rmp; - int rv; -#if IPSEC > 0 - ipsec_sa_t sa; - sa.id = ntohl (mp->sa_id); - sa.crypto_key_len = mp->crypto_key_length; - clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key)); - sa.integ_key_len = mp->integrity_key_length; - clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key)); - - rv = ipsec_set_sa_key (vm, &sa); -#else - rv = VNET_API_ERROR_UNIMPLEMENTED; -#endif - - REPLY_MACRO (VL_API_IPSEC_SA_SET_KEY_REPLY); -} - static void vl_api_cop_interface_enable_disable_t_handler (vl_api_cop_interface_enable_disable_t * mp) { @@ -6333,82 +5960,6 @@ vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp) } static void -send_ipsec_spd_details (ipsec_policy_t * p, unix_shared_memory_queue_t * q, - u32 context) -{ - vl_api_ipsec_spd_details_t *mp; - - mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); - mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS); - mp->context = context; - - mp->spd_id = htonl (p->id); - mp->priority = htonl (p->priority); - mp->is_outbound = p->is_outbound; - mp->is_ipv6 = p->is_ipv6; - if (p->is_ipv6) - { - memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16); - memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16); - memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16); - memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16); - } - else - { - memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4); - memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4); - memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4); - memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4); - } - mp->local_start_port = htons (p->lport.start); - mp->local_stop_port = htons (p->lport.stop); - mp->remote_start_port = htons (p->rport.start); - mp->remote_stop_port = htons (p->rport.stop); - mp->protocol = p->protocol; - mp->policy = p->policy; - mp->sa_id = htonl (p->sa_id); - mp->bytes = clib_host_to_net_u64 (p->counter.bytes); - mp->packets = clib_host_to_net_u64 (p->counter.packets); - - vl_msg_api_send_shmem (q, (u8 *) & mp); -} - -static void -vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp) -{ - unix_shared_memory_queue_t *q; - ipsec_main_t *im = &ipsec_main; - ipsec_policy_t *policy; - ipsec_spd_t *spd; - uword *p; - u32 spd_index; -#if IPSEC > 0 - q = vl_api_client_index_to_input_queue (mp->client_index); - if (q == 0) - return; - - p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id)); - if (!p) - return; - - spd_index = p[0]; - spd = pool_elt_at_index (im->spds, spd_index); - - /* *INDENT-OFF* */ - pool_foreach (policy, spd->policies, - ({ - if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id) - send_ipsec_spd_details (policy, q, - mp->context);} - )); - /* *INDENT-ON* */ -#else - clib_warning ("unimplemented"); -#endif -} - -static void vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp) { vl_api_feature_enable_disable_reply_t *rmp; diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 7556a223219..0d7de596141 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -33,6 +33,7 @@ * GRE APIs: see .../vnet/vnet/gre/{gre.api, gre_api.c} * L2TP APIs: see .../vnet/vnet/l2tp/{l2tp.api, l2tp_api.c} * BFD APIs: see .../vnet/vnet/bfd/{bfd.api, bfd_api.c} + * IPSEC APIs: see .../vnet/vnet/ipsec/{ipsec.api, ipsec_api.c} */ /** \brief Create a new subinterface with the given vlan id @@ -2679,387 +2680,6 @@ define input_acl_set_interface_reply i32 retval; }; -/** \brief IPsec: Add/delete Security Policy Database - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add SPD if non-zero, else delete - @param spd_id - SPD instance id (control plane allocated) -*/ - -define ipsec_spd_add_del -{ - u32 client_index; - u32 context; - u8 is_add; - u32 spd_id; -}; - -/** \brief Reply for IPsec: Add/delete Security Policy Database entry - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ - -define ipsec_spd_add_del_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IPsec: Add/delete SPD from interface - - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add security mode if non-zero, else delete - @param sw_if_index - index of the interface - @param spd_id - SPD instance id to use for lookups -*/ - - -define ipsec_interface_add_del_spd -{ - u32 client_index; - u32 context; - - u8 is_add; - u32 sw_if_index; - u32 spd_id; -}; - -/** \brief Reply for IPsec: Add/delete SPD from interface - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ - -define ipsec_interface_add_del_spd_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IPsec: Add/delete Security Policy Database entry - - See RFC 4301, 4.4.1.1 on how to match packet to selectors - - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add SPD if non-zero, else delete - @param spd_id - SPD instance id (control plane allocated) - @param priority - priority of SPD entry (non-unique value). Used to order SPD matching - higher priorities match before lower - @param is_outbound - entry applies to outbound traffic if non-zero, otherwise applies to inbound traffic - @param is_ipv6 - remote/local address are IPv6 if non-zero, else IPv4 - @param remote_address_start - start of remote address range to match - @param remote_address_stop - end of remote address range to match - @param local_address_start - start of local address range to match - @param local_address_stop - end of local address range to match - @param protocol - protocol type to match [0 means any] - @param remote_port_start - start of remote port range to match ... - @param remote_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] - @param local_port_start - start of local port range to match ... - @param local_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] - @param policy - 0 = bypass (no IPsec processing), 1 = discard (discard packet with ICMP processing), 2 = resolve (send request to control plane for SA resolving, and discard without ICMP processing), 3 = protect (apply IPsec policy using following parameters) - @param sa_id - SAD instance id (control plane allocated) - -*/ - -define ipsec_spd_add_del_entry -{ - u32 client_index; - u32 context; - u8 is_add; - - u32 spd_id; - i32 priority; - u8 is_outbound; - - // Selector - u8 is_ipv6; - u8 is_ip_any; - u8 remote_address_start[16]; - u8 remote_address_stop[16]; - u8 local_address_start[16]; - u8 local_address_stop[16]; - - u8 protocol; - - u16 remote_port_start; - u16 remote_port_stop; - u16 local_port_start; - u16 local_port_stop; - - // Policy - u8 policy; - u32 sa_id; -}; - -/** \brief Reply for IPsec: Add/delete Security Policy Database entry - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ - -define ipsec_spd_add_del_entry_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IPsec: Add/delete Security Association Database entry - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_add - add SAD entry if non-zero, else delete - - @param sad_id - sad id - - @param spi - security parameter index - - @param protocol - 0 = AH, 1 = ESP - - @param crypto_algorithm - 0 = Null, 1 = AES-CBC-128, 2 = AES-CBC-192, 3 = AES-CBC-256, 4 = 3DES-CBC - @param crypto_key_length - length of crypto_key in bytes - @param crypto_key - crypto keying material - - @param integrity_algorithm - 0 = None, 1 = MD5-96, 2 = SHA1-96, 3 = SHA-256, 4 = SHA-384, 5=SHA-512 - @param integrity_key_length - length of integrity_key in bytes - @param integrity_key - integrity keying material - - @param use_extended_sequence_number - use ESN when non-zero - - @param is_tunnel - IPsec tunnel mode if non-zero, else transport mode - @param is_tunnel_ipv6 - IPsec tunnel mode is IPv6 if non-zero, else IPv4 tunnel only valid if is_tunnel is non-zero - @param tunnel_src_address - IPsec tunnel source address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero - @param tunnel_dst_address - IPsec tunnel destination address IPv6 if is_tunnel_ipv6 is non-zero, else IPv4. Only valid if is_tunnel is non-zero - - To be added: - Anti-replay - IPsec tunnel address copy mode (to support GDOI) - */ - -define ipsec_sad_add_del_entry -{ - u32 client_index; - u32 context; - u8 is_add; - - u32 sad_id; - - u32 spi; - - u8 protocol; - - u8 crypto_algorithm; - u8 crypto_key_length; - u8 crypto_key[128]; - - u8 integrity_algorithm; - u8 integrity_key_length; - u8 integrity_key[128]; - - u8 use_extended_sequence_number; - - u8 is_tunnel; - u8 is_tunnel_ipv6; - u8 tunnel_src_address[16]; - u8 tunnel_dst_address[16]; -}; - -/** \brief Reply for IPsec: Add/delete Security Association Database entry - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ - -define ipsec_sad_add_del_entry_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IPsec: Update Security Association keys - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - - @param sa_id - sa id - - @param crypto_key_length - length of crypto_key in bytes - @param crypto_key - crypto keying material - - @param integrity_key_length - length of integrity_key in bytes - @param integrity_key - integrity keying material -*/ - -define ipsec_sa_set_key -{ - u32 client_index; - u32 context; - - u32 sa_id; - - u8 crypto_key_length; - u8 crypto_key[128]; - - u8 integrity_key_length; - u8 integrity_key[128]; -}; - -/** \brief Reply for IPsec: Update Security Association keys - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ - -define ipsec_sa_set_key_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IKEv2: Add/delete profile - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - - @param name - IKEv2 profile name - @param is_add - Add IKEv2 profile if non-zero, else delete -*/ -define ikev2_profile_add_del -{ - u32 client_index; - u32 context; - - u8 name[64]; - u8 is_add; -}; - -/** \brief Reply for IKEv2: Add/delete profile - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define ikev2_profile_add_del_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IKEv2: Set IKEv2 profile authentication method - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - - @param name - IKEv2 profile name - @param auth_method - IKEv2 authentication method (shared-key-mic/rsa-sig) - @param is_hex - Authentication data in hex format if non-zero, else string - @param data_len - Authentication data length - @param data - Authentication data (for rsa-sig cert file path) -*/ -define ikev2_profile_set_auth -{ - u32 client_index; - u32 context; - - u8 name[64]; - u8 auth_method; - u8 is_hex; - u32 data_len; - u8 data[0]; -}; - -/** \brief Reply for IKEv2: Set IKEv2 profile authentication method - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define ikev2_profile_set_auth_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IKEv2: Set IKEv2 profile local/remote identification - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - - @param name - IKEv2 profile name - @param is_local - Identification is local if non-zero, else remote - @param id_type - Identification type - @param data_len - Identification data length - @param data - Identification data -*/ -define ikev2_profile_set_id -{ - u32 client_index; - u32 context; - - u8 name[64]; - u8 is_local; - u8 id_type; - u32 data_len; - u8 data[0]; -}; - -/** \brief Reply for IKEv2: - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define ikev2_profile_set_id_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IKEv2: Set IKEv2 profile traffic selector parameters - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - - @param name - IKEv2 profile name - @param is_local - Traffic selector is local if non-zero, else remote - @param proto - Traffic selector IP protocol (if zero not relevant) - @param start_port - The smallest port number allowed by traffic selector - @param end_port - The largest port number allowed by traffic selector - @param start_addr - The smallest address included in traffic selector - @param end_addr - The largest address included in traffic selector -*/ -define ikev2_profile_set_ts -{ - u32 client_index; - u32 context; - - u8 name[64]; - u8 is_local; - u8 proto; - u16 start_port; - u16 end_port; - u32 start_addr; - u32 end_addr; -}; - -/** \brief Reply for IKEv2: Set IKEv2 profile traffic selector parameters - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define ikev2_profile_set_ts_reply -{ - u32 context; - i32 retval; -}; - -/** \brief IKEv2: Set IKEv2 local RSA private key - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - - @param key_file - Key file absolute path -*/ -define ikev2_set_local_key -{ - u32 client_index; - u32 context; - - u8 key_file[256]; -}; - -/** \brief Reply for IKEv2: Set IKEv2 local key - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define ikev2_set_local_key_reply -{ - u32 context; - i32 retval; -}; - /** \brief Tell client about a DHCP completion event @param client_index - opaque cookie to identify the sender @param pid - client pid registered to receive notification @@ -4121,61 +3741,6 @@ define punt_reply i32 retval; }; -/** \brief Dump ipsec policy database data - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param spd_id - SPD instance id - @param sa_id - SA id, optional, set to ~0 to see all policies in SPD -*/ -define ipsec_spd_dump { - u32 client_index; - u32 context; - u32 spd_id; - u32 sa_id; -}; - -/** \brief IPsec policy database response - @param context - sender context which was passed in the request - @param spd_id - SPD instance id - @param priority - numeric value to control policy evaluation order - @param is_outbound - [1|0] to indicate if direction is [out|in]bound - @param is_ipv6 - [1|0] to indicate if address family is ipv[6|4] - @param local_start_addr - first address in local traffic selector range - @param local_stop_addr - last address in local traffic selector range - @param local_start_port - first port in local traffic selector range - @param local_stop_port - last port in local traffic selector range - @param remote_start_addr - first address in remote traffic selector range - @param remote_stop_addr - last address in remote traffic selector range - @param remote_start_port - first port in remote traffic selector range - @param remote_stop_port - last port in remote traffic selector range - @param protocol - traffic selector protocol - @param policy - policy action - @param sa_id - SA id - @param bytes - byte count of packets matching this policy - @param packets - count of packets matching this policy -*/ - -define ipsec_spd_details { - u32 context; - u32 spd_id; - i32 priority; - u8 is_outbound; - u8 is_ipv6; - u8 local_start_addr[16]; - u8 local_stop_addr[16]; - u16 local_start_port; - u16 local_stop_port; - u8 remote_start_addr[16]; - u8 remote_stop_addr[16]; - u16 remote_start_port; - u16 remote_stop_port; - u8 protocol; - u8 policy; - u32 sa_id; - u64 bytes; - u64 packets; -}; - /** \brief Feature path enable/disable request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request |