diff options
Diffstat (limited to 'src/vnet/ipsec')
-rw-r--r-- | src/vnet/ipsec/esp.h | 4 | ||||
-rw-r--r-- | src/vnet/ipsec/esp_format.c | 39 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.c | 8 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.h | 15 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_if.c | 78 |
5 files changed, 100 insertions, 44 deletions
diff --git a/src/vnet/ipsec/esp.h b/src/vnet/ipsec/esp.h index 799003b9e61..98db70179bd 100644 --- a/src/vnet/ipsec/esp.h +++ b/src/vnet/ipsec/esp.h @@ -15,6 +15,9 @@ #ifndef __ESP_H__ #define __ESP_H__ +#include <vnet/ip/ip.h> +#include <vnet/ipsec/ipsec.h> + #include <openssl/hmac.h> #include <openssl/rand.h> #include <openssl/evp.h> @@ -82,6 +85,7 @@ esp_main_t esp_main; #define ESP_WINDOW_SIZE (64) #define ESP_SEQ_MAX (4294967295UL) +u8 *format_esp_header (u8 * s, va_list * args); always_inline int esp_replay_check (ipsec_sa_t * sa, u32 seq) diff --git a/src/vnet/ipsec/esp_format.c b/src/vnet/ipsec/esp_format.c new file mode 100644 index 00000000000..615d576043b --- /dev/null +++ b/src/vnet/ipsec/esp_format.c @@ -0,0 +1,39 @@ +/* + * esp_format.c : ESP format + * + * Copyright (c) 2017 Intel 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 <vnet/api_errno.h> +#include <vnet/ipsec/esp.h> + +u8 * +format_esp_header (u8 * s, va_list * args) +{ + esp_header_t *esp = va_arg (*args, esp_header_t *); + + s = format (s, "ESP: spi %u, seq %u", + clib_net_to_host_u32 (esp->spi), + clib_net_to_host_u32 (esp->seq)); + return s; +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c index cfe434ab457..ba0d68bde97 100644 --- a/src/vnet/ipsec/ipsec.c +++ b/src/vnet/ipsec/ipsec.c @@ -434,7 +434,7 @@ ipsec_add_del_sa (vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add) } hash_unset (im->sa_index_by_sa_id, sa->id); if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (sa_index, is_add) < 0) + im->cb.add_del_sa_sess_cb (sa_index, 0) < 0) return VNET_API_ERROR_SYSCALL_ERROR_1; pool_put (im->sad, sa); } @@ -445,7 +445,7 @@ ipsec_add_del_sa (vlib_main_t * vm, ipsec_sa_t * new_sa, int is_add) sa_index = sa - im->sad; hash_set (im->sa_index_by_sa_id, sa->id, sa_index); if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (sa_index, is_add) < 0) + im->cb.add_del_sa_sess_cb (sa_index, 1) < 0) return VNET_API_ERROR_SYSCALL_ERROR_1; } return 0; @@ -482,7 +482,7 @@ ipsec_set_sa_key (vlib_main_t * vm, ipsec_sa_t * sa_update) sa->integ_key_len = sa_update->integ_key_len; } - if (sa->crypto_key_len + sa->integ_key_len > 0) + if (0 < sa_update->crypto_key_len || 0 < sa_update->integ_key_len) { if (im->cb.add_del_sa_sess_cb && im->cb.add_del_sa_sess_cb (sa_index, 0) < 0) @@ -516,8 +516,6 @@ ipsec_check_support (ipsec_sa_t * sa) return clib_error_return (0, "unsupported aes-gcm-128 crypto-alg"); if (sa->integ_alg == IPSEC_INTEG_ALG_NONE) return clib_error_return (0, "unsupported none integ-alg"); - if (sa->integ_alg == IPSEC_INTEG_ALG_AES_GCM_128) - return clib_error_return (0, "unsupported aes-gcm-128 integ-alg"); return 0; } diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h index 1eff1c3a0be..f11bc56cb9a 100644 --- a/src/vnet/ipsec/ipsec.h +++ b/src/vnet/ipsec/ipsec.h @@ -15,6 +15,9 @@ #ifndef __IPSEC_H__ #define __IPSEC_H__ +#include <vnet/ip/ip.h> +#include <vnet/feature/feature.h> + #define IPSEC_FLAG_IPSEC_GRE_TUNNEL (1 << 0) @@ -63,7 +66,12 @@ typedef enum _(1, AES_CBC_128, "aes-cbc-128") \ _(2, AES_CBC_192, "aes-cbc-192") \ _(3, AES_CBC_256, "aes-cbc-256") \ - _(4, AES_GCM_128, "aes-gcm-128") + _(4, AES_CTR_128, "aes-ctr-128") \ + _(5, AES_CTR_192, "aes-ctr-192") \ + _(6, AES_CTR_256, "aes-ctr-256") \ + _(7, AES_GCM_128, "aes-gcm-128") \ + _(8, AES_GCM_192, "aes-gcm-192") \ + _(9, AES_GCM_256, "aes-gcm-256") typedef enum { @@ -80,8 +88,7 @@ typedef enum _(3, SHA_256_96, "sha-256-96") /* draft-ietf-ipsec-ciph-sha-256-00 */ \ _(4, SHA_256_128, "sha-256-128") /* RFC4868 */ \ _(5, SHA_384_192, "sha-384-192") /* RFC4868 */ \ - _(6, SHA_512_256, "sha-512-256") /* RFC4868 */ \ - _(7, AES_GCM_128, "aes-gcm-128") /* RFC4106 */ + _(6, SHA_512_256, "sha-512-256") /* RFC4868 */ typedef enum { @@ -236,7 +243,7 @@ typedef struct typedef struct { - i32 (*add_del_sa_sess_cb) (u32 sa_index, u8 is_add); + clib_error_t *(*add_del_sa_sess_cb) (u32 sa_index, u8 is_add); clib_error_t *(*check_support_cb) (ipsec_sa_t * sa); } ipsec_main_callbacks_t; diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c index 9359a3b772e..974553489ea 100644 --- a/src/vnet/ipsec/ipsec_if.c +++ b/src/vnet/ipsec/ipsec_if.c @@ -49,25 +49,63 @@ ipsec_admin_up_down_function (vnet_main_t * vnm, u32 hw_if_index, u32 flags) ipsec_sa_t *sa; hi = vnet_get_hw_interface (vnm, hw_if_index); + t = pool_elt_at_index (im->tunnel_interfaces, hi->hw_instance); + if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) { - t = pool_elt_at_index (im->tunnel_interfaces, hi->hw_instance); ASSERT (im->cb.check_support_cb); + sa = pool_elt_at_index (im->sad, t->input_sa_index); + err = im->cb.check_support_cb (sa); if (err) return err; + if (im->cb.add_del_sa_sess_cb) + { + err = im->cb.add_del_sa_sess_cb (t->input_sa_index, 1); + if (err) + return err; + } + sa = pool_elt_at_index (im->sad, t->output_sa_index); + err = im->cb.check_support_cb (sa); if (err) return err; + if (im->cb.add_del_sa_sess_cb) + { + err = im->cb.add_del_sa_sess_cb (t->output_sa_index, 1); + if (err) + return err; + } + vnet_hw_interface_set_flags (vnm, hw_if_index, VNET_HW_INTERFACE_FLAG_LINK_UP); } else - vnet_hw_interface_set_flags (vnm, hw_if_index, 0 /* down */ ); + { + vnet_hw_interface_set_flags (vnm, hw_if_index, 0 /* down */ ); + + sa = pool_elt_at_index (im->sad, t->input_sa_index); + + if (im->cb.add_del_sa_sess_cb) + { + err = im->cb.add_del_sa_sess_cb (t->input_sa_index, 0); + if (err) + return err; + } + + sa = pool_elt_at_index (im->sad, t->output_sa_index); + + if (im->cb.add_del_sa_sess_cb) + { + err = im->cb.add_del_sa_sess_cb (t->output_sa_index, 0); + if (err) + return err; + } + } return /* no error */ 0; } @@ -157,10 +195,6 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, args->remote_crypto_key_len); } - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->input_sa_index, args->is_add) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; - pool_get (im->sad, sa); memset (sa, 0, sizeof (*sa)); t->output_sa_index = sa - im->sad; @@ -168,7 +202,6 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, sa->tunnel_src_addr.ip4.as_u32 = args->local_ip.as_u32; sa->tunnel_dst_addr.ip4.as_u32 = args->remote_ip.as_u32; sa->is_tunnel = 1; - sa->seq = 1; sa->use_esn = args->esn; sa->use_anti_replay = args->anti_replay; sa->integ_alg = args->integ_alg; @@ -186,10 +219,6 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, args->local_crypto_key_len); } - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->output_sa_index, args->is_add) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; - hash_set (im->ipsec_if_pool_index_by_key, key, t - im->tunnel_interfaces); @@ -242,18 +271,10 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, /* delete input and output SA */ sa = pool_elt_at_index (im->sad, t->input_sa_index); - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->input_sa_index, args->is_add) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; - pool_put (im->sad, sa); sa = pool_elt_at_index (im->sad, t->output_sa_index); - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->output_sa_index, args->is_add) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; - pool_put (im->sad, sa); hash_unset (im->ipsec_if_pool_index_by_key, key); @@ -340,16 +361,15 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, hi = vnet_get_hw_interface (vnm, hw_if_index); t = pool_elt_at_index (im->tunnel_interfaces, hi->dev_instance); + if (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) + return VNET_API_ERROR_SYSCALL_ERROR_1; + if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO) { sa = pool_elt_at_index (im->sad, t->output_sa_index); sa->crypto_alg = alg; sa->crypto_key_len = vec_len (key); clib_memcpy (sa->crypto_key, key, vec_len (key)); - - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->output_sa_index, 0) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; } else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG) { @@ -357,10 +377,6 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, sa->integ_alg = alg; sa->integ_key_len = vec_len (key); clib_memcpy (sa->integ_key, key, vec_len (key)); - - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->output_sa_index, 0) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO) { @@ -368,10 +384,6 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, sa->crypto_alg = alg; sa->crypto_key_len = vec_len (key); clib_memcpy (sa->crypto_key, key, vec_len (key)); - - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->input_sa_index, 0) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG) { @@ -379,10 +391,6 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, sa->integ_alg = alg; sa->integ_key_len = vec_len (key); clib_memcpy (sa->integ_key, key, vec_len (key)); - - if (im->cb.add_del_sa_sess_cb && - im->cb.add_del_sa_sess_cb (t->input_sa_index, 0) < 0) - return VNET_API_ERROR_SYSCALL_ERROR_1; } else return VNET_API_ERROR_INVALID_VALUE; |